# Apple Health (HealthKit) do FHIR

> Čítajte dáta z Apple Watch a Apple Health pomocou HealthKit v Swifte, za lokálny deň, a zapisujte ich do FHIR R4 záznamu: povolenia, synchronizácia na pozadí, pravidlá Apple.

Source: https://developers.anpheros.com/sk/guides/apple-health-fhir

**Dáta z Apple Watch žijú v Apple Health na spárovanom iPhone a jediný spôsob, ako ich čítať, je HealthKit, z aplikácie na tomto iPhone, s povolením osoby.** Aby ste ich mohli vložiť do FHIR záznamu, prečítajte denné štatistiky pomocou `HKStatisticsCollectionQuery`, pošlite hodnoty na váš backend a zapíšte každú metriku ako Observation s LOINC kódom a UCUM jednotkou. Táto stránka ukazuje Swift kód (typovo kontrolovaný voči iOS 17 SDK), povolenia a pravidlá, ktoré Apple stanovuje, a ako sa hodnoty stávajú FHIR R4 Observations.

## Čo obsahuje Apple Health

Apple Health zbiera to, čo merajú iPhone a Apple Watch — srdcová frekvencia, pokojová srdcová frekvencia, variabilita srdcovej frekvencie (SDNN), kyslík v krvi, dychová frekvencia, kroky, energia, fázy spánku, upozornenia na nepravidelný rytmus, záznamy EKG — a to, čo zapisujú iné aplikácie: Garmin Connect, Oura, Withings Health Mate, inteligentné váhy, tlakomery, glukomery. Čítanie Apple Health teda pokrýva viac ako len Apple Watch.

Neexistuje žiadny server HealthKit ani webové API. Dáta zostávajú na zariadení (a v šifrovanej zálohe iCloud používateľa); vaša aplikácia ich číta lokálne.

## Povolenia

1. Zapnite funkciu **HealthKit** v Xcode a pridajte `NSHealthShareUsageDescription` do `Info.plist` (plus `NSHealthUpdateUsageDescription`, iba ak zapisujete).
2. Požiadajte o typy, ktoré potrebujete. Ľudia môžu povoliť niektoré a odmietnuť iné, pričom **HealthKit vašej aplikácii nepovie, či bol prístup na čítanie odmietnutý**: odmietnutý typ jednoducho nevráti žiadne údaje. Navrhnite obrazovky pre „žiadne údaje“ namiesto pre chybu.
3. Požiadajte v momente, keď sa osoba pripojí, s vysvetlením, prečo, nie pri prvom spustení.

## Čítanie denných hodnôt v Swift

```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
}
```

Prečo štatistické dotazy namiesto čítania vzoriek: `HKStatisticsCollectionQuery` vracia celkové denné súčty a priemery, ktoré Apple Health už de-duplikoval naprieč zdrojmi, takže kroky počítané iPhone aj Watch sa nepridajú dvakrát. Čítanie surových vzoriek a ich vlastné sčítanie je najčastejším zdrojom nafúknutého počtu krokov.

Dni sú lokálne kalendárne dni osoby (`Calendar.current`). Udržujte ich takto až po FHIR záznam, kde `effectivePeriod` v Observation je tento lokálny deň s jeho časovým posunom.

## Udržiavanie záznamu aktuálnym

- **Pri otvorení:** pri každom prechode aplikácie do popredia prečítajte počet dní od poslednej úspešnej synchronizácie. Toto je spoľahlivý základ.
- **Na pozadí:** `HKObserverQuery` s `enableBackgroundDelivery(for:frequency:)` zobudia vašu aplikáciu, keď prídu nové dáta; vyžaduje si to oprávnenie HealthKit background delivery a iOS rozhoduje o presnom načasovaní.
- **Prvé pripojenie:** importujte obmedzenú históriu (napríklad 30 dní) namiesto rokov, potom postupujte vpred.

## Z hodnôt Swift na FHIR Observations

Pošlite pole `DailyValue` na váš backend a zapíšte jedno Observation na osobu, metriku a deň so stabilným identifikátorom, pričom ho aktualizujte, keď ten istý deň príde znova. Mapovacia tabuľka (HealthKit type → LOINC → UCUM), validovaný JSON príklad a TypeScript kód, ktorý vykonáva tento upsert, spustený proti platforme, sú na [Wearable data in FHIR](https://developers.anpheros.com/sk/guides/wearable-data-fhir). Kódy pre dve metriky sú tu:

| HealthKit | LOINC | UCUM | Hodnota za deň |
|---|---|---|---|
| `heartRate` | 8867-4 Heart rate | `/min` | priemer, s minimom a maximom ako komponentmi |
| `stepCount` | 41950-7 Number of steps in 24 hour | `{steps}` | celkom |

## Pravidlá spoločnosti Apple pre zdravotné údaje

- Pokyn pre revíziu aplikácií 5.1.3: zdravotné údaje sa nesmú používať na reklamu ani na ťažbu údajov, nesmú sa zdieľať s tretími stranami bez súhlasu osoby a osobné zdravotné informácie sa nesmú ukladať v službe iCloud.
- Vaše zásady ochrany osobných údajov musia uvádzať, čo čítate a prečo; Apple to kontroluje.
- Údaje zapísané vašou aplikáciou do Apple Health sú pripísané vašej aplikácii; údaje, ktoré čítate, si zachovávajú svoj pôvodný zdroj (`HKSource`), ktorý by ste mali do záznamu preniesť ako zdrojový systém.

## Apple Health Records

Oddeľujúc od fitness dát, Apple Health môže uchovávať klinické záznamy stiahnuté z participujúcich zdravotníckych systémov (hlavne v Spojených štátoch) a HealthKit ich sprístupňuje ako `HKClinicalRecord` objekty, ktoré nesú pôvodný FHIR resource. Ich čítanie si vyžaduje vlastné povolenie a oprávnenie. Ide o inú integráciu ako dáta z nositeľných zariadení a Anpheros Daily ich dnes nečíta.

## Kde Anpheros zapadá

Platforma Anpheros ukladá výsledok: záznam FHIR R4 osoby, pričom každá hodnota zo zariadenia je zaznamenaná ako Observation označená ako dáta zo zariadenia, súhlas pre iné aplikácie, pôvod a denník prístupov. Sama o sebe nečíta Apple Health – to sa deje vo vašej iOS aplikácii. Vlastná aplikácia Anpheros, **Anpheros Daily**, číta Apple Health na iPhone (plány Plus a Max) a zapisuje denné súhrny do záznamu s vyššie uvedenými kódmi.

## Často kladené otázky

### Môžem čítať dáta z Apple Watch zo servera?
Nie. Dáta z Apple Watch sa synchronizujú s Apple Health na spárovanom iPhone a HealthKit môže použiť iba aplikácia na tomto zariadení. Aplikácia číta dáta a posiela ich na váš server.

### Existuje webové API alebo REST API pre Apple Health?
Nie. Apple neponúka žiadne webové ani REST API pre Apple Health: HealthKit beží iba v rámci aplikácie na iPhone (alebo Apple Watch) používateľa. Na použitie dát na serveri ich vaša aplikácia prečíta s povolením používateľa a odošle ich, napríklad ako FHIR Observations do Anpheros.

### Potrebujem API kľúč alebo platím za Apple Health API?
Žiadny kľúč a žiadny poplatok: HealthKit je súčasťou iOS. Potrebujete povolenie HealthKit vo vašej aplikácii, popis použitia pre každý typ dát a povolenie používateľa; recenzia v App Store kontroluje, ako dáta používate.

### Ako zistím, či používateľ odmietol prístup k typu HealthKit?
Pre prístup na čítanie to nemôžete zistiť: HealthKit to skrýva na ochranu súkromia a odmietnutý typ nevracia žiadne dáta. "Žiadne dáta" považujte za normálny stav a ponúknite možnosť skontrolovať povolenia v aplikácii Health.

### Prečo sú moje počty krokov vyššie ako v aplikácii Health?
Pravdepodobne sčítavate surové vzorky z viacerých zdrojov (iPhone a Watch). Použite `HKStatisticsCollectionQuery` s `.cumulativeSum`, ktoré aplikuje vlastnú deduplikáciu Apple Health.

### Ktorý LOINC kód zodpovedá variabilite srdcovej frekvencie Apple Watch?
Apple Health ukladá HRV ako SDNN, čo zodpovedá LOINC 80404-7. Health Connect ukladá RMSSD, čo je iná štatistika, takže tieto dve nekombinujte pod jedným kódom.

## Súvisiace

- [Údaje z nositeľných zariadení vo formáte FHIR](https://developers.anpheros.com/sk/guides/wearable-data-fhir): tabuľka mapovania a backendový kód
- [Health Connect do FHIR](https://developers.anpheros.com/sk/guides/health-connect-fhir): to isté na Androide
- [Ako vytvoriť aplikáciu osobného zdravotného záznamu](https://developers.anpheros.com/sk/guides/personal-health-record-app)
- [Ako vytvoriť zdravotnícku aplikáciu s Flutterom](https://developers.anpheros.com/guides/healthcare-app-flutter)
