Skip to content

Conversation

iarata
Copy link
Contributor

@iarata iarata commented Jun 3, 2025

Architecture

Core Components

SwiftHealthPlugin (Main Plugin Class)
├── HealthDataReader (Reading health data)
├── HealthDataWriter (Writing health data)
├── HealthDataOperations (Permissions and deletion)
├── HealthUtilities (Helper functions)
└── HealthConstants (Constants and enums)

Classes and Their Responsibilities

1. SwiftHealthPlugin

Main plugin class that coordinates all health data operations and serves as the entry point for Flutter method channel calls.

Properties:

  • healthStore: HKHealthStore instance for interacting with HealthKit
  • dataTypesDict: Dictionary mapping string keys to HKSampleType objects
  • unitDict: Dictionary mapping string keys to HKUnit objects
  • workoutActivityTypeMap: Dictionary mapping workout activity names to HKWorkoutActivityType

Methods:

register(with registrar:)

Registers the plugin with Flutter's plugin registrar.

handle(_ call:result:)

Main method channel handler that routes Flutter method calls to appropriate service classes.

Supported Method Calls:

  • checkIfHealthDataAvailable
  • requestAuthorization
  • getData
  • getIntervalData
  • getTotalStepsInInterval
  • writeData
  • writeAudiogram
  • writeBloodPressure
  • writeMeal
  • writeInsulinDelivery
  • writeWorkoutData
  • writeMenstruationFlow
  • hasPermissions
  • delete
  • deleteByUUID

2. HealthDataReader

Handles all read operations from HealthKit.

Methods:

  • getData(call:result:) Reads health data for a specific data type within a date range.
  • getIntervalData(call:result:) Retrieves aggregated health data in specified time intervals.
  • getTotalStepsInInterval(call:result:) Gets the total step count within a specified time period.

3. HealthDataWriter

Handles all write operations to HealthKit.

Methods:

  • writeData(call:result:) Writes general health data points.
  • writeAudiogram(call:result:) Writes audiogram data with frequency and sensitivity measurements.
  • writeBloodPressure(call:result:) Creates a blood pressure correlation with systolic and diastolic values.
  • writeMeal(call:result:) Writes nutritional data as a food correlation (iOS 15+).
  • writeWorkoutData(call:result:) Records workout sessions with activity type, duration, and optional metrics.

4. HealthDataOperations

Manages permissions, authorization, and data deletion.

Methods:

  • hasPermissions(call:result:) Checks if the app has the required permissions for specified health data types. Permission Types: 0: READ access, 1: WRITE access, Other: READ_WRITE access
  • requestAuthorization(call:result:) Requests authorization from the user for specified health data types.
  • delete(call:result:) Deletes health data within a specified date range.
  • deleteByUUID(call:result:) Deletes a specific health record by its UUID.

5. HealthUtilities

Provides helper methods for data conversion and sanitization.

Methods:

  • sanitizeMetadata(_ metadata:) Converts HealthKit metadata to Flutter-compatible format.
  • dateFromMilliseconds(_ milliseconds:) Converts milliseconds since epoch to Date object.

Error Handling

The plugin uses PluginError for internal error handling and returns appropriate Flutter errors:

  • ARGUMENT_ERROR: Invalid or missing arguments
  • INVALID_TYPE: Unknown health data type
  • HEALTH_ERROR: HealthKit operation failed
  • WRITE_ERROR: Failed to write data
  • PERMISSION_ERROR: Permission-related errors
  • DELETE_ERROR: Failed to delete data

Metadata Handling

The plugin sanitizes HealthKit metadata to ensure Flutter compatibility:

  • Converts NSNumber, String, Bool values
  • Recursively processes arrays and dictionaries
  • Filters out non-serializable types

Now all HealthKit operations are asynchronous, results are dispatched to the main thread before calling Flutter callbacks, the plugin handles concurrent operations safely

@iarata iarata merged commit 716b3ed into master Jun 3, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants