讓我為你開啟 HealthKit 的大門
從入門到到八門盾甲全開(才怪)的手把手帶你進入 HealthKit 的世界!

從入門到八門盾甲全開(才怪)的手把手帶你進入 HealthKit 的世界!
現在大家越來越注重健康,除了透過課程以及自我學習並依靠自制力來運動或是控制飲食,也有另一種選擇就是讓你的 iPhone、Apple Watch 或是其他智慧穿戴裝置來輔助紀錄甚至是提醒你達成目的。
像是紀錄經期、每餐的飲食吃下了多少熱量、每日飲水料夠不夠、咖啡因會不會攝取過多?都有各式各樣的 App 可以達成。
這就是我們今天的主題 HealthKit!
最近剛在有在工作接觸到,並且也在公司的技術分享會上面介紹,想說不然也分享給各位朋友們一起學習討論,那就讓我們進入今天的主題吧。
Table of Content
⏺ 什麼是 HealthKit ?
⏺ 一切都從最基礎的設定開始
⏺ Data Types
⏺ 寫入資料
⏺ 讀取資料
⏺ 資料篩選
什麼是 HealthKit ?
HealthKit 是 Apple 為用戶健康數據建立的中央儲存庫的框架,可以在多個設備與健康交互。HealthKit 會自己安全的保護以及同步資料,開發人員無需處理。
其實就是負責管理所有你在 Apple 支援的設備中的健康資料的框架。

先看一眼怎麼用,用個簡單的範例讓你有個 fu?從檢查可否使用到要求權限,並且讀取資料。

一切都從最基礎的設定開始
首先點選你的專案檔並且選擇好 Target 然後到 Signing & Capabilities
中將 HealthKit 加入。
點選畫面中的 + Capabilities
就會看到如右圖中的畫面,有各式各樣的功能可以添加,我們選擇 HealthKit 即可。


另外跟大家簡單介紹一下,左圖有個 Clinical Health Record 是什麼功能?簡單的來說就是可以跟支持的醫療機構去接入他們的電子病歷,讓你的健康 App 可以匯集各個角落的健康數據,使用的是 FHIR(Fast Healthcare Interoperability Resources)
這個國際醫療資料交換標準。
醫療機構要申請的話詳細 Healthcare 有更多說明。
但是!目前截至 2024/4/1 只有美國、英國、加拿大這三個國家有開放使用這個功能,可以到這裡去查看目前支援的國家以及所有支持的機構。

我們在拉回來,只要在設定完這個就可以開始進入撰寫程式的部分了,就是我們的 Info.plist
,基本上我們所會使用到的讀取與寫入就是要添加這兩個,並且添加文字說明,在要求權限時要顯示給用戶看的,這個也是必需添加的哦!就看你是否兩個權限都需要。
- Privacy — Health Share Usage Description
- Privacy — Health Update Usage Description

Data Types
來到了本文章的重點環節,也是比較囉嗦複雜一點點🤏的章節,大家聽我娓娓道來。
首先我們來看幾個健康種類:
- 步數
- 動態能量(卡路里)
- 睡眠
- 月經
- 性別
- 血型
但其實這些都能歸類成常用的三大類型:
- 數值類型(HKQuantityType):步數、動態能量(卡路里)
- 類別類型(HKCategoryType):睡眠、月經
- 特徵類型(HKCharacteristicType):性別、血型
如果能看的出它們之間的差異性,那恭喜你後面的內容對你來說應該都很容易懂。不能?那也沒關係很正常,我會慢慢的解釋給你聽。
只有特徵類別是直接繼承 HKObject,其他類別都是繼承 HKSample,由此可發現 HKCharacteristic 是比較特別的,我們先這樣記住就好。

這些類別都有共同的地方,分別是 Type(類別)、Value(值)、Time(時間)、Metadata(元資料)。
- Type 是健康類型,例如步數、睡眠、卡路里⋯⋯等等各式各樣的種類。
- Value 是你所要儲存的值,以下圖為例可以是距離
628
公尺、音量的101
分貝、甚至是腹部絞痛程度的輕微
,有數值也有非數值。 - Time 是紀錄這個樣本(Sample)的啟迄時間。
- Metadata 紀錄額外資訊,例如
是否為用戶手動輸入
。
Sample 在這裡是專有名詞,用來表示要儲存或讀取出來的物件。

HKCharacteristicType 特徵類型
Apple HealthKit 中的一種資料類型。它表示不隨時間變化的資料類別,例如生日、血型、姓別等等。
詳細請參閱 HKCharacteristicType、HKCharacteristicTypeIdentifier。
在健康 App 中都是在這個頁面設置。



HKQuantityType 數值類型
會隨時間積累數值的類別,最常使用的資料類別,例如走路步數、動態能量(燃燒卡路里量)、爬樓梯層數、心率。
詳細請參閱 HKQuantityType、HKQuantityTypeIdentifier。


HKCategoryType 類別類型
它用於讀取離散的資料。例如睡眠分析的資料會有床上
、清醒
、核心睡眠
等等的詳細的分析不同階段的睡眠時間。
使用 value
來儲存枚舉資料,而數值主要是時間並且要自己從 startDate
跟 endDate
去計算。
詳細請參閱 HKCategoryType、HKCategoryTypeIdentifier。


寫入資料
HKQuantitySample
我們先以 HKQuantityType 的資料為例,要注意的是會需要指定資料的單位(HKUnit),舉例以走路距離(distanceWalkingRunning)
的文件來說需要使用長度的數據單位。
HKQuantitySample 就是你用來寫入或讀取需要建立的物件,對應 HKQuantityType,其他類型也是如此。
詳細請參閱 HKQuantitySample。

use length units
我們對應健康 App 的畫面來看,如前面提到每個建康資料都共同點都有 Type、Time、Value、Metadata(非必要,所以這裡沒有)。

接下來我們把上面的轉換成程式碼也是一模一樣,準備好要寫入的 Type、Value、Time、Medatada(非必填),然後在準備 HKQuantitySample 這個物件來將這些資訊組合在一起就可以進行寫入了!
寫入的資料就長如右圖那樣。


HKCategorySample
這個資料類型要儲存的值必須符合該資料類別的枚舉(enum)。
以睡眠分析 sleepAnalysis 來說是用這個枚舉 HKCategoryValueSleepAnalysis,裡面會有幾種,一樣打開健康 App 我們也可以很直觀的看到。
- 床上(inBed)
- 清醒(awake)
- 核心睡眠(asleepCore)

跟前面都一模一樣,差異就在 Value 不是用數值而使使用該類別對應的列表資料(enum),如上圖所示那樣,還有一個差別就在儲存的物件當然也要對應改成 HKCategorySsample。


讀取資料
在這邊只介紹兩個簡單的取資料的方式,一個是直接存取另一個是需要使用查詢為什麼會有這兩種類別呢?其實很簡單,我們仔細回想一下有個類型是特徵類別,這種類型的資料是出生之後就永遠不會改變了,例如生日、血型等等,所以直接存取它就好了!
HKCharacteristicSample 這類型的資料無法寫入,只能由用戶在健康 App 裡面去設定。

另一種需要建立查詢(Query)的又是什麼呢,例如我們要存取步數資料,我們可以決定要讀取那個時間範圍、決定步數是以天還是以月統計等等,有學過 SQL 的同學一定能很快理解。
並且我們建立好查詢後需要去執行它,如下圖中的 store.execute(query)
才是真正的去讀資料。
這裡我們注意一下 5 ~ 7 行,我們建立了一個 predicate 可以把它想像成一個篩選器(非必要),這裡篩選的就是某個時間範圍。

資料篩選
大家注意囉,這裡其實也是蠻重要的一個環節,因為健康數據是允許用戶在手機上直接手動輸入資料的,所以你的 App 如果會運用這些資料去給予各種形式的獎勵就要排除手動輸入的資料,這樣才能避免作弊的可能性產生。
排除手動輸入的原理是利用 Metadata,它是用來記錄額外資訊,如圖中手動輸入有些健康類別的資料也會利用這個去紀錄其他資訊,你的 App 也能自訂你需要的資料,使用 Dicitonary 存儲 [String: Any]。
HealthKit 有提供預設好的可以參考 Metadata Keys。

篩選手動輸入
我們只要選擇下面兩個其中一個方式就可以進行篩選了,然後把它加入前面有提到的 predicate(一種篩選器)就完成了。


但細心的你可能會發現,為什麼不能這樣寫 HKMetadataKeyWasUserEntered == NO
?因為若不是手動輸入就不會有使用者自行手動輸入
這個 Metadata 的資料。

篩選裝置來源
排除手動輸入後其實還有一個問題,那就是 Metadata 也是可以用 App 寫入資料的,所以還需要有個能夠保證不是人為輸入的資料,那就是由不同裝置(這裡使用 Apple Watch)自動建立的資料,會有裝置詳細資訊如下圖,方式也是一樣我們要建立 predicate 並且跟前面的方法一樣,就能過濾出要的資料了。


如果喜歡我的這篇文章的話可以在下面幫我點個讚支持我,我會繼續分享更多內容給大家閱讀。
