iOS (Swift)
Read authorized Apple Health data through HealthKit and synchronize it with Sonar.
Scope
The iOS SDK coordinates permission requests, reads authorized HealthKit data, maintains incremental synchronization state, and uploads changes for the associated Sonar user. Apple Health remains the user-facing data store; HealthKit is the framework the app integrates with.
The SDK requests the complete Sonar-supported HealthKit read set and synchronizes the types authorized by the user. It does not write data to Apple Health. See Supported Native Data for the exact HealthKit coverage.
Requirements
| Area | Requirement |
|---|---|
| Platform | iOS 16 or later |
| Project | Add the Sonar iOS SDK to the application target |
| Capability | Enable HealthKit and HealthKit Background Delivery for the application target |
| Privacy | Add NSHealthShareUsageDescription with a clear explanation of why the app reads health data |
| Identity | Provide a client-token callback backed by your authenticated backend |
| Background sync | Enable Background fetch and Background processing |
| Background tasks | Permit co.sonarhealth.sdk.refresh and co.sonarhealth.sdk.backfill in BGTaskSchedulerPermittedIdentifiers |
The corresponding Info.plist entries are:
<key>NSHealthShareUsageDescription</key>
<string>Explain why your app reads the person's health data.</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>co.sonarhealth.sdk.refresh</string>
<string>co.sonarhealth.sdk.backfill</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>Install
Add the package in Xcode using:
https://github.com/Sonar-Health/sonar-ios-sdk.gitSelect version 1.0.0 or newer and add the SonarSDK product to the application target. For a Swift package manifest:
dependencies: [
.package(
url: "https://github.com/Sonar-Health/sonar-ios-sdk.git",
from: "1.0.0"
)
]Configure Every Launch
Call configure from application(_:didFinishLaunchingWithOptions:) on every launch. This timing is required because iOS ignores background-task and HealthKit observer registration performed after application launch finishes.
import SonarSDK
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
do {
try Sonar.configure(
appId: "app_01K4M7D9R3W2V8Y6T5Q1N0PABC",
environment: .sandbox
)
} catch {
assertionFailure("Sonar could not be configured: \(error)")
return false
}
return true
}
}Call authenticate on every launch as soon as the application’s signed-in customer session is available. The SDK persists its Sonar session, so this normally returns alreadyAuthenticated; calling it again registers the in-memory client-token provider needed if that session later has to be replaced.
Authenticate and Connect
import SonarSDK
try await Sonar.authenticate { context in
try await customerAPI.createSonarClientToken(
appId: context.appId,
installationId: context.installationId
).clientToken
}
let observation = Sonar.observeState { state in
renderNativeHealthState(state)
}
try await Sonar.connect(.appleHealth)Keep the returned observation while the owning application lifecycle is active and call observation.cancel() when it ends. Authentication, provider, synchronization, and sign-out methods use Swift concurrency and return the shared method results.
Integration Flow
Add the SDK
Add the SonarSDK Swift package to the application target and keep it aligned with the version used by your React Native bindings, when applicable.
Configure HealthKit
Enable HealthKit and HealthKit Background Delivery. Add NSHealthShareUsageDescription; the SDK is read-only, so it does not require NSHealthUpdateUsageDescription. Enable Background fetch and Background processing, then add both Sonar task identifiers to BGTaskSchedulerPermittedIdentifiers.
Configure and Authenticate
Configure the SDK with the registered application and environment, then authenticate through the mobile app’s client-token provider. The SDK exchanges the short-lived token for a user-scoped session. A Sonar API key must never be included in the app.
Connect Apple Health
Call connect to request the Sonar HealthKit read set, record the provider connection, and start automatic synchronization. The SDK continues with the types authorized by the user.
Observe and Synchronize
Observe SDK state for progress, retry, and reauthorization requirements. Use sync() for an immediate incremental pull or resync(provider) for a safe full replay.
Permission Behavior
- The SDK reports whether HealthKit is available before the app presents onboarding.
- The mobile app declares why it reads health data through
NSHealthShareUsageDescription. - Synchronization continues for authorized types when the user grants only part of the request.
- iOS does not reveal read-denial status for individual HealthKit types; an empty result must not be presented as proof that the user denied access.
- The app directs the user to Apple Health settings when authorization needs attention.
Synchronization Contract
- The SDK owns the HealthKit query anchors and uploads changes incrementally.
- Duplicate uploads are idempotent, and edited samples update the normalized record.
- Initial synchronization covers recent data first, then continues backwards for up to two years.
- Observer delivery schedules background synchronization when iOS permits execution.
- A failed upload does not advance its HealthKit position. A later foreground, observer, or background opportunity reads and sends that work again.
- Sign-out or user switch revokes the current Sonar session and clears its local credentials before another user is initialized.
Read Supported Native Data, the SDK Interface, SDK Synchronization, and Provider Lifecycle, return to the Mobile SDK overview, or continue to Android (Kotlin).
Sonar