# Flutter package

Canonical page: https://docs.ovok.com/flutter-sdk/flutter

`ovok_flutter` is the package Flutter apps depend on. `ovok_sdk` is the pure-Dart
API client; `ovok_flutter` sits on top of it and adds Flutter-only modules, including
the questionnaire form and Bluetooth runtime. Both follow the
`@ovok/native/next` contract, with Dart names.

## What it adds over `ovok_sdk` [#what-it-adds-over-ovok_sdk]

Its library re-exports every public symbol of `ovok_sdk` unchanged and adds
Flutter-specific widgets. `Ovok`, its namespaces, `Page` and the
`OvokException` classes are the same types under either import. The
[`ovok_flutter` reference](/flutter-sdk/reference/ovok_flutter) lists each re-exported
symbol and links to its page.

Depend on `ovok_flutter` in a Flutter app so Flutter modules arrive without changing
your imports. Servers, command-line tools and other Dart-only projects depend on
`ovok_sdk` alone and never pull in Flutter.

## Install [#install]

```bash
flutter pub add ovok_flutter
```

It requires Dart 3.6 or later and pulls in the matching `ovok_sdk`. Do not add
`ovok_sdk` separately; import one library:

```dart
import 'package:ovok_flutter/ovok_flutter.dart';
```

## Set up a client [#set-up-a-client]

Create one `Ovok` client per tenant when the app starts and keep it for the app's
lifetime. The client keeps the signed-in session in an `OvokSecureStore`; the
[Get started](/flutter-sdk/getting-started#create-a-client) guide shows an adapter for
`flutter_secure_storage`.

```dart
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:ovok_flutter/ovok_flutter.dart';

final navigatorKey = GlobalKey<NavigatorState>();

final ovok = Ovok(
  baseUrl: 'https://api.sandbox.ovok.com',
  tenantCode: 'your-tenant',
  secureStore: SecureStore(const FlutterSecureStorage()),
  onUnauthenticated: (reason) =>
      navigatorKey.currentState?.pushNamedAndRemoveUntil('/sign-in', (_) => false),
);

void main() => runApp(MaterialApp(navigatorKey: navigatorKey, home: const HomePage()));
```

`onUnauthenticated` runs when the server refuses the refresh token and the session is
cleared, so the app can return to its sign-in screen. Pass the client to the widgets
that need it the way your app shares other services, for example through a provider or
constructor arguments.

## Features [#features]

| Feature | Where |
| --- | --- |
| API client, sign-in, FHIR, measurements and every other namespace | Re-exported from `ovok_sdk`; see the [guides](/flutter-sdk#guides) and the [`ovok_sdk` reference](/flutter-sdk/reference/ovok_sdk). |
| Authentication forms and account widgets | [Auth widgets](/flutter-sdk/auth-widgets) covers sign-in, MFA, registration, reset, profile, sessions, logout and account deletion. |
| Questionnaire response forms | [`QuestionnaireForm`](/flutter-sdk/questionnaire-forms) renders and validates FHIR questionnaires. |
| Bluetooth scanning and device protocols | [Bluetooth devices](/flutter-sdk/bluetooth) covers the runtime, device definitions, and `flutter_reactive_ble` scanner. |
| Offline measurement background sync | [Background sync](/flutter-sdk/background-sync) schedules Core queue flushes through Workmanager. |
| Health data sync progress | [Data sync](/flutter-sdk/data-sync) renders per-type status and record counts. |
| Apple Health and Health Connect readings | [Health data sync](/flutter-sdk/health-sync) imports step counts and heart rate. |
