AnpherosAnpheros PlatformDevelopers

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

بيانات Apple Health (HealthKit) بصيغة FHIR

قراءة بيانات Apple Watch و Apple Health عبر HealthKit بلغة Swift، حسب اليوم المحلي، وكتابتها في سجل FHIR R4: الأذونات، المزامنة في الخلفية، وقواعد Apple.

توجد بيانات Apple Watch في Apple Health على جهاز iPhone المقترن، والطريقة الوحيدة لقراءتها هي HealthKit، من تطبيق على هذا الـ iPhone، بإذن الشخص. لوضعها في سجل FHIR، اقرأ الإحصائيات اليومية باستخدام HKStatisticsCollectionQuery، وأرسل القيم إلى الواجهة الخلفية الخاصة بك، واكتب كل مقياس كملاحظة (Observation) مع رمز LOINC ووحدة UCUM. تعرض هذه الصفحة كود Swift (تم التحقق من النوع مقابل iOS 17 SDK)، والأذونات والقواعد التي تضعها Apple، وكيف تصبح القيم ملاحظات FHIR R4.

ما هو موجود في Apple Health

تجمع Apple Health ما تقيسه iPhone و Apple Watch — معدل ضربات القلب، ومعدل ضربات القلب أثناء الراحة، وتقلب معدل ضربات القلب (SDNN)، والأكسجين في الدم، ومعدل التنفس، والخطوات، والطاقة، ومراحل النوم، وإشعارات عدم انتظام ضربات القلب، وتسجيلات ECG — وما تكتبه التطبيقات الأخرى: Garmin Connect، و Oura، و Withings Health Mate، والمقاييس الذكية، وأجهزة قياس ضغط الدم، وأجهزة قياس نسبة الجلوكوز. لذلك، فإن قراءة Apple Health تغطي أكثر من مجرد Apple Watch.

لا يوجد خادم HealthKit أو واجهة برمجة تطبيقات ويب. تبقى البيانات على الجهاز (وفي النسخة الاحتياطية المشفرة لـ iCloud الخاصة بالشخص)؛ يقرأها تطبيقك محليًا.

الأذونات

  1. قم بتشغيل إمكانية HealthKit في Xcode وأضف NSHealthShareUsageDescription إلى Info.plist (بالإضافة إلى NSHealthUpdateUsageDescription فقط إذا كنت تكتب).
  2. اطلب أنواع البيانات التي تحتاجها. يمكن للأشخاص السماح ببعضها ورفض البعض الآخر، ولا يخبر HealthKit تطبيقك ما إذا كان الوصول للقراءة قد تم رفضه: النوع المرفوض ببساطة لا يُرجع أي بيانات. صمم الشاشات لـ "عدم وجود بيانات" بدلاً من تصميمها لخطأ.
  3. اطلب في اللحظة التي يتصل فيها الشخص، مع جملة تشرح السبب، وليس عند التشغيل الأول.

قراءة القيم اليومية في 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
}

لماذا استعلامات الإحصائيات بدلاً من قراءة العينات: HKStatisticsCollectionQuery تُرجع الإجماليات والمتوسطات لكل يوم والتي قامت Apple Health بإلغاء تكرارها بالفعل عبر المصادر، لذلك لا تتم إضافة الخطوات التي تم حسابها بواسطة كل من iPhone و Watch مرتين. قراءة العينات الأولية وجمعها بنفسك هو المصدر الأكثر شيوعًا لزيادة عدد الخطوات.

الأيام هي أيام التقويم المحلية للشخص (Calendar.current). احتفظ بها على هذا النحو طوال الطريق إلى سجل FHIR، حيث يكون effectivePeriod في Observation هو ذلك اليوم المحلي مع إزاحة المنطقة الزمنية الخاصة به.

الحفاظ على تحديث السجل

من قيم Swift إلى ملاحظات FHIR

أرسل مصفوفة DailyValue إلى الواجهة الخلفية الخاصة بك واكتب ملاحظة (Observation) واحدة لكل شخص ومقياس ويوم بمعرف ثابت، وقم بتحديثها عندما يأتي نفس اليوم مرة أخرى. جدول الربط (نوع HealthKit → LOINC → UCUM)، مثال JSON تم التحقق منه، وشفرة TypeScript التي تقوم بعملية التحديث/الإدراج هذه، والتي تعمل على المنصة، موجودة في بيانات الأجهزة القابلة للارتداء في FHIR. الرموز للمقياسين هنا هي:

HealthKit LOINC UCUM القيمة لليوم الواحد
heartRate 8867-4 Heart rate /min متوسط، مع الحد الأدنى والأقصى كمكونات
stepCount 41950-7 Number of steps in 24 hour {steps} الإجمالي

قواعد Apple لبيانات الصحة

سجلات صحة Apple

بصرف النظر عن بيانات اللياقة البدنية، يمكن لـ Apple Health الاحتفاظ بالسجلات السريرية التي تم تنزيلها من أنظمة صحية مشاركة (معظمها في الولايات المتحدة)، ويكشف HealthKit عنها ككائنات HKClinicalRecord تحمل مورد FHIR الأصلي. تتطلب قراءتها إذنًا وحقًا خاصين بها. إنها تكامل مختلف عن بيانات الأجهزة القابلة للارتداء، ولا تقرأها Anpheros Daily حاليًا.

أين يتناسب Anpheros

يقوم Anpheros Platform بتخزين النتيجة: سجل FHIR R4 للشخص، مع كل قيمة من الأجهزة القابلة للارتداء كـ Observation تم تمييزها كبيانات جهاز، وموافقة للتطبيقات الأخرى، وبيانات المصدر، وسجل وصول. لا يقرأ Apple Health بنفسه - يحدث ذلك في تطبيق iOS الخاص بك. يقرأ تطبيق Anpheros الخاص، Anpheros Daily، Apple Health على iPhone (خطط Plus و Max) ويكتب ملخصات يومية إلى السجل باستخدام الرموز المذكورة أعلاه.

أسئلة متكررة

هل يمكنني قراءة بيانات Apple Watch من خادم؟

لا. تتم مزامنة بيانات Apple Watch مع Apple Health على جهاز iPhone المقترن، ولا يمكن استخدام HealthKit إلا بواسطة تطبيق على هذا الجهاز. يقرأ التطبيق البيانات ويرسلها إلى خادمك.

هل توجد واجهة برمجة تطبيقات ويب أو واجهة برمجة تطبيقات REST لـ Apple Health؟

لا. لا تقدم Apple واجهة برمجة تطبيقات ويب أو REST لـ Apple Health: يعمل HealthKit فقط داخل تطبيق على iPhone (أو Apple Watch) الخاص بالشخص. لاستخدام البيانات على خادم، يقرأها تطبيقك بإذن الشخص ويرسلها، على سبيل المثال كـ FHIR Observations إلى Anpheros.

هل أحتاج إلى مفتاح API أو الدفع مقابل واجهة برمجة تطبيقات Apple Health؟

لا يوجد مفتاح ولا رسوم: HealthKit هو جزء من iOS. تحتاج إلى إمكانية HealthKit في تطبيقك، ووصف استخدام لكل نوع بيانات، وإذن الشخص؛ يقوم مراجعة App Store بالتحقق من كيفية استخدامك للبيانات.

كيف أعرف إذا رفض الشخص الوصول إلى نوع HealthKit؟

لا يمكنك ذلك، بالنسبة لوصول القراءة: يخفي HealthKit ذلك لحماية الخصوصية، ويعيد النوع المرفوض عدم وجود بيانات. تعامل مع "عدم وجود بيانات" كحالة طبيعية وقدم طريقة لمراجعة الأذونات في تطبيق Health.

لماذا عدد خطواتي أعلى مما هو عليه في تطبيق Health؟

من المحتمل أنك تجمع عينات خام من عدة مصادر (iPhone و Watch). استخدم HKStatisticsCollectionQuery مع .cumulativeSum، والذي يطبق إزالة التكرار الخاصة بـ Apple Health.

ما هو رمز LOINC لمعدل ضربات القلب المتغيرة لساعة Apple Watch؟

يخزن Apple Health معدل ضربات القلب المتغيرة (HRV) كـ SDNN، والذي يتطابق مع LOINC 80404-7. يخزن Health Connect RMSSD، وهو إحصائية مختلفة، لذا لا تخلط بين الاثنين تحت رمز واحد.

ذات الصلة

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