Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Apple Health (HealthKit) a FHIR
Lee datos de Apple Watch y Apple Health con HealthKit en Swift, por día local, y escríbelos en un registro FHIR R4: permisos, sincronización en segundo plano, reglas de Apple.
Los datos de Apple Watch residen en Apple Health en el iPhone emparejado, y la única forma de leerlos es HealthKit, desde una aplicación en ese iPhone, con el permiso de la persona. Para introducirlos en un registro FHIR, lee estadísticas diarias con HKStatisticsCollectionQuery, envía los valores a tu backend y escribe cada métrica como una Observation con un código LOINC y una unidad UCUM. Esta página muestra el código Swift (verificado por tipo contra el SDK de iOS 17), los permisos y reglas que establece Apple, y cómo los valores se convierten en FHIR R4 Observations.
Qué hay en Apple Health
Apple Health recopila lo que miden el iPhone y el Apple Watch — frecuencia cardíaca, frecuencia cardíaca en reposo, variabilidad de la frecuencia cardíaca (SDNN), oxígeno en sangre, frecuencia respiratoria, pasos, energía, etapas del sueño, notificaciones de ritmo irregular, grabaciones de ECG — y lo que otras aplicaciones escriben: Garmin Connect, Oura, Withings Health Mate, básculas inteligentes, monitores de presión arterial, medidores de glucosa. Por lo tanto, leer Apple Health cubre más que solo el Apple Watch.
No existe un servidor HealthKit ni una API web. Los datos permanecen en el dispositivo (y en la copia de seguridad cifrada de iCloud de la persona); tu aplicación los lee localmente.
Permisos
- Activa la capacidad HealthKit en Xcode y añade
NSHealthShareUsageDescriptionaInfo.plist(másNSHealthUpdateUsageDescriptionsolo si escribes). - Solicita los tipos que necesitas. Las personas pueden permitir algunos y rechazar otros, y HealthKit no informa a tu aplicación si se denegó el acceso de lectura: un tipo denegado simplemente no devuelve datos. Diseña las pantallas para "sin datos" en lugar de para un error.
- Solicita en el momento en que la persona se conecte, con una frase que explique el motivo, no al primer lanzamiento.
Lectura de valores diarios 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
}
Por qué consultas de estadísticas en lugar de leer muestras: HKStatisticsCollectionQuery devuelve totales y promedios por día que Apple Health ya ha desduplicado entre fuentes, por lo que los pasos contados tanto por el iPhone como por el Watch no se suman dos veces. Leer muestras sin procesar y sumarlas usted mismo es la fuente más común de recuentos de pasos inflados.
Los días son los días calendario locales de la persona (Calendar.current). Mantenlos así hasta el registro FHIR, donde el effectivePeriod de la Observation es ese día local con su desplazamiento de zona horaria.
Mantener el registro actualizado
- Al abrir: lea los días transcurridos desde la última sincronización exitosa cada vez que la aplicación pasa a primer plano. Esta es la base confiable.
- En segundo plano:
HKObserverQueryconenableBackgroundDelivery(for:frequency:)activa su aplicación cuando llegan nuevos datos; necesita el entitlement de entrega en segundo plano de HealthKit, y iOS decide el momento exacto. - Primera conexión: importe un historial limitado (por ejemplo, 30 días) en lugar de años, y luego avance.
De valores de Swift a Observaciones FHIR
Envía el array DailyValue a tu backend y escribe una Observación por persona, métrica y día con un identificador estable, actualizándola cuando vuelva a llegar el mismo día. La tabla de mapeo (tipo HealthKit → LOINC → UCUM), un ejemplo JSON validado y el código TypeScript que realiza esta operación de inserción/actualización (upsert), ejecutado contra la plataforma, se encuentran en Datos de wearables en FHIR. Los códigos para las dos métricas aquí son:
| HealthKit | LOINC | UCUM | Valor por día |
|---|---|---|---|
heartRate |
8867-4 Heart rate | /min |
promedio, con mínimo y máximo como componentes |
stepCount |
41950-7 Number of steps in 24 hour | {steps} |
total |
Reglas de Apple para datos de salud
- Directriz de revisión de aplicaciones 5.1.3: los datos de salud no pueden usarse para publicidad o minería de datos, no pueden compartirse con terceros sin el consentimiento de la persona, y la información de salud personal no puede almacenarse en iCloud.
- Su política de privacidad debe indicar qué lee y por qué; Apple lo verifica.
- Los datos escritos por su aplicación en Apple Health se atribuyen a su aplicación; los datos que lee conservan su origen original (
HKSource), que debe incluir en el registro como el sistema de origen.
Registros de Salud de Apple
Por separado de los datos de fitness, Apple Health puede almacenar registros clínicos descargados de sistemas de salud participantes (principalmente en los Estados Unidos), y HealthKit los expone como objetos HKClinicalRecord que contienen el recurso FHIR original. Su lectura requiere su propio permiso y autorización. Son una integración diferente de los datos de wearables, y Anpheros Daily no los lee actualmente.
Dónde encaja Anpheros
La Plataforma Anpheros almacena el resultado: el registro FHIR R4 de la persona, con cada valor de dispositivo portátil como una Observación marcada como datos del dispositivo, consentimiento para otras aplicaciones, procedencia y un registro de acceso. No lee Apple Health directamente; eso ocurre en tu aplicación iOS. La propia aplicación de Anpheros, Anpheros Daily, lee Apple Health en iPhone (planes Plus y Max) y escribe resúmenes diarios en el registro con los códigos anteriores.
Preguntas frecuentes
¿Puedo leer datos de Apple Watch desde un servidor?
No. Los datos de Apple Watch se sincronizan con Apple Health en el iPhone emparejado, y HealthKit solo puede ser utilizado por una aplicación en ese dispositivo. La aplicación lee los datos y los envía a su servidor.
¿Existe una API web o REST de Apple Health?
No. Apple no ofrece una API web o REST para Apple Health: HealthKit se ejecuta solo dentro de una aplicación en el iPhone (o Apple Watch) de la persona. Para usar los datos en un servidor, su aplicación los lee con el permiso de la persona y los envía, por ejemplo, como Observaciones FHIR a Anpheros.
¿Necesito una clave de API o pagar por la API de Apple Health?
No se requiere clave ni tarifa: HealthKit es parte de iOS. Necesita la capacidad HealthKit en su aplicación, una descripción de uso para cada tipo de dato y el permiso de la persona; la revisión de la App Store verifica cómo utiliza los datos.
¿Cómo sé si la persona rechazó el acceso a un tipo de HealthKit?
No puede, para el acceso de lectura: HealthKit lo oculta para proteger la privacidad, y un tipo rechazado no devuelve ningún dato. Trate "sin datos" como un estado normal y ofrezca una forma de revisar los permisos en la aplicación Health.
¿Por qué mis recuentos de pasos son más altos que en la aplicación Health?
Probablemente esté sumando muestras brutas de varias fuentes (iPhone y Watch). Utilice HKStatisticsCollectionQuery con .cumulativeSum, que aplica la propia deduplicación de Apple Health.
¿Qué código LOINC corresponde a la variabilidad de la frecuencia cardíaca de Apple Watch?
Apple Health almacena la HRV como SDNN, que coincide con LOINC 80404-7. Health Connect almacena RMSSD, una estadística diferente, por lo que no mezcle las dos bajo un mismo código.
Relacionado
- Datos de wearables en FHIR: la tabla de mapeo y el código de backend
- Health Connect a FHIR: lo mismo en Android
- Cómo crear una aplicación de registro de salud personal
- Cómo crear una aplicación de atención médica con Flutter
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card