AnpherosAnpheros PlatformDevelopers

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Apple Health (HealthKit) vers FHIR

Lire les données Apple Watch et Apple Health avec HealthKit en Swift, par jour local, et les écrire dans un dossier FHIR R4 : permissions, synchronisation en arrière-plan, règles Apple.

Les données d'Apple Watch résident dans Apple Health sur l'iPhone jumelé, et la seule façon de les lire est HealthKit, depuis une application sur cet iPhone, avec la permission de la personne. Pour les intégrer dans un enregistrement FHIR, lisez les statistiques quotidiennes avec HKStatisticsCollectionQuery, envoyez les valeurs à votre backend, et écrivez chaque métrique comme une Observation avec un code LOINC et une unité UCUM. Cette page présente le code Swift (vérifié par type avec le SDK iOS 17), les permissions et les règles définies par Apple, et comment les valeurs deviennent des Observations FHIR R4.

Ce que contient Apple Health

Apple Health collecte ce que l'iPhone et l'Apple Watch mesurent — fréquence cardiaque, fréquence cardiaque au repos, variabilité de la fréquence cardiaque (SDNN), oxygène sanguin, fréquence respiratoire, pas, énergie, stades de sommeil, notifications de rythme irrégulier, enregistrements ECG — et ce que d'autres applications écrivent : Garmin Connect, Oura, Withings Health Mate, balances connectées, tensiomètres, glucomètres. Lire Apple Health couvre donc plus que l'Apple Watch.

Il n'y a pas de serveur HealthKit ni d'API web. Les données restent sur l'appareil (et dans la sauvegarde iCloud chiffrée de la personne) ; votre application les lit localement.

Permissions

  1. Activez la capacité HealthKit dans Xcode et ajoutez NSHealthShareUsageDescription à Info.plist (plus NSHealthUpdateUsageDescription si vous écrivez).
  2. Demandez les types dont vous avez besoin. Les utilisateurs peuvent autoriser certains types et en refuser d'autres, et HealthKit ne vous indique pas si l'accès en lecture a été refusé : un type refusé ne renvoie simplement aucune donnée. Concevez vos écrans pour gérer le cas "aucune donnée" plutôt qu'une erreur.
  3. Demandez au moment où l'utilisateur se connecte, en expliquant pourquoi, et non au premier lancement.

Lecture des valeurs quotidiennes en Swift

import Foundation
import HealthKit

/// One day of Apple Health data, ready to send to your backend.
struct DailyValue: Codable {
    let metric: String      // "heart_rate", "steps"
    let day: String         // "2026-10-01", the user's local day
    let value: Double
    let min: Double?
    let max: Double?
}

let store = HKHealthStore()
let heartRate = HKQuantityType(.heartRate)
let steps = HKQuantityType(.stepCount)

func requestAccess() async throws {
    // Read-only: the app never writes to Apple Health.
    try await store.requestAuthorization(toShare: [], read: [heartRate, steps])
}

/// Daily statistics for the last `days` days, one value per local calendar day.
func dailyValues(_ type: HKQuantityType, metric: String, unit: HKUnit,
                 options: HKStatisticsOptions, days: Int) async throws -> [DailyValue] {
    let calendar = Calendar.current
    let end = calendar.startOfDay(for: Date()).addingTimeInterval(86_400)
    let start = calendar.date(byAdding: .day, value: -days, to: end)!
    let query = HKStatisticsCollectionQueryDescriptor(
        predicate: HKSamplePredicate.quantitySample(type: type,
                                                    predicate: HKQuery.predicateForSamples(withStart: start, end: end)),
        options: options,
        anchorDate: start,
        intervalComponents: DateComponents(day: 1))
    let collection = try await query.result(for: store)
    let fmt = DateFormatter()
    fmt.dateFormat = "yyyy-MM-dd"
    var out: [DailyValue] = []
    collection.enumerateStatistics(from: start, to: end) { stats, _ in
        let day = fmt.string(from: stats.startDate)
        if options.contains(.cumulativeSum), let sum = stats.sumQuantity() {
            out.append(DailyValue(metric: metric, day: day, value: sum.doubleValue(for: unit), min: nil, max: nil))
        } else if let avg = stats.averageQuantity() {
            out.append(DailyValue(metric: metric, day: day, value: avg.doubleValue(for: unit),
                                  min: stats.minimumQuantity()?.doubleValue(for: unit),
                                  max: stats.maximumQuantity()?.doubleValue(for: unit)))
        }
    }
    return out
}

func collect() async throws -> [DailyValue] {
    try await requestAccess()
    let bpm = HKUnit.count().unitDivided(by: .minute())
    let hr = try await dailyValues(heartRate, metric: "heart_rate", unit: bpm,
                                   options: [.discreteAverage, .discreteMin, .discreteMax], days: 30)
    let st = try await dailyValues(steps, metric: "steps", unit: .count(), options: .cumulativeSum, days: 30)
    return hr + st   // POST these to your backend, which writes them to the FHIR record
}

Pourquoi des requêtes statistiques plutôt que la lecture d'échantillons : HKStatisticsCollectionQuery renvoie des totaux et des moyennes par jour qu'Apple Health a déjà dédupliqués entre les sources, de sorte que les pas comptés par l'iPhone et la Watch ne sont pas ajoutés deux fois. La lecture d'échantillons bruts et leur sommation par vous-même est la source la plus courante de comptages de pas gonflés.

Les jours sont les jours calendaires locaux de la personne (Calendar.current). Conservez-les ainsi jusqu'au dossier FHIR, où le effectivePeriod de l'Observation est ce jour local avec son décalage horaire.

Garder le dossier à jour

Des valeurs Swift aux Observations FHIR

Envoyez le tableau DailyValue à votre backend et écrivez une Observation par personne, métrique et jour avec un identifiant stable, en la mettant à jour lorsque le même jour revient. Le tableau de mappage (type HealthKit → LOINC → UCUM), un exemple JSON validé et le code TypeScript qui effectue cette opération d'insertion/mise à jour (upsert), exécuté sur la plateforme, se trouvent sur Données portables en FHIR. Les codes pour les deux métriques ici sont :

HealthKit LOINC UCUM Valeur par jour
heartRate 8867-4 Heart rate /min moyenne, avec minimum et maximum comme composantes
stepCount 41950-7 Number of steps in 24 hour {steps} total

Règles d'Apple concernant les données de santé

Apple Health Records

Séparément des données de fitness, Apple Health peut contenir des dossiers cliniques téléchargés à partir de systèmes de santé participants (principalement aux États-Unis), et HealthKit les expose sous forme d'objets HKClinicalRecord qui portent la ressource FHIR d'origine. Leur lecture nécessite sa propre autorisation et son propre entitlement. Il s'agit d'une intégration différente de celle des données de wearables, et Anpheros Daily ne les lit pas aujourd'hui.

Où Anpheros s'intègre

La plateforme Anpheros stocke le résultat : le dossier FHIR R4 de la personne, avec chaque valeur de dispositif portable comme une Observation marquée comme données de dispositif, un consentement pour d'autres applications, la provenance et un journal d'accès. Elle ne lit pas Apple Health elle-même — cela se passe dans votre application iOS. L'application d'Anpheros, Anpheros Daily, lit Apple Health sur iPhone (plans Plus et Max) et écrit des résumés quotidiens dans le dossier avec les codes ci-dessus.

Questions fréquemment posées

Puis-je lire les données Apple Watch depuis un serveur ?

Non. Les données Apple Watch sont synchronisées avec Apple Health sur l'iPhone jumelé, et HealthKit ne peut être utilisé que par une application sur cet appareil. L'application lit les données et les envoie à votre serveur.

Existe-t-il une API web ou une API REST pour Apple Health ?

Non. Apple ne propose pas d'API web ou REST pour Apple Health : HealthKit s'exécute uniquement à l'intérieur d'une application sur l'iPhone (ou l'Apple Watch) de la personne. Pour utiliser les données sur un serveur, votre application les lit avec la permission de la personne et les envoie, par exemple sous forme d'Observations FHIR à Anpheros.

Ai-je besoin d'une clé API ou de payer pour l'API Apple Health ?

Pas de clé et pas de frais : HealthKit fait partie d'iOS. Vous avez besoin de la capacité HealthKit dans votre application, d'une description d'utilisation pour chaque type de données, et de la permission de la personne ; l'examen de l'App Store vérifie comment vous utilisez les données.

Comment savoir si la personne a refusé l'accès à un type HealthKit ?

Vous ne pouvez pas, pour l'accès en lecture : HealthKit le masque pour protéger la vie privée, et un type refusé ne renvoie aucune donnée. Traitez "aucune donnée" comme un état normal et proposez un moyen de consulter les autorisations dans l'application Health.

Pourquoi mes comptages de pas sont-ils plus élevés que dans l'application Health ?

Vous additionnez probablement des échantillons bruts provenant de plusieurs sources (iPhone et Watch). Utilisez HKStatisticsCollectionQuery avec .cumulativeSum, qui applique la propre déduplication d'Apple Health.

Quel code LOINC correspond à la variabilité de la fréquence cardiaque de l'Apple Watch ?

Apple Health stocke la HRV sous forme de SDNN, ce qui correspond au LOINC 80404-7. Health Connect stocke la RMSSD, une statistique différente, il ne faut donc pas mélanger les deux sous un seul code.

Liens connexes

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy