# Data sync

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

`SyncProgressList` displays the current status and record counts for each
configured data type. Pass a map keyed by the data type and update it as the
sync run advances:

```dart
SyncProgressList(
  progress: const {
    'heartRate': SyncProgress(
      measurementTypeKey: 'heartRate',
      status: SyncProgressStatus.syncing,
      progress: SyncProgressCounts(done: 84, total: 120, created: 78),
    ),
  },
)
```

The widget humanizes data type keys by default. Provide `labelForType`,
`statusLabels`, and `reasonLabels` to supply app-specific labels and
translations. A missing or empty progress map renders no rows.

## Health data modes [#health-data-modes]

`getHealthDataMode` returns the Native SDK default for a health sync key.
Pass `configuredMode` to override it. `HealthDataType` supplies the keys for
health-only types that are not Core measurement services.

```dart
final mode = getHealthDataMode('stepCount');
final sleepMode = getHealthDataMode(
  HealthDataType.sleep.key,
  configuredMode: HealthDataMode.point,
);
```

Step counts, distance, active energy, flights climbed, exercise minutes, water,
carbohydrates, and calories eaten default to `dailyTotal`; heart rate and
heart-rate summaries default to `dailySummary`; sleep and workouts default to
`session`. Other keys, including blood alcohol and insulin, default to `point`.
`series` is available for explicitly configured time-series imports.

## Health sync configuration [#health-sync-configuration]

`HealthSyncConfiguration` mirrors the Native SDK's data sync settings. It maps
each sync key to the platform identifiers to read and the optional observation
coding, date limit, and aggregation mode. The same settings carry the record
page size, Wi-Fi preference, and progress or error callbacks.

```dart
final configuration = HealthSyncConfiguration<String>(
  dataToSync: {
    'heartRate': HealthSyncTypeConfiguration(
      typeIdentifiers: const [
        HealthSyncTypeIdentifier(
          typeIdentifier: 'HKQuantityTypeIdentifierHeartRate',
          code: '8867-4',
          system: 'http://loinc.org',
          display: 'Heart rate',
        ),
      ],
      mode: HealthDataMode.dailySummary,
    ),
  },
);
```

The default chunk size is 5000 records and Wi-Fi-only syncing is off. Platform
adapters provide the identifiers and read the configured records.

## Health import access [#health-import-access]

`HealthImportController` mirrors the Native SDK's `useHealthImport` state for
Flutter apps. Supply an adapter for the app's health source; the controller
tracks access and requests it when import is enabled, while health data reading
stays with that adapter.

```dart
final healthImportController = HealthImportController(
  types: const ['heartRate', 'stepCount'],
  adapter: healthImportAdapter,
  background: true,
);

await healthImportController.refresh();
await healthImportController.setEnabled(true);
```

Listen to the controller to update the UI. `statusByType` contains the last
successful access status for each type, `notShared` lists refused types, and
`error` contains the last status-check or access-request error. Dispose the
controller when its owner is removed.

Wrap the widgets that need access state in `HealthImportProvider`. Descendants
read the nearest controller with `HealthImportProvider.of`; they rebuild when
its state changes:

```dart
HealthImportProvider<String>(
  controller: healthImportController,
  child: Builder(
    builder: (context) {
      final healthImport = HealthImportProvider.of<String>(context);
      return Text(healthImport.enabled ? 'Enabled' : 'Disabled');
    },
  ),
)
```
