health_connector 2.3.2
health_connector: ^2.3.2 copied to clipboard
The most comprehensive Flutter health plugin for seamless iOS HealthKit and Android Health Connect integration.
health_connector #
The most complete Flutter health SDK β unified, type-safe access to 100+ health data types across iOS HealthKit and Android Health Connect.
π Table of Contents #
π± Exploring SDK Capabilities using Health Connector Toolbox #
To explore the SDK's capabilities hands-on, you can use the Health Connector Toolbox app included in the repository.
| Permission Request | Read Data | Write Data | Delete Data | Aggregate Data |
|---|---|---|---|---|
| [Permission Request] | [Read Data] | [Write Data] | [Delete Data] | [Aggregate Data] |
| [Permission Request] | [Read Data] | [Write Data] | [Delete Data] | [Aggregate Data] |
βΉοΈ Note: The toolbox is intended as a demonstration and internal testing tool only. It is not recommended as a reference for building production applications.
What the Toolbox Offers
- Interactive demonstrations of core SDK capabilities
- Permission management
- Read, write, update, and delete operations
- Data aggregation
- Feature management
- Visual representation of health records
Running the Toolbox
# Clone the repository
git clone https://github.com/fam-tung-lam/health_connector.git
cd health_connector
# Navigate to the toolbox app
cd examples/health_connector_toolbox
# Install dependencies
flutter pub get
# Run on your device
flutter run
π Quick Start #
π Requirements #
| Platform | Minimum Version |
|---|---|
| Android | API 26+ |
| iOS | β₯15.0 |
π¦ Installation #
flutter pub add health_connector
Or add manually to pubspec.yaml:
dependencies:
health_connector: [latest_version]
π§ Platform Setup #
π€ Android Health Connect Setup
Step 1: Update AndroidManifest.xml
Add to android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<!-- Your existing configuration -->
<!-- Health Connect intent filter for showing permissions rationale -->
<activity-alias
android:name="ViewPermissionUsageActivity"
android:exported="true"
android:targetActivity=".MainActivity"
android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
<intent-filter>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent-filter>
</activity-alias>
</application>
<!-- Declare Health Connect permissions for each data type you use -->
<!-- Read permissions -->
<uses-permission android:name="android.permission.health.READ_STEPS" />
<uses-permission android:name="android.permission.health.READ_WEIGHT" />
<uses-permission android:name="android.permission.health.READ_HEART_RATE" />
<!-- Add more read permissions... -->
<!-- Write permissions -->
<uses-permission android:name="android.permission.health.WRITE_STEPS" />
<uses-permission android:name="android.permission.health.WRITE_WEIGHT" />
<uses-permission android:name="android.permission.health.WRITE_HEART_RATE" />
<!-- Add more write permissions... -->
<!-- Feature permissions -->
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY" />
<!-- Add more feature permissions... -->
</manifest>
β Important: You must declare a permission for each health data type and feature your app accesses. See the Health Connect data types list for all available permissions.
Step 2: Update MainActivity (Android 14+)
This SDK uses the modern registerForActivityResult API when requesting permissions from Health
Connect. For this to work correctly, your app's MainActivity must extend FlutterFragmentActivity
instead of FlutterActivity. This is required because registerForActivityResult is only available
in ComponentActivity and its subclasses.
Update android/app/src/main/kotlin/.../MainActivity.kt:
package com.example.yourapp
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
// Your existing code
}
Step 3: Enable AndroidX
Health Connect is built on AndroidX libraries. android.useAndroidX=true enables AndroidX support,
and android.enableJetifier=true automatically migrates third-party libraries to use AndroidX.
Update android/gradle.properties:
# Your existing configuration
android.enableJetifier=true
android.useAndroidX=true
Step 4: Update Gradle
Update android/app/build.gradle:
android {
// Your existing configuration
defaultConfig {
// Your existing configuration
minSdkVersion 26
}
}
π iOS HealthKit Setup
Step 1: Set Minimum iOS Version
- Open your project in Xcode (
ios/Runner.xcworkspace) - Select your app target
- Go to General tab
- Set Minimum Deployments to 15.0
Step 2: Enable HealthKit Capability
- Open your project in Xcode (
ios/Runner.xcworkspace) - Select your app target
- Go to Signing & Capabilities tab
- Click + Capability
- Add HealthKit
Step 3: Update Info.plist
Add to ios/Runner/Info.plist:
<dict>
<!-- Existing keys -->
<!-- Required: Describe why your app reads health data -->
<key>NSHealthShareUsageDescription</key>
<string>This app needs to read your health data to provide personalized insights.</string>
<!-- Required: Describe why your app writes health data -->
<key>NSHealthUpdateUsageDescription</key>
<string>This app needs to save health data to track your progress.</string>
</dict>
β οΈ Warning: Vague or generic usage descriptions may result in App Store rejection. Be specific about what data you access and why.
β‘ Quick Demo #
import 'package:health_connector/health_connector.dart';
Future<void> quickStart() async {
// 1. Check platform availability
final status = await HealthConnector.getHealthPlatformStatus();
if (status != HealthPlatformStatus.available) {
print('Health platform not available: $status');
return;
}
// 2. Create connector instance
final connector = await HealthConnector.create(
HealthConnectorConfig(isLoggerEnabled: true),
);
// 3. Request permissions for steps
// **Note**: Feel free to use any other data type you want.
final results = await connector.requestPermissions([
HealthDataType.steps.readPermission,
HealthDataType.steps.writePermission,
]);
// 4. Check if all permissions were granted
final arePermissionsGranted = results.every((r) => r.status != PermissionStatus.denied);
if (!arePermissionsGranted) {
print('Permissions not granted');
return;
}
// 5. Write multiple step records
final stepsRecords = [
StepsRecord(
startTime: DateTime.now().subtract(Duration(hours: 3)),
endTime: DateTime.now().subtract(Duration(hours: 2)),
count: Number(1500),
metadata: Metadata.automaticallyRecorded(
dataOrigin: DataOrigin('com.example'),
device: Device.fromType(DeviceType.phone),
),
),
StepsRecord(
startTime: DateTime.now().subtract(Duration(hours: 2)),
endTime: DateTime.now().subtract(Duration(hours: 1)),
count: Number(2000),
metadata: Metadata.automaticallyRecorded(
dataOrigin: DataOrigin('com.example'),
device: Device.fromType(DeviceType.phone),
),
),
StepsRecord(
startTime: DateTime.now().subtract(Duration(hours: 1)),
endTime: DateTime.now(),
count: Number(1800),
metadata: Metadata.automaticallyRecorded(
dataOrigin: DataOrigin('com.example'),
device: Device.fromType(DeviceType.phone),
),
),
];
final recordIds = await connector.writeRecords(stepsRecords);
print('Wrote ${recordIds.length} records');
// 6. Read today's step records
final response = await connector.readRecords(
HealthDataType.steps.readInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 1)),
endTime: DateTime.now(),
),
);
for (final record in response.records) {
print('Record: ${record.count.value} (${record.startTime} - ${record.endTime})');
}
}
π Developer Guide #
π Permission Management #
Request Permissions
β οΈ iOS Privacy Limitation: HealthKit always returns
PermissionStatus.unknownfor read permissions to protect user privacy. This is Apple's intentional design, not a limitation of this SDK.
final permissions = [
// Data permissions
HealthDataType.steps.readPermission,
HealthDataType.steps.writePermission,
HealthDataType.weight.readPermission,
HealthDataType.weight.writePermission,
// Feature permissions
HealthPlatformFeature.readHealthDataInBackground.permission,
];
final results = await connector.requestPermissions(permissions);
for (final result in results) {
print('${result.permission}: ${result.status}');
}
iOS Read Permission Workaround
While the SDK respects Apple's privacy guidelines by returning unknown for read permissions,
developers who need to determine actual read permission status can use the following workaround:
Workaround Strategy: Attempt to read a small amount of data.
If the read fails with NotAuthorizedException, the permission is denied. If it succeeds (even with empty results), the permission is granted.
Future<bool> checkIOSReadPermission(HealthDataType dataType) async {
try {
// Attempt to read a minimal amount of data
final request = dataType.readInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 1)),
endTime: DateTime.now(),
pageSize: 1, // Minimal data fetch
);
await connector.readRecords(request);
// If read succeeds, permission is granted
return true;
} on NotAuthorizedException {
// Permission was denied
return false;
}
}
β οΈ Important Considerations:
- This workaround is not officially recommended by Apple
- The SDK intentionally does not implement this as default behavior to ensure developers are aware of the privacy implications
Check Individual Permission Status
final status = await connector.getPermissionStatus(
HealthDataType.steps.readPermission,
);
switch (status) {
case PermissionStatus.granted:
print('Permission granted');
case PermissionStatus.denied:
print('Permission denied');
case PermissionStatus.unknown:
print('Cannot determine (iOS read permission)');
}
Get All Granted Permissions (Android Health Connect Only)
iOS Privacy Note: This API is not available on iOS. HealthKit does not provide a way to query all granted permissions to protect user privacy. Apps cannot enumerate what health data access they have been granted.
try {
final grantedPermissions = await connector.getGrantedPermissions();
for (final permission in grantedPermissions) {
if (permission is HealthDataPermission) {
print('${permission.dataType} (${permission.accessType})');
}
}
} on UnsupportedOperationException {
print('Only available on Android');
}
Revoke All Permissions (Android Health Connect Only)
iOS Privacy Note: This API is not available on iOS. HealthKit requires users to manually revoke permissions through the iOS Settings app. This ensures users have full control and visibility over their health data permissions.
try {
await connector.revokeAllPermissions();
} on UnsupportedOperationException {
print('Only available on Android');
}
π Reading Health Data #
Platform Note - Historical Data Access
Android Health Connect: By default, Health Connect only provides access to the last 30 days of historical health data. To read data older than 30 days, the
HealthPlatformFeature.readHealthDataHistoryfeature must be available and its permission must be granted.iOS HealthKit: HealthKit has no default limitation on historical data access. Apps can read health data from any time period, subject only to user permission.
Read by ID
final recordId = HealthRecordId('existing-record-id');
final request = HealthDataType.steps.readRecord(recordId);
final record = await connector.readRecord(request);
if (record != null) {
print('Steps: ${record.count.value}');
} else {
print('Record not found');
}
Read Multiple Records
final request = HealthDataType.steps.readInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 7)),
endTime: DateTime.now(),
pageSize: 100,
);
final response = await connector.readRecords(request);
for (final record in response.records) {
print('Steps: ${record.count.value} (${record.startTime} - ${record.endTime})');
}
Pagination
var request = HealthDataType.steps.readInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 30)),
endTime: DateTime.now(),
pageSize: 100,
);
final allRecords = <StepsRecord>[];
while (true) {
final response = await connector.readRecords(request);
allRecords.addAll(response.records.cast<StepsRecord>());
if (response.nextPageRequest == null) break;
request = response.nextPageRequest!;
}
print('Total records: ${allRecords.length}');
πΎ Writing Health Data #
Write Single Record
final stepRecord = StepsRecord(
id: HealthRecordId.none, // Must be .none for new records
startTime: DateTime.now().subtract(Duration(hours: 1)),
endTime: DateTime.now(),
count: Number(5000),
metadata: Metadata.automaticallyRecorded(
device: Device.fromType(DeviceType.phone),
),
);
final recordId = await connector.writeRecord(stepRecord);
print('Record ID: $recordId');
Atomic Write Multiple Records
All records succeed or all fail together:
final records = [
StepsRecord(
id: HealthRecordId.none,
startTime: DateTime.now().subtract(Duration(hours: 2)),
endTime: DateTime.now().subtract(Duration(hours: 1)),
count: Number(3000),
metadata: Metadata.automaticallyRecorded(
device: Device.fromType(DeviceType.phone),
),
),
StepsRecord(
id: HealthRecordId.none,
startTime: DateTime.now().subtract(Duration(hours: 1)),
endTime: DateTime.now(),
count: Number(2000),
metadata: Metadata.automaticallyRecorded(
device: Device.fromType(DeviceType.phone),
),
),
];
final recordIds = await connector.writeRecords(records);
print('Wrote ${recordIds.length} records');
βοΈ Updating Health Records #
iOS Privacy Note: HealthKit does not provide an update API because it uses an immutable data model. Once a health record is written to HealthKit, it cannot be modifiedβonly deleted.
Update Record (Android Health Connect Only)
final recordId = HealthRecordId('existing-record-id');
final request = HealthDataType.steps.readRecord(recordId);
final existingRecord = await connector.readRecord(request);
if (existingRecord != null) {
final updatedRecord = existingRecord.copyWith(
count: Number(existingRecord.count.value + 500),
);
await connector.updateRecord(updatedRecord);
print('Record updated');
}
Atomic Update Multiple Records (Android Health Connect Only)
Update multiple records atomicallyβall succeed or all fail together:
// Read existing records
final readRequest = HealthDataType.steps.readInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 7)),
endTime: DateTime.now(),
);
final response = await connector.readRecords(readRequest);
// Update all records by adding 100 steps to each
final updatedRecords = response.records.map((record) {
return record.copyWith(
count: Number(record.count.value + 100),
);
}).toList();
// Batch update all records
await connector.updateRecords(updatedRecords);
print('Updated ${updatedRecords.length} records');
iOS HealthKit Update Workaround (Delete + Write)
// 1. Delete existing record
await connector.deleteRecords(
HealthDataType.steps.deleteByIds([existingRecord.id]),
);
// 2. Write new record with updated values
final newRecord = StepsRecord(
id: HealthRecordId.none,
startTime: existingRecord.startTime,
endTime: existingRecord.endTime,
count: Number(newValue),
metadata: existingRecord.metadata,
);
final newId = await connector.writeRecord(newRecord);
// Note: newId will be different from the original ID
ποΈ Deleting Health Records #
Atomic Delete by IDs
await connector.deleteRecords(
HealthDataType.steps.deleteByIds([
HealthRecordId('id-1'),
HealthRecordId('id-2'),
]),
);
Atomic Delete by Time Range
await connector.deleteRecords(
HealthDataType.steps.deleteInTimeRange(
startTime: DateTime.now().subtract(Duration(days: 7)),
endTime: DateTime.now(),
),
);
Important: Apps can only delete records they created. Attempting to delete records from other apps will lead to
NotAuthorizedException.
β Aggregating Health Data #
Sum Aggregation
Get the total value over a period, such as total steps for a day:
final sumRequest = HealthDataType.steps.aggregateSum(
startTime: DateTime.now().subtract(Duration(days: 1)),
endTime: DateTime.now(),
);
final sumResponse = await connector.aggregate(sumRequest);
print('Total steps: ${sumResponse.value.value}');
Average Aggregation
Get the average value over 30 days:
final avgRequest = HealthDataType.weight.aggregateAvg(
startTime: DateTime.now().subtract(Duration(days: 30)),
endTime: DateTime.now(),
);
final avgResponse = await connector.aggregate(avgRequest);
print('Average weight: ${avgResponse.value.inKilograms} kg');
Minimum Aggregation
Get the minimum recorded value over a period:
final minRequest = HealthDataType.weight.aggregateMin(
startTime: DateTime.now().subtract(Duration(days: 30)),
endTime: DateTime.now(),
);
final minResponse = await connector.aggregate(minRequest);
print('Min weight: ${minResponse.value.inKilograms} kg');
Maximum Aggregation
Get the maximum recorded value over a period:
final maxRequest = HealthDataType.weight.aggregateMax(
startTime: DateTime.now().subtract(Duration(days: 30)),
endTime: DateTime.now(),
);
final maxResponse = await connector.aggregate(maxRequest);
print('Max weight: ${maxResponse.value.inKilograms} kg');
βοΈ Feature Management #
Platform features have different availability characteristics across platforms.
Platform Differences
- iOS HealthKit:
- All features are available and granted by default
- When checking feature status with
getFeatureStatus(), the SDK always returnsHealthPlatformFeatureStatus.available - When requesting feature permissions with
requestPermissions(), the SDK always returnsPermissionStatus.granted
- Android Health Connect:
- Feature availability depends on Android version and Health Connect SDK version
- Some features require specific minimum versions, f.e. background health data reading requires
Health Connect SDK
v1.1.0-alpha04
Checking Feature Availability
// Check if background reading is available
final status = await connector.getFeatureStatus(
HealthPlatformFeature.readHealthDataInBackground,
);
if (status == HealthPlatformFeatureStatus.available) {
// Feature is supported - safe to request permission
await connector.requestPermissions([
HealthPlatformFeature.readHealthDataInBackground.permission,
]);
} else {
// Feature not available on this device/version
print('Background reading not available');
// Implement fallback or disable feature in UI
}
Feature Permission Status
When checking the status of a feature permission:
final permissionStatus = await connector.getPermissionStatus(
HealthPlatformFeature.readHealthDataInBackground.permission,
);
// On iOS: Always returns PermissionStatus.granted
// On Android: Returns actual status (granted/denied)
β οΈ Error Handling #
The SDK provides two approaches for handling errors.
Approach 1: Catching Specific Exceptions
Use Dart's type-based exception handling to catch specific error types.
try {
await connector.requestPermissions([...]);
await connector.writeRecord(record);
} on NotAuthorizedException catch (e) {
// User denied or revoked permissions
// Recovery: Explain why permission is needed, guide to settings
print('Permission denied: ${e.message}');
} on InvalidConfigurationException catch (e) {
// Missing AndroidManifest.xml or Info.plist configuration
// Recovery: Fix app configuration (development-time error)
print('Configuration error: ${e.message}');
} on UnsupportedOperationException catch (e) {
// Platform doesn't support this operation
// Recovery: Check platform before calling, use alternative approach
print('Not supported: ${e.message}');
} on InvalidArgumentException catch (e) {
// Invalid input (e.g., startTime > endTime, negative values)
// Recovery: Validate inputs before calling
print('Invalid argument: ${e.message}');
} on HealthPlatformUnavailableException catch (e) {
// Device doesn't support health API
// Recovery: Disable health features for this device
print('Health unavailable: ${e.message}');
} on HealthPlatformNotInstalledOrUpdateRequiredException catch (e) {
// Health Connect needs installation/update (Android Health Connect Only)
// Recovery: Prompt user to install/update Health Connect
print('Health Connect needs update: ${e.message}');
} on RemoteErrorException catch (e) {
// Transient I/O or communication error
// Recovery: Retry with exponential backoff
print('Remote error: ${e.message}');
} on HealthConnectorException catch (e) {
// Generic fallback for unexpected errors
print('Unknown error [${e.code}]: ${e.message}');
}
Approach 2: Handling by Error Code
Catch the base HealthConnectorException and switch on HealthConnectorErrorCode.
try {
await connector.requestPermissions([...]);
await connector.writeRecord(record);
} on HealthConnectorException catch (e) {
switch (e.code) {
case HealthConnectorErrorCode.notAuthorized:
print('Permission denied: ${e.message}');
case HealthConnectorErrorCode.invalidConfiguration:
print('Configuration error: ${e.message}');
case HealthConnectorErrorCode.unsupportedOperation:
print('Not supported: ${e.message}');
case HealthConnectorErrorCode.invalidArgument:
print('Invalid argument: ${e.message}');
case HealthConnectorErrorCode.healthPlatformUnavailable:
print('Health unavailable: ${e.message}');
case HealthConnectorErrorCode.healthPlatformNotInstalledOrUpdateRequired:
print('Health Connect needs update: ${e.message}');
case HealthConnectorErrorCode.remoteError:
print('Remote error: ${e.message}');
case HealthConnectorErrorCode.unknown:
print('Unknown error [${e.code}]: ${e.message}');
}
}
Exception Quick Reference
| Exception | Cause | Recovery |
|---|---|---|
NotAuthorizedException |
Permission denied/revoked | Guide user to settings |
InvalidConfigurationException |
Missing manifest entries | Fix configuration |
UnsupportedOperationException |
API not available | Check platform first |
InvalidArgumentException |
Invalid input values | Validate inputs |
HealthPlatformUnavailableException |
Device unsupported | Disable health features |
HealthPlatformNotInstalledOrUpdateRequiredException |
Health Connect app missing | Prompt installation |
π§ Troubleshooting #
Common Issues
| Issue | Platform | Solution |
|---|---|---|
HealthPlatformUnavailableException |
iOS HealthKit API | Add HealthKit capability in Xcode β Signing & Capabilities |
HealthPlatformUnavailableException |
Android Health Connect API | Device doesn't support Health Connect (requires Android 8.0+) |
HealthPlatformNotInstalledOrUpdateRequiredException |
Android Health Connect API | Prompt user to install Health Connect |
InvalidConfigurationException |
Android Health Connect API | Add required permissions to AndroidManifest.xml |
InvalidConfigurationException |
iOS HealthKit API | Add NSHealthShareUsageDescription and NSHealthUpdateUsageDescription to Info.plist |
Read permissions return unknown |
iOS HealthKit API | Normal behaviorβiOS doesn't expose read permission status for privacy |
| Can't delete/update records | Both | Apps can only modify records they created |
Debug Logging
Enable detailed logs to troubleshoot issues:
final connector = await HealthConnector.create(
HealthConnectorConfig(isLoggerEnabled: true),
);
β FAQ #
Why do iOS read permissions always return unknown?
Apple intentionally hides read permission status to protect user privacy. This prevents apps from inferring whether a user has any health data by checking if read permission was denied.
How do I handle Health Connect not being installed?
final status = await HealthConnector.getHealthPlatformStatus();
if (status == HealthPlatformStatus.installationOrUpdateRequired) {
// Show dialog prompting user to install Health Connect
// Then launch the app store page:
await HealthConnector.launchHealthAppPageInAppStore();
}
What's the difference between heartRateSeriesRecord and heartRateMeasurementRecord?
- Android Health Connect: Uses
heartRateSeriesRecordβ a single record with multiple samples over a time interval - iOS HealthKit: Uses
heartRateMeasurementRecordβ each measurement is a separate record with its own ID
Can I read health data from other apps?
Yes, with user permission. When granted read access, you can read health data from all sources ( other apps, devices, manual entries).
Can I delete health data from other apps?
No. Apps can only delete records they created. This is a platform security restriction.
π― Real-World Use Cases #
Fitness Tracker
Track daily activity with steps, calories, and distance:
Future<Map<String, double>> getDailyActivitySummary(
HealthConnector connector,
DateTime date,
) async {
final startOfDay = DateTime(date.year, date.month, date.day);
final endOfDay = startOfDay.add(Duration(days: 1));
final steps = await connector.aggregate(
HealthDataType.steps.aggregateSum(
startTime: startOfDay,
endTime: endOfDay,
),
);
final calories = await connector.aggregate(
HealthDataType.activeCaloriesBurned.aggregateSum(
startTime: startOfDay,
endTime: endOfDay,
),
);
return {
'steps': steps.value.value,
'calories': calories.value.inKilocalories,
};
}
Health Dashboard
Display vital signs with recent measurements:
Future<void> displayVitals(HealthConnector connector) async {
final now = DateTime.now();
final weekAgo = now.subtract(Duration(days: 7));
// Get latest weight
final weightResponse = await connector.readRecords(
HealthDataType.weight.readInTimeRange(
startTime: weekAgo,
endTime: now,
pageSize: 1,
),
);
if (weightResponse.records.isNotEmpty) {
final latestWeight = weightResponse.records.first as WeightRecord;
print('Latest weight: ${latestWeight.weight.inKilograms} kg');
}
// Get heart rate average
final heartRateAvg = await connector.aggregate(
HealthDataType.restingHeartRate.aggregateAvg(
startTime: weekAgo,
endTime: now,
),
);
print('Avg resting HR: ${heartRateAvg.value.inBeatsPerMinute} bpm');
}
Nutrition Logger
Log meals with macronutrients:
Future<void> logMeal({
required HealthConnector connector,
required String mealName,
required double calories,
required double proteinGrams,
required double carbsGrams,
required double fatGrams,
}) async {
final now = DateTime.now();
final nutritionRecord = NutritionRecord(
id: HealthRecordId.none,
startTime: now.subtract(Duration(minutes: 30)),
endTime: now,
mealType: MealType.lunch,
name: mealName,
energy: Energy.kilocalories(calories),
protein: Mass.grams(proteinGrams),
totalCarbohydrate: Mass.grams(carbsGrams),
totalFat: Mass.grams(fatGrams),
metadata: Metadata.manual(),
);
await connector.writeRecord(nutritionRecord);
print('Meal logged: $mealName');
}
π References #
π Supported Health Data Types #
π Activity
General Activity
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Steps | Number of steps taken | HealthDataType.steps |
Sum | StepsRecord | HKQuantityTypeIdentifier.stepCount |
| Active Calories Burned | Energy burned through active movement | HealthDataType.activeCaloriesBurned |
Sum | ActiveCaloriesBurnedRecord | HKQuantityTypeIdentifier.activeEnergyBurned |
| Floors Climbed | Number of floors (flights of stairs) climbed | HealthDataType.floorsClimbed |
Sum | FloorsClimbedRecord | HKQuantityTypeIdentifier.flightsClimbed |
| Sexual Activity | Sexual activity tracking | HealthDataType.sexualActivity |
- | SexualActivityRecord | HKCategoryTypeIdentifier.sexualActivity |
| Wheelchair Pushes | Number of wheelchair pushes | HealthDataType.wheelchairPushes |
Sum | WheelchairPushesRecord | HKQuantityTypeIdentifier.pushCount |
| Cycling Cadence | Cycling pedaling cadence | HealthDataType.cyclingPedalingCadence |
Avg, Min, Max | CyclingPedalingCadenceRecord | HKQuantityTypeIdentifier.cyclingCadence |
| Total Calories Burned | Total energy burned (active + basal) | HealthDataType.totalCaloriesBurned |
Sum | TotalCaloriesBurnedRecord | - |
| Basal Energy Burned | Energy burned by basal metabolism | HealthDataType.basalEnergyBurned |
Sum | - | HKQuantityTypeIdentifier.basalEnergyBurned |
Distance Types
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Distance (generic) | Generic distance traveled | HealthDataType.distance |
Sum | DistanceRecord | - |
| Walking/Running Distance | Distance covered by walking or running | HealthDataType.walkingRunningDistance |
Sum | - | HKQuantityTypeIdentifier.distanceWalkingRunning |
| Cycling Distance | Distance covered by cycling | HealthDataType.cyclingDistance |
Sum | - | HKQuantityTypeIdentifier.distanceCycling |
| Swimming Distance | Distance covered by swimming | HealthDataType.swimmingDistance |
Sum | - | HKQuantityTypeIdentifier.distanceSwimming |
| Wheelchair Distance | Distance covered using a wheelchair | HealthDataType.wheelchairDistance |
Sum | - | HKQuantityTypeIdentifier.distanceWheelchair |
| Downhill Snow Sports Distance | Distance covered during downhill snow sports | HealthDataType.downhillSnowSportsDistance |
Sum | - | HKQuantityTypeIdentifier.distanceDownhillSnowSports |
| Cross Country Skiing Distance | Distance covered during cross country skiing | HealthDataType.crossCountrySkiingDistance |
Sum | - | HKQuantityTypeIdentifier.distanceCrossCountrySkiing |
| Paddle Sports Distance | Distance covered during paddle sports | HealthDataType.paddleSportsDistance |
Sum | - | HKQuantityTypeIdentifier.distancePaddleSports |
| Rowing Distance | Distance covered during rowing | HealthDataType.rowingDistance |
Sum | - | HKQuantityTypeIdentifier.distanceRowing |
| Skating Sports Distance | Distance covered during skating sports | HealthDataType.skatingSportsDistance |
Sum | - | HKQuantityTypeIdentifier.distanceSkatingSports |
| Six Minute Walk Test Distance | Distance covered during 6-minute walk test | HealthDataType.sixMinuteWalkTestDistance |
Sum | - | HKQuantityTypeIdentifier.sixMinuteWalkTestDistance |
Speed Types
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Speed Series | Speed measurements over time | HealthDataType.speedSeries |
- | SpeedRecord | - |
| Walking Speed | Walking speed measurement | HealthDataType.walkingSpeed |
- | - | HKQuantityTypeIdentifier.walkingSpeed |
| Running Speed | Running speed measurement | HealthDataType.runningSpeed |
- | - | HKQuantityTypeIdentifier.runningSpeed |
| Stair Ascent Speed | Speed while climbing stairs | HealthDataType.stairAscentSpeed |
- | - | HKQuantityTypeIdentifier.stairAscentSpeed |
| Stair Descent Speed | Speed while descending stairs | HealthDataType.stairDescentSpeed |
- | - | HKQuantityTypeIdentifier.stairDescentSpeed |
Power Types
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Power Series | Power measurements over time | HealthDataType.powerSeries |
Avg, Min, Max | PowerRecord | - |
| Cycling Power | Power output during cycling | HealthDataType.cyclingPower |
Avg, Min, Max | - | HKQuantityTypeIdentifier.cyclingPower |
Exercise Sessions
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Exercise Session | Complete workout session with exercise type and stats | HealthDataType.exerciseSession |
Duration | ExerciseSessionRecord | HKWorkout |
Exercise Types
| Exercise Type | Android Health Connect | iOS HealthKit |
|---|---|---|
ExerciseType.other |
β | β |
ExerciseType.running |
β | β |
ExerciseType.runningTreadmill |
β | β |
ExerciseType.walking |
β | β |
ExerciseType.cycling |
β | β |
ExerciseType.cyclingStationary |
β | β |
ExerciseType.hiking |
β | β |
ExerciseType.handCycling |
β | β |
ExerciseType.trackAndField |
β | β |
ExerciseType.swimming |
β | β |
ExerciseType.swimmingOpenWater |
β | β |
ExerciseType.swimmingPool |
β | β |
ExerciseType.surfing |
β | β |
ExerciseType.waterPolo |
β | β |
ExerciseType.rowing |
β | β |
ExerciseType.sailing |
β | β |
ExerciseType.paddling |
β | β |
ExerciseType.diving |
β | β |
ExerciseType.waterFitness |
β | β |
ExerciseType.waterSports |
β | β |
ExerciseType.strengthTraining |
β | β |
ExerciseType.weightlifting |
β | β |
ExerciseType.calisthenics |
β | β |
ExerciseType.basketball |
β | β |
ExerciseType.soccer |
β | β |
ExerciseType.americanFootball |
β | β |
ExerciseType.frisbeeDisc |
β | β |
ExerciseType.australianFootball |
β | β |
ExerciseType.baseball |
β | β |
ExerciseType.softball |
β | β |
ExerciseType.volleyball |
β | β |
ExerciseType.rugby |
β | β |
ExerciseType.cricket |
β | β |
ExerciseType.handball |
β | β |
ExerciseType.iceHockey |
β | β |
ExerciseType.rollerHockey |
β | β |
ExerciseType.hockey |
β | β |
ExerciseType.lacrosse |
β | β |
ExerciseType.discSports |
β | β |
ExerciseType.tennis |
β | β |
ExerciseType.tableTennis |
β | β |
ExerciseType.badminton |
β | β |
ExerciseType.squash |
β | β |
ExerciseType.racquetball |
β | β |
ExerciseType.pickleball |
β | β |
ExerciseType.skiing |
β | β |
ExerciseType.snowboarding |
β | β |
ExerciseType.snowshoeing |
β | β |
ExerciseType.skating |
β | β |
ExerciseType.crossCountrySkiing |
β | β |
ExerciseType.curling |
β | β |
ExerciseType.downhillSkiing |
β | β |
ExerciseType.snowSports |
β | β |
ExerciseType.boxing |
β | β |
ExerciseType.kickboxing |
β | β |
ExerciseType.martialArts |
β | β |
ExerciseType.wrestling |
β | β |
ExerciseType.fencing |
β | β |
ExerciseType.taiChi |
β | β |
ExerciseType.dancing |
β | β |
ExerciseType.gymnastics |
β | β |
ExerciseType.barre |
β | β |
ExerciseType.cardioDance |
β | β |
ExerciseType.socialDance |
β | β |
ExerciseType.yoga |
β | β |
ExerciseType.pilates |
β | β |
ExerciseType.highIntensityIntervalTraining |
β | β |
ExerciseType.elliptical |
β | β |
ExerciseType.exerciseClass |
β | β |
ExerciseType.bootCamp |
β | β |
ExerciseType.guidedBreathing |
β | β |
ExerciseType.stairClimbing |
β | β |
ExerciseType.crossTraining |
β | β |
ExerciseType.jumpRope |
β | β |
ExerciseType.fitnessGaming |
β | β |
ExerciseType.mixedCardio |
β | β |
ExerciseType.cooldown |
β | β |
ExerciseType.flexibility |
β | β |
ExerciseType.mindAndBody |
β | β |
ExerciseType.preparationAndRecovery |
β | β |
ExerciseType.stepTraining |
β | β |
ExerciseType.coreTraining |
β | β |
ExerciseType.golf |
β | β |
ExerciseType.archery |
β | β |
ExerciseType.bowling |
β | β |
ExerciseType.paragliding |
β | β |
ExerciseType.climbing |
β | β |
ExerciseType.equestrianSports |
β | β |
ExerciseType.fishing |
β | β |
ExerciseType.hunting |
β | β |
ExerciseType.play |
β | β |
ExerciseType.wheelchair |
β | β |
ExerciseType.wheelchairWalkPace |
β | β |
ExerciseType.wheelchairRunPace |
β | β |
ExerciseType.transition |
β | β |
ExerciseType.swimBikeRun |
β | β |
π Body Measurements
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Weight | Body weight measurement | HealthDataType.weight |
Avg, Min, Max | WeightRecord | HKQuantityTypeIdentifier.bodyMass |
| Height | Body height measurement | HealthDataType.height |
Avg, Min, Max | HeightRecord | HKQuantityTypeIdentifier.height |
| Body Fat Percentage | Percentage of body fat | HealthDataType.bodyFatPercentage |
Avg, Min, Max | BodyFatRecord | HKQuantityTypeIdentifier.bodyFatPercentage |
| Lean Body Mass | Mass of body excluding fat | HealthDataType.leanBodyMass |
Avg, Min, Max | LeanBodyMassRecord | HKQuantityTypeIdentifier.leanBodyMass |
| Body Temperature | Core body temperature | HealthDataType.bodyTemperature |
Avg, Min, Max | BodyTemperatureRecord | HKQuantityTypeIdentifier.bodyTemperature |
| Body Water Mass | Mass of body water | HealthDataType.bodyWaterMass |
Avg, Min, Max | BodyWaterMassRecord | - |
| Bone Mass | Mass of bone mineral | HealthDataType.boneMass |
Avg, Min, Max | BoneMassRecord | - |
| Body Mass Index | Body Mass Index (BMI) | HealthDataType.bodyMassIndex |
Avg, Min, Max | - | HKQuantityTypeIdentifier.bodyMassIndex |
| Waist Circumference | Waist circumference measurement | HealthDataType.waistCircumference |
Avg, Min, Max | - | HKQuantityTypeIdentifier.waistCircumference |
β€οΈ Vitals
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Heart Rate Series | Heart rate measurements over time | HealthDataType.heartRateSeriesRecord |
Avg, Min, Max | HeartRateRecord | - |
| Heart Rate Measurement | Single heart rate measurement | HealthDataType.heartRateMeasurementRecord |
Avg, Min, Max | - | HKQuantityTypeIdentifier.heartRate |
| Resting Heart Rate | Heart rate while at rest | HealthDataType.restingHeartRate |
Avg, Min, Max | RestingHeartRateRecord | HKQuantityTypeIdentifier.restingHeartRate |
| Blood Pressure | Systolic and diastolic blood pressure | HealthDataType.bloodPressure |
Avg, Min, Max | BloodPressureRecord | HKCorrelationTypeIdentifier.bloodPressure |
| Systolic Blood Pressure | Upper blood pressure value | HealthDataType.systolicBloodPressure |
Avg, Min, Max | - | HKQuantityTypeIdentifier.bloodPressureSystolic |
| Diastolic Blood Pressure | Lower blood pressure value | HealthDataType.diastolicBloodPressure |
Avg, Min, Max | - | HKQuantityTypeIdentifier.bloodPressureDiastolic |
| Oxygen Saturation | Blood oxygen saturation percentage | HealthDataType.oxygenSaturation |
Avg, Min, Max | OxygenSaturationRecord | HKQuantityTypeIdentifier.oxygenSaturation |
| Respiratory Rate | Breathing rate (breaths per minute) | HealthDataType.respiratoryRate |
Avg, Min, Max | RespiratoryRateRecord | HKQuantityTypeIdentifier.respiratoryRate |
| VOβ Max | Maximum oxygen consumption | HealthDataType.vo2Max |
Avg, Min, Max | Vo2MaxRecord | HKQuantityTypeIdentifier.vo2Max |
| Blood Glucose | Blood glucose concentration | HealthDataType.bloodGlucose |
Avg, Min, Max | BloodGlucoseRecord | HKQuantityTypeIdentifier.bloodGlucose |
| HRV RMSSD | Heart Rate Variability (RMSSD) | HealthDataType.heartRateVariabilityRmssd |
- | HeartRateVariabilityRmssdRecord | - |
| HRV SDNN | Heart Rate Variability (SDNN) | HealthDataType.heartRateVariabilitySdnn |
- | - | HKQuantityTypeIdentifier.heartRateVariabilitySDNN |
π΄ Sleep
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Sleep Session | Complete sleep session with sleep stages | HealthDataType.sleepSession |
- | SleepSessionRecord | - |
| Sleep Stage Record | Individual sleep stage measurement | HealthDataType.sleepStageRecord |
- | - | HKCategoryTypeIdentifier.sleepAnalysis |
π Nutrition
Core & Hydration
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Nutrition (composite) | Complete nutrition record with macros and micronutrients | HealthDataType.nutrition |
- | NutritionRecord | HKCorrelationType.food |
| Energy | Total energy intake from food | HealthDataType.energyNutrient (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.energy field) | HKQuantityTypeIdentifier.dietaryEnergyConsumed |
| Hydration/Water | Water and fluid intake | HealthDataType.hydration |
Sum | HydrationRecord | HKQuantityTypeIdentifier.dietaryWater |
Macronutrients
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Protein | Protein intake | HealthDataType.protein (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.protein) | HKQuantityTypeIdentifier.dietaryProtein |
| Total Carbohydrate | Total carbs intake | HealthDataType.totalCarbohydrate (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.carbs) | HKQuantityType Identifier.dietaryCarbohydrates |
| Total Fat | Total fat intake | HealthDataType.totalFat (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.totalFat) | HKQuantityTypeIdentifier.dietaryFatTotal |
| Caffeine | Caffeine intake | HealthDataType.caffeine (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.caffeine) | HKQuantityTypeIdentifier.dietaryCaffeine |
Fats
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Saturated Fat | Saturated fat intake | HealthDataType.saturatedFat (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.saturatedFat) | HKQuantityTypeIdentifier.dietaryFatSaturated |
| Monounsaturated Fat | Monounsaturated fat intake | HealthDataType.monounsaturatedFat (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.monounsaturatedFat) | HKQuantityTypeIdentifier.dietaryFatMonounsaturated |
| Polyunsaturated Fat | Polyunsaturated fat intake | HealthDataType.polyunsaturatedFat (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.polyunsaturatedFat) | HKQuantityTypeIdentifier.dietaryFatPolyunsaturated |
| Cholesterol | Cholesterol intake | HealthDataType.cholesterol (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.cholesterol) | HKQuantityTypeIdentifier.dietaryCholesterol |
Fiber & Sugar
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Dietary Fiber | Dietary fiber intake | HealthDataType.dietaryFiber (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.dietaryFiber) | HKQuantityTypeIdentifier.dietaryFiber |
| Sugar | Sugar intake | HealthDataType.sugar (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.sugar) | HKQuantityTypeIdentifier.dietarySugar |
Minerals
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Calcium | Calcium intake | HealthDataType.calcium (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.calcium) | HKQuantityTypeIdentifier.dietaryCalcium |
| Iron | Iron intake | HealthDataType.iron (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.iron) | HKQuantityTypeIdentifier.dietaryIron |
| Magnesium | Magnesium intake | HealthDataType.magnesium (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.magnesium) | HKQuantityTypeIdentifier.dietaryMagnesium |
| Manganese | Manganese intake | HealthDataType.manganese (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.manganese) | HKQuantityTypeIdentifier.dietaryManganese |
| Phosphorus | Phosphorus intake | HealthDataType.phosphorus (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.phosphorus) | HKQuantityTypeIdentifier.dietaryPhosphorus |
| Potassium | Potassium intake | HealthDataType.potassium (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.potassium) | HKQuantityTypeIdentifier.dietaryPotassium |
| Selenium | Selenium intake | HealthDataType.selenium (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.selenium) | HKQuantityTypeIdentifier.dietarySelenium |
| Sodium | Sodium intake | HealthDataType.sodium (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.sodium) | HKQuantityTypeIdentifier.dietarySodium |
| Zinc | Zinc intake | HealthDataType.zinc (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.zinc) | HKQuantityTypeIdentifier.dietaryZinc |
B Vitamins
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Thiamin (B1) | Thiamin (vitamin B1) intake | HealthDataType.thiamin (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.thiamin) | HKQuantityTypeIdentifier.dietaryThiamin |
| Riboflavin (B2) | Riboflavin (vitamin B2) | HealthDataType.riboflavin (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.riboflavin) | HKQuantityTypeIdentifier.dietaryRiboflavin |
| Niacin (B3) | Niacin (vitamin B3) intake | HealthDataType.niacin (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.niacin) | HKQuantityTypeIdentifier.dietaryNiacin |
| Pantothenic Acid (B5) | Pantothenic acid (vitamin B5) | HealthDataType.pantothenicAcid (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.pantothenicAcid) | HKQuantityTypeIdentifier.dietaryPantothenicAcid |
| Vitamin B6 | Vitamin B6 intake | HealthDataType.vitaminB6 (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminB6) | HKQuantityTypeIdentifier.dietaryVitaminB6 |
| Biotin (B7) | Biotin (vitamin B7) intake | HealthDataType.biotin (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.biotin) | HKQuantityTypeIdentifier.dietaryBiotin |
| Folate (B9) | Folate (vitamin B9) intake | HealthDataType.folate (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.folate) | HKQuantityTypeIdentifier.dietaryFolate |
| Vitamin B12 | Vitamin B12 intake | HealthDataType.vitaminB12 (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminB12) | HKQuantityTypeIdentifier.dietaryVitaminB12 |
Other Vitamins
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Vitamin A | Vitamin A intake | HealthDataType.vitaminA (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminA) | HKQuantityTypeIdentifier.dietaryVitaminA |
| Vitamin C | Vitamin C intake | HealthDataType.vitaminC (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminC) | HKQuantityTypeIdentifier.dietaryVitaminC |
| Vitamin D | Vitamin D intake | HealthDataType.vitaminD (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminD) | HKQuantityTypeIdentifier.dietaryVitaminD |
| Vitamin E | Vitamin E intake | HealthDataType.vitaminE (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminE) | HKQuantityTypeIdentifier.dietaryVitaminE |
| Vitamin K | Vitamin K intake | HealthDataType.vitaminK (iOS HealthKit Only) |
Sum | NutritionRecord (NutritionRecord.vitaminK) | HKQuantityTypeIdentifier.dietaryVitaminK |
π§ Wellness
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Mindfulness Session | Meditation and mindfulness sessions | HealthDataType.mindfulnessSession |
Sum | MindfulnessSessionRecord | HKCategoryTypeIdentifier.mindfulSession |
πͺ· Cycle Tracking
| Data Type | Description | Data Type | Supported Aggregation | Android Health Connect API | iOS HealthKit API |
|---|---|---|---|---|---|
| Cervical Mucus | Cervical mucus observations for fertility | HealthDataType.cervicalMucus |
- | CervicalMucusRecord | HKCategoryTypeIdentifier.cervicalMucusQuality |
| Basal Body Temperature | Basal body temperature | HealthDataType.basalBodyTemperature |
Avg, Min, Max | BasalBodyTemperatureRecord | HKQuantityTypeIdentifier.basalBodyTemperature |
| Menstruation Flow | Menstrual flow intensity | HealthDataType.menstrualFlow |
- | MenstruationFlowRecord | HKCategoryTypeIdentifier.menstrualFlow |
| Ovulation Test | Ovulation test result | HealthDataType.ovulationTest |
- | OvulationTestRecord | HKCategoryTypeIdentifier.ovulationTestResult |
| Intermenstrual Bleeding | Intermenstrual bleeding spotting | HealthDataType.intermenstrualBleeding |
- | - | HKCategoryTypeIdentifier.persistentIntermenstrualBleeding |
π Migration Guides #
- Migration Guide from
v1.x.xtov2.x.x
π€ Contributing #
Contributions are welcome! See our GitHub Issues to report bugs or request features.
π License #
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.