{"id":"30b7a874-f83e-44e8-ba3b-cc132b59df64","shortId":"sr7kQb","kind":"skill","title":"Healthkit","tagline":"Swift Ios Skills skill by Dpearson2699","description":"# HealthKit\n\nRead and write health and fitness data from the Apple Health store. Covers authorization, queries, writing samples, background delivery, and workout sessions. Targets Swift 6.3 / iOS 26+.\n\n## Contents\n\n- [Setup and Availability](#setup-and-availability)\n- [Authorization](#authorization)\n- [Reading Data: Sample Queries](#reading-data-sample-queries)\n- [Reading Data: Statistics Queries](#reading-data-statistics-queries)\n- [Reading Data: Statistics Collection Queries](#reading-data-statistics-collection-queries)\n- [Writing Data](#writing-data)\n- [Background Delivery](#background-delivery)\n- [Workout Sessions](#workout-sessions)\n- [Common Data Types](#common-data-types)\n- [HKUnit Reference](#hkunit-reference)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Setup and Availability\n\n### Project Configuration\n\n1. Enable the HealthKit capability in Xcode (adds the entitlement)\n2. Add `NSHealthShareUsageDescription` (read) and `NSHealthUpdateUsageDescription` (write) to Info.plist\n3. For background delivery, enable the \"Background Delivery\" sub-capability\n\n### Availability Check\n\nAlways check availability before accessing HealthKit. iPad and some devices do not support it.\n\n```swift\nimport HealthKit\n\nlet healthStore = HKHealthStore()\n\nguard HKHealthStore.isHealthDataAvailable() else {\n    // HealthKit not available on this device (e.g., iPad)\n    return\n}\n```\n\nCreate a single `HKHealthStore` instance and reuse it throughout your app. It is thread-safe.\n\n## Authorization\n\nRequest only the types your app genuinely needs. App Review rejects apps that over-request.\n\n```swift\nfunc requestAuthorization() async throws {\n    let typesToShare: Set<HKSampleType> = [\n        HKQuantityType(.stepCount),\n        HKQuantityType(.activeEnergyBurned)\n    ]\n\n    let typesToRead: Set<HKObjectType> = [\n        HKQuantityType(.stepCount),\n        HKQuantityType(.heartRate),\n        HKQuantityType(.activeEnergyBurned),\n        HKCharacteristicType(.dateOfBirth)\n    ]\n\n    try await healthStore.requestAuthorization(\n        toShare: typesToShare,\n        read: typesToRead\n    )\n}\n```\n\n### Checking Authorization Status\n\nThe app can only determine if it has **not yet requested** authorization. If the user denied access, HealthKit returns empty results rather than an error -- this is a privacy design.\n\n```swift\nlet status = healthStore.authorizationStatus(\n    for: HKQuantityType(.stepCount)\n)\n\nswitch status {\ncase .notDetermined:\n    // Haven't requested yet -- safe to call requestAuthorization\n    break\ncase .sharingAuthorized:\n    // User granted write access\n    break\ncase .sharingDenied:\n    // User denied write access (read denial is indistinguishable from \"no data\")\n    break\n@unknown default:\n    break\n}\n```\n\n## Reading Data: Sample Queries\n\nUse `HKSampleQueryDescriptor` (async/await) for one-shot reads. Prefer descriptors over the older callback-based `HKSampleQuery`.\n\n```swift\nfunc fetchRecentHeartRates() async throws -> [HKQuantitySample] {\n    let heartRateType = HKQuantityType(.heartRate)\n\n    let descriptor = HKSampleQueryDescriptor(\n        predicates: [.quantitySample(type: heartRateType)],\n        sortDescriptors: [SortDescriptor(\\.endDate, order: .reverse)],\n        limit: 20\n    )\n\n    let results = try await descriptor.result(for: healthStore)\n    return results\n}\n\n// Extracting values from samples:\nfor sample in results {\n    let bpm = sample.quantity.doubleValue(\n        for: HKUnit.count().unitDivided(by: .minute())\n    )\n    print(\"\\(bpm) bpm at \\(sample.endDate)\")\n}\n```\n\n## Reading Data: Statistics Queries\n\nUse `HKStatisticsQueryDescriptor` for aggregated single-value stats (sum, average, min, max).\n\n```swift\nfunc fetchTodayStepCount() async throws -> Double? {\n    let calendar = Calendar.current\n    let startOfDay = calendar.startOfDay(for: Date())\n    let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)!\n\n    let predicate = HKQuery.predicateForSamples(\n        withStart: startOfDay, end: endOfDay\n    )\n    let stepType = HKQuantityType(.stepCount)\n    let samplePredicate = HKSamplePredicate.quantitySample(\n        type: stepType, predicate: predicate\n    )\n\n    let query = HKStatisticsQueryDescriptor(\n        predicate: samplePredicate,\n        options: .cumulativeSum\n    )\n\n    let result = try await query.result(for: healthStore)\n    return result?.sumQuantity()?.doubleValue(for: .count())\n}\n```\n\n**Options by data type:**\n- Cumulative types (steps, calories): `.cumulativeSum`\n- Discrete types (heart rate, weight): `.discreteAverage`, `.discreteMin`, `.discreteMax`\n\n## Reading Data: Statistics Collection Queries\n\nUse `HKStatisticsCollectionQueryDescriptor` for time-series data grouped into intervals -- ideal for charts.\n\n```swift\nfunc fetchDailySteps(forLast days: Int) async throws -> [(date: Date, steps: Double)] {\n    let calendar = Calendar.current\n    let endDate = calendar.startOfDay(\n        for: calendar.date(byAdding: .day, value: 1, to: Date())!\n    )\n    let startDate = calendar.date(byAdding: .day, value: -days, to: endDate)!\n\n    let predicate = HKQuery.predicateForSamples(\n        withStart: startDate, end: endDate\n    )\n    let stepType = HKQuantityType(.stepCount)\n    let samplePredicate = HKSamplePredicate.quantitySample(\n        type: stepType, predicate: predicate\n    )\n\n    let query = HKStatisticsCollectionQueryDescriptor(\n        predicate: samplePredicate,\n        options: .cumulativeSum,\n        anchorDate: endDate,\n        intervalComponents: DateComponents(day: 1)\n    )\n\n    let collection = try await query.result(for: healthStore)\n    var dailySteps: [(date: Date, steps: Double)] = []\n\n    collection.statisticsCollection.enumerateStatistics(\n        from: startDate, to: endDate\n    ) { statistics, _ in\n        let steps = statistics.sumQuantity()?\n            .doubleValue(for: .count()) ?? 0\n        dailySteps.append((date: statistics.startDate, steps: steps))\n    }\n\n    return dailySteps\n}\n```\n\n### Long-Running Collection Query\n\nUse `results(for:)` (plural) to get an `AsyncSequence` that emits updates as new data arrives:\n\n```swift\nlet updateStream = query.results(for: healthStore)\n\nTask {\n    for try await result in updateStream {\n        // result.statisticsCollection contains updated data\n    }\n}\n```\n\n## Writing Data\n\nCreate `HKQuantitySample` objects and save them to the store.\n\n```swift\nfunc saveSteps(count: Double, start: Date, end: Date) async throws {\n    let stepType = HKQuantityType(.stepCount)\n    let quantity = HKQuantity(unit: .count(), doubleValue: count)\n\n    let sample = HKQuantitySample(\n        type: stepType,\n        quantity: quantity,\n        start: start,\n        end: end\n    )\n\n    try await healthStore.save(sample)\n}\n\n```\n\nYour app can only delete samples it created. Samples from other apps or Apple Watch are read-only.\n\n## Background Delivery\n\nRegister for background updates so your app is launched when new data arrives. Requires the background delivery entitlement.\n\n```swift\nfunc enableStepCountBackgroundDelivery() async throws {\n    let stepType = HKQuantityType(.stepCount)\n\n    try await healthStore.enableBackgroundDelivery(\n        for: stepType,\n        frequency: .hourly\n    )\n}\n```\n\n**Pair with an `HKObserverQuery`** to handle notifications. Always call the completion handler:\n\n```swift\nlet observerQuery = HKObserverQuery(\n    sampleType: HKQuantityType(.stepCount),\n    predicate: nil\n) { query, completionHandler, error in\n    defer { completionHandler() }  // Must call to signal done\n    guard error == nil else { return }\n    // Fetch new data, update UI, etc.\n}\nhealthStore.execute(observerQuery)\n```\n\n**Frequencies:** `.immediate`, `.hourly`, `.daily`, `.weekly`\n\nCall `enableBackgroundDelivery` once (e.g., at app launch). The system persists the registration.\n\n## Workout Sessions\n\nUse `HKWorkoutSession` and `HKLiveWorkoutBuilder` to track live workouts. Available on watchOS 2+ and iOS 17+.\n\n```swift\nfunc startWorkout() async throws {\n    let configuration = HKWorkoutConfiguration()\n    configuration.activityType = .running\n    configuration.locationType = .outdoor\n\n    let session = try HKWorkoutSession(\n        healthStore: healthStore,\n        configuration: configuration\n    )\n    session.delegate = self\n\n    let builder = session.associatedWorkoutBuilder()\n    builder.dataSource = HKLiveWorkoutDataSource(\n        healthStore: healthStore,\n        workoutConfiguration: configuration\n    )\n\n    session.startActivity(with: Date())\n    try await builder.beginCollection(at: Date())\n}\n\nfunc endWorkout(\n    session: HKWorkoutSession,\n    builder: HKLiveWorkoutBuilder\n) async throws {\n    session.end()\n    try await builder.endCollection(at: Date())\n    try await builder.finishWorkout()\n}\n```\n\nFor full workout lifecycle management including pause/resume, delegate handling, and multi-device mirroring, see [references/healthkit-patterns.md](references/healthkit-patterns.md).\n\n## Common Data Types\n\n### HKQuantityTypeIdentifier\n\n| Identifier | Category | Unit |\n|---|---|---|\n| `.stepCount` | Fitness | `.count()` |\n| `.distanceWalkingRunning` | Fitness | `.meter()` |\n| `.activeEnergyBurned` | Fitness | `.kilocalorie()` |\n| `.basalEnergyBurned` | Fitness | `.kilocalorie()` |\n| `.heartRate` | Vitals | `.count()/.minute()` |\n| `.restingHeartRate` | Vitals | `.count()/.minute()` |\n| `.oxygenSaturation` | Vitals | `.percent()` |\n| `.bodyMass` | Body | `.gramUnit(with: .kilo)` |\n| `.bodyMassIndex` | Body | `.count()` |\n| `.height` | Body | `.meter()` |\n| `.bodyFatPercentage` | Body | `.percent()` |\n| `.bloodGlucose` | Lab | `.gramUnit(with: .milli).unitDivided(by: .literUnit(with: .deci))` |\n\n### HKCategoryTypeIdentifier\n\nCommon category types: `.sleepAnalysis`, `.mindfulSession`, `.appleStandHour`\n\n### HKCharacteristicType\n\nRead-only user characteristics: `.dateOfBirth`, `.biologicalSex`, `.bloodType`, `.fitzpatrickSkinType`\n\n## HKUnit Reference\n\n```swift\n// Basic units\nHKUnit.count()                              // Steps, counts\nHKUnit.meter()                              // Distance\nHKUnit.mile()                               // Distance (imperial)\nHKUnit.kilocalorie()                        // Energy\nHKUnit.joule(with: .kilo)                   // Energy (SI)\nHKUnit.gramUnit(with: .kilo)                // Mass (kg)\nHKUnit.pound()                              // Mass (imperial)\nHKUnit.percent()                            // Percentage\n\n// Compound units\nHKUnit.count().unitDivided(by: .minute())   // Heart rate (bpm)\nHKUnit.meter().unitDivided(by: .second())   // Speed (m/s)\n\n// Prefixed units\nHKUnit.gramUnit(with: .milli)               // Milligrams\nHKUnit.literUnit(with: .deci)               // Deciliters\n```\n\n## Common Mistakes\n\n### 1. Over-requesting data types\n\nDON'T -- request everything:\n```swift\n// App Review will reject this\nlet allTypes: Set<HKObjectType> = [\n    HKQuantityType(.stepCount),\n    HKQuantityType(.heartRate),\n    HKQuantityType(.bloodGlucose),\n    HKQuantityType(.bodyMass),\n    HKQuantityType(.oxygenSaturation),\n    // ...20 more types the app never uses\n]\n```\n\nDO -- request only what you use:\n```swift\nlet neededTypes: Set<HKObjectType> = [\n    HKQuantityType(.stepCount),\n    HKQuantityType(.activeEnergyBurned)\n]\n```\n\n### 2. Not handling authorization denial\n\nDON'T -- assume data will be returned:\n```swift\nfunc getSteps() async throws -> Double {\n    let result = try await query.result(for: healthStore)\n    return result!.sumQuantity()!.doubleValue(for: .count()) // Crashes if denied\n}\n```\n\nDO -- handle nil gracefully:\n```swift\nfunc getSteps() async throws -> Double {\n    let result = try await query.result(for: healthStore)\n    return result?.sumQuantity()?.doubleValue(for: .count()) ?? 0\n}\n```\n\n### 3. Assuming HealthKit is always available\n\nDON'T -- skip the check:\n```swift\nlet store = HKHealthStore() // Crashes on iPad\ntry await store.requestAuthorization(toShare: types, read: types)\n```\n\nDO -- guard availability:\n```swift\nguard HKHealthStore.isHealthDataAvailable() else {\n    showUnsupportedDeviceMessage()\n    return\n}\n```\n\n### 4. Running heavy queries on the main thread\n\nDON'T -- use old callback-based queries on main thread. DO -- use async descriptors:\n```swift\n// Bad: HKSampleQuery with callback on main thread\n// Good: async descriptor\nfunc loadAllData() async throws -> [HKQuantitySample] {\n    let descriptor = HKSampleQueryDescriptor(\n        predicates: [.quantitySample(type: stepType)],\n        sortDescriptors: [SortDescriptor(\\.endDate, order: .reverse)],\n        limit: 100\n    )\n    return try await descriptor.result(for: healthStore)\n}\n```\n\n### 5. Forgetting to call completionHandler in observer queries\n\nDON'T -- skip the completion handler:\n```swift\nlet query = HKObserverQuery(sampleType: type, predicate: nil) { _, handler, _ in\n    processNewData()\n    // Forgot to call handler() -- system won't schedule next delivery\n}\n```\n\nDO -- always call it:\n```swift\nlet query = HKObserverQuery(sampleType: type, predicate: nil) { _, handler, _ in\n    defer { handler() }\n    processNewData()\n}\n```\n\n### 6. Using wrong statistics options for the data type\n\nDON'T -- use cumulative sum on discrete types:\n```swift\n// Heart rate is discrete, not cumulative -- this returns nil\nlet query = HKStatisticsQueryDescriptor(\n    predicate: heartRatePredicate,\n    options: .cumulativeSum\n)\n```\n\nDO -- match options to data type:\n```swift\n// Use discrete options for discrete types\nlet query = HKStatisticsQueryDescriptor(\n    predicate: heartRatePredicate,\n    options: .discreteAverage\n)\n```\n\n## Review Checklist\n\n- [ ] `HKHealthStore.isHealthDataAvailable()` checked before any HealthKit access\n- [ ] Only necessary data types requested in authorization\n- [ ] `Info.plist` includes `NSHealthShareUsageDescription` and/or `NSHealthUpdateUsageDescription`\n- [ ] HealthKit capability enabled in Xcode project\n- [ ] Authorization denial handled gracefully (nil results, not crashes)\n- [ ] Single `HKHealthStore` instance reused (not created per query)\n- [ ] Async query descriptors used instead of callback-based queries\n- [ ] Heavy queries not blocking main thread\n- [ ] Statistics options match data type (cumulative vs. discrete)\n- [ ] Background delivery paired with `HKObserverQuery` and `completionHandler` called\n- [ ] Background delivery entitlement enabled if using `enableBackgroundDelivery`\n- [ ] Workout sessions properly ended and builder finalized\n- [ ] Write operations only for sample types the app created\n\n## References\n\n- Extended patterns (workouts, anchored queries, SwiftUI integration): [references/healthkit-patterns.md](references/healthkit-patterns.md)\n- [HealthKit framework](https://sosumi.ai/documentation/healthkit)\n- [HKHealthStore](https://sosumi.ai/documentation/healthkit/hkhealthstore)\n- [HKSampleQueryDescriptor](https://sosumi.ai/documentation/healthkit/hksamplequerydescriptor)\n- [HKStatisticsQueryDescriptor](https://sosumi.ai/documentation/healthkit/hkstatisticsquerydescriptor)\n- [HKStatisticsCollectionQueryDescriptor](https://sosumi.ai/documentation/healthkit/hkstatisticscollectionquerydescriptor)\n- [HKWorkoutSession](https://sosumi.ai/documentation/healthkit/hkworkoutsession)\n- [HKLiveWorkoutBuilder](https://sosumi.ai/documentation/healthkit/hkliveworkoutbuilder)\n- [Setting up HealthKit](https://sosumi.ai/documentation/healthkit/setting-up-healthkit)\n- [Authorizing access to health data](https://sosumi.ai/documentation/healthkit/authorizing-access-to-health-data)","tags":["healthkit","swift","ios","skills","dpearson2699"],"capabilities":["skill","source-dpearson2699","category-swift-ios-skills"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/healthkit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under dpearson2699/swift-ios-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T05:40:40.182Z","embedding":null,"createdAt":"2026-04-18T20:34:15.139Z","updatedAt":"2026-04-22T05:40:40.182Z","lastSeenAt":"2026-04-22T05:40:40.182Z","tsv":"'/.minute':924,928 '/documentation/healthkit)':1448 '/documentation/healthkit/authorizing-access-to-health-data)':1486 '/documentation/healthkit/hkhealthstore)':1452 '/documentation/healthkit/hkliveworkoutbuilder)':1472 '/documentation/healthkit/hksamplequerydescriptor)':1456 '/documentation/healthkit/hkstatisticscollectionquerydescriptor)':1464 '/documentation/healthkit/hkstatisticsquerydescriptor)':1460 '/documentation/healthkit/hkworkoutsession)':1468 '/documentation/healthkit/setting-up-healthkit)':1478 '0':602,1137 '1':119,434,533,575,1030 '100':1224 '17':828 '2':129,825,1080 '20':367,1059 '26':35 '3':138,1138 '4':1172 '5':1231 '6':1283 '6.3':33 'access':155,265,304,311,1344,1480 'activeenergyburn':227,236,915,1079 'add':126,130 'aggreg':405 'alltyp':1047 'alway':151,757,1142,1267 'anchor':1438 'anchord':570 'and/or':1355 'app':193,205,208,211,250,696,706,722,805,1041,1063,1432 'appl':18,708 'applestandhour':962 'arriv':629,728 'assum':1087,1139 'async':219,347,417,516,667,737,832,874,1095,1121,1193,1204,1208,1379 'async/await':329 'asyncsequ':622 'author':22,44,45,199,247,260,1083,1351,1363,1479 'avail':39,43,116,149,153,176,822,1143,1165 'averag':411 'await':240,371,465,579,639,692,744,864,878,883,1101,1127,1157,1227 'background':26,80,83,140,144,714,718,731,1403,1411 'background-deliveri':82 'bad':1196 'basalenergyburn':918 'base':342,1186,1387 'basic':976 'biologicalsex':970 'block':1392 'bloodglucos':946,1054 'bloodtyp':971 'bodi':933,938,941,944 'bodyfatpercentag':943 'bodymass':932,1056 'bodymassindex':937 'bpm':386,394,395,1011 'break':298,305,319,322 'builder':852,872,1423 'builder.begincollection':865 'builder.datasource':854 'builder.endcollection':879 'builder.finishworkout':884 'byad':431,530,539 'calendar':421,523 'calendar.current':422,524 'calendar.date':430,529,538 'calendar.startofday':425,527 'call':296,758,778,800,1234,1258,1268,1410 'callback':341,1185,1199,1386 'callback-bas':340,1184,1385 'calori':482 'capabl':123,148,1358 'case':288,299,306 'categori':907,958 'category-swift-ios-skills' 'characterist':968 'chart':509 'check':150,152,246,1148,1340 'checklist':108,111,1338 'collect':67,73,495,577,613 'collection.statisticscollection.enumeratestatistics':589 'common':90,94,102,105,902,957,1028 'common-data-typ':93 'common-mistak':104 'complet':760,1243 'completionhandl':772,776,1235,1409 'compound':1003 'configur':118,835,847,848,859 'configuration.activitytype':837 'configuration.locationtype':839 'contain':644 'content':36 'count':474,601,661,677,679,911,923,927,939,980,1110,1136 'cover':21 'crash':1111,1153,1370 'creat':183,649,702,1376,1433 'cumul':479,1295,1306,1400 'cumulativesum':461,483,569,1316 'daili':798 'dailystep':584,609 'dailysteps.append':603 'data':15,47,52,56,61,65,71,76,79,91,95,318,324,399,477,493,503,628,646,648,727,789,903,1034,1088,1290,1321,1347,1398,1483 'date':427,518,519,535,585,586,604,664,666,862,867,881 'datecompon':573 'dateofbirth':238,969 'day':432,514,531,540,542,574 'deci':955,1026 'decilit':1027 'default':321 'defer':775,1280 'deleg':892 'delet':699 'deliveri':27,81,84,141,145,715,732,1265,1404,1412 'deni':264,309,1113 'denial':313,1084,1364 'descriptor':336,355,1194,1205,1212,1381 'descriptor.result':372,1228 'design':278 'determin':253 'devic':160,179,897 'discret':484,1298,1304,1325,1328,1402 'discreteaverag':489,1336 'discretemax':491 'discretemin':490 'distanc':982,984 'distancewalkingrun':912 'done':781 'doubl':419,521,588,662,1097,1123 'doublevalu':472,599,678,1108,1134 'dpearson2699':7 'e.g':180,803 'els':173,785,1169 'emit':624 'empti':268 'enabl':120,142,1359,1414 'enablebackgrounddeliveri':801,1417 'enablestepcountbackgrounddeliveri':736 'end':442,550,665,689,690,1421 'enddat':363,526,544,551,571,593,1220 'endofday':429,443 'endworkout':869 'energi':987,991 'entitl':128,733,1413 'error':273,773,783 'etc':792 'everyth':1039 'extend':1435 'extract':377 'fetch':787 'fetchdailystep':512 'fetchrecentheartr':346 'fetchtodaystepcount':416 'final':1424 'fit':14,910,913,916,919 'fitzpatrickskintyp':972 'forget':1232 'forgot':1256 'forlast':513 'framework':1445 'frequenc':748,795 'full':886 'func':217,345,415,511,659,735,830,868,1093,1119,1206 'genuin':206 'get':620 'getstep':1094,1120 'good':1203 'grace':1117,1366 'gramunit':934,948 'grant':302 'group':504 'guard':171,782,1164,1167 'handl':755,893,1082,1115,1365 'handler':761,1244,1253,1259,1278,1281 'haven':290 'health':12,19,1482 'healthkit':1,8,122,156,167,174,266,1140,1343,1357,1444,1475 'healthstor':169,374,468,582,635,845,846,856,857,1104,1130,1230 'healthstore.authorizationstatus':282 'healthstore.enablebackgrounddelivery':745 'healthstore.execute':793 'healthstore.requestauthorization':241 'healthstore.save':693 'heart':486,1009,1301 'heartrat':234,353,921,1052 'heartratepred':1314,1334 'heartratetyp':351,360 'heavi':1174,1389 'height':940 'hkcategorytypeidentifi':956 'hkcharacteristictyp':237,963 'hkhealthstor':170,186,1152,1372,1449 'hkhealthstore.ishealthdataavailable':172,1168,1339 'hkliveworkoutbuild':817,873,1469 'hkliveworkoutdatasourc':855 'hkobserverqueri':753,765,1248,1273,1407 'hkquantiti':675 'hkquantitysampl':349,650,682,1210 'hkquantitytyp':224,226,231,233,235,284,352,446,554,671,741,767,1049,1051,1053,1055,1057,1076,1078 'hkquantitytypeidentifi':905 'hkquery.predicateforsamples':439,547 'hksamplepredicate.quantitysample':450,558 'hksamplequeri':343,1197 'hksamplequerydescriptor':328,356,1213,1453 'hkstatisticscollectionquerydescriptor':498,565,1461 'hkstatisticsquerydescriptor':403,457,1312,1332,1457 'hkunit':97,100,973 'hkunit-refer':99 'hkunit.count':389,978,1005 'hkunit.gramunit':993,1020 'hkunit.joule':988 'hkunit.kilocalorie':986 'hkunit.literunit':1024 'hkunit.meter':981,1012 'hkunit.mile':983 'hkunit.percent':1001 'hkunit.pound':998 'hkworkoutconfigur':836 'hkworkoutsess':815,844,871,1465 'hour':749,797 'ideal':507 'identifi':906 'immedi':796 'imperi':985,1000 'import':166 'includ':890,1353 'indistinguish':315 'info.plist':137,1352 'instanc':187,1373 'instead':1383 'int':515 'integr':1441 'interv':506 'intervalcompon':572 'io':3,34,827 'ipad':157,181,1155 'kg':997 'kilo':936,990,995 'kilocalori':917,920 'lab':947 'launch':724,806 'let':168,221,228,280,350,354,368,385,420,423,428,437,444,448,455,462,522,525,536,545,552,556,563,576,596,631,669,673,680,739,763,834,841,851,1046,1073,1098,1124,1150,1211,1246,1271,1310,1330 'lifecycl':888 'limit':366,1223 'literunit':953 'live':820 'loadalldata':1207 'long':611 'long-run':610 'm/s':1017 'main':1178,1189,1201,1393 'manag':889 'mass':996,999 'match':1318,1397 'max':413 'meter':914,942 'milli':950,1022 'milligram':1023 'min':412 'mindfulsess':961 'minut':392,1008 'mirror':898 'mistak':103,106,1029 'multi':896 'multi-devic':895 'must':777 'necessari':1346 'need':207 'neededtyp':1074 'never':1064 'new':627,726,788 'next':1264 'nil':770,784,1116,1252,1277,1309,1367 'notdetermin':289 'notif':756 'nshealthshareusagedescript':131,1354 'nshealthupdateusagedescript':134,1356 'object':651 'observ':1237 'observerqueri':764,794 'old':1183 'older':339 'one':332 'one-shot':331 'oper':1426 'option':460,475,568,1287,1315,1319,1326,1335,1396 'order':364,1221 'outdoor':840 'over-request':213,1031 'oxygensatur':929,1058 'pair':750,1405 'pattern':1436 'pause/resume':891 'per':1377 'percent':931,945 'percentag':1002 'persist':809 'plural':618 'predic':357,438,453,454,458,546,561,562,566,769,1214,1251,1276,1313,1333 'prefer':335 'prefix':1018 'print':393 'privaci':277 'processnewdata':1255,1282 'project':117,1362 'proper':1420 'quantiti':674,685,686 'quantitysampl':358,1215 'queri':23,49,54,58,63,68,74,326,401,456,496,564,614,771,1175,1187,1238,1247,1272,1311,1331,1378,1380,1388,1390,1439 'query.result':466,580,1102,1128 'query.results':633 'rate':487,1010,1302 'rather':270 'read':9,46,51,55,60,64,70,132,244,312,323,334,398,492,712,965,1161 'read-on':711,964 'reading-data-sample-queri':50 'reading-data-statistics-collection-queri':69 'reading-data-statistics-queri':59 'refer':98,101,112,113,974,1434 'references/healthkit-patterns.md':900,901,1442,1443 'regist':716 'registr':811 'reject':210,1044 'request':200,215,259,292,1033,1038,1067,1349 'requestauthor':218,297 'requir':729 'restingheartr':925 'result':269,369,376,384,463,470,616,640,1099,1106,1125,1132,1368 'result.statisticscollection':643 'return':182,267,375,469,608,786,1091,1105,1131,1171,1225,1308 'reus':189,1374 'revers':365,1222 'review':107,110,209,1042,1337 'review-checklist':109 'run':612,838,1173 'safe':198,294 'sampl':25,48,53,325,380,382,681,694,700,703,1429 'sample.enddate':397 'sample.quantity.doublevalue':387 'samplepred':449,459,557,567 'sampletyp':766,1249,1274 'save':653 'savestep':660 'schedul':1263 'second':1015 'see':899 'self':850 'seri':502 'session':30,86,89,813,842,870,1419 'session.associatedworkoutbuilder':853 'session.delegate':849 'session.end':876 'session.startactivity':860 'set':223,230,1048,1075,1473 'setup':37,41,114 'setup-and-avail':40 'sharingauthor':300 'sharingdeni':307 'shot':333 'showunsupporteddevicemessag':1170 'si':992 'signal':780 'singl':185,407,1371 'single-valu':406 'skill':4,5 'skip':1146,1241 'sleepanalysi':960 'sortdescriptor':361,362,1218,1219 'sosumi.ai':1447,1451,1455,1459,1463,1467,1471,1477,1485 'sosumi.ai/documentation/healthkit)':1446 'sosumi.ai/documentation/healthkit/authorizing-access-to-health-data)':1484 'sosumi.ai/documentation/healthkit/hkhealthstore)':1450 'sosumi.ai/documentation/healthkit/hkliveworkoutbuilder)':1470 'sosumi.ai/documentation/healthkit/hksamplequerydescriptor)':1454 'sosumi.ai/documentation/healthkit/hkstatisticscollectionquerydescriptor)':1462 'sosumi.ai/documentation/healthkit/hkstatisticsquerydescriptor)':1458 'sosumi.ai/documentation/healthkit/hkworkoutsession)':1466 'sosumi.ai/documentation/healthkit/setting-up-healthkit)':1476 'source-dpearson2699' 'speed':1016 'start':663,687,688 'startdat':537,549,591 'startofday':424,436,441 'startworkout':831 'stat':409 'statist':57,62,66,72,400,494,594,1286,1395 'statistics.startdate':605 'statistics.sumquantity':598 'status':248,281,287 'step':481,520,587,597,606,607,979 'stepcount':225,232,285,447,555,672,742,768,909,1050,1077 'steptyp':445,452,553,560,670,684,740,747,1217 'store':20,657,1151 'store.requestauthorization':1158 'sub':147 'sub-cap':146 'sum':410,1296 'sumquant':471,1107,1133 'support':163 'swift':2,32,165,216,279,344,414,510,630,658,734,762,829,975,1040,1072,1092,1118,1149,1166,1195,1245,1270,1300,1323 'swiftui':1440 'switch':286 'system':808,1260 'target':31 'task':636 'thread':197,1179,1190,1202,1394 'thread-saf':196 'throughout':191 'throw':220,348,418,517,668,738,833,875,1096,1122,1209 'time':501 'time-seri':500 'toshar':242,1159 'track':819 'tri':239,370,464,578,638,691,743,843,863,877,882,1100,1126,1156,1226 'type':92,96,203,359,451,478,480,485,559,683,904,959,1035,1061,1160,1162,1216,1250,1275,1291,1299,1322,1329,1348,1399,1430 'typestoread':229,245 'typestoshar':222,243 'ui':791 'unit':676,908,977,1004,1019 'unitdivid':390,951,1006,1013 'unknown':320 'updat':625,645,719,790 'updatestream':632,642 'use':327,402,497,615,814,1065,1071,1182,1192,1284,1294,1324,1382,1416 'user':263,301,308,967 'valu':378,408,433,532,541 'var':583 'vital':922,926,930 'vs':1401 'watch':709 'watcho':824 'week':799 'weight':488 'withstart':440,548 'won':1261 'workout':29,85,88,812,821,887,1418,1437 'workout-sess':87 'workoutconfigur':858 'write':11,24,75,78,135,303,310,647,1425 'writing-data':77 'wrong':1285 'xcode':125,1361 'yet':258,293","prices":[{"id":"c35652fe-d349-4073-9c6f-d56f9938eb03","listingId":"30b7a874-f83e-44e8-ba3b-cc132b59df64","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:15.139Z"}],"sources":[{"listingId":"30b7a874-f83e-44e8-ba3b-cc132b59df64","source":"github","sourceId":"dpearson2699/swift-ios-skills/healthkit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/healthkit","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:00.994Z","lastSeenAt":"2026-04-22T00:53:43.190Z"},{"listingId":"30b7a874-f83e-44e8-ba3b-cc132b59df64","source":"skills_sh","sourceId":"dpearson2699/swift-ios-skills/healthkit","sourceUrl":"https://skills.sh/dpearson2699/swift-ios-skills/healthkit","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:15.139Z","lastSeenAt":"2026-04-22T05:40:40.182Z"}],"details":{"listingId":"30b7a874-f83e-44e8-ba3b-cc132b59df64","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"healthkit","source":"skills_sh","category":"swift-ios-skills","skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/healthkit"},"updatedAt":"2026-04-22T05:40:40.182Z"}}