根據新聞報導,健康與健美在今時今日的重要程度比已往任何時候都高。說起來有點可笑,似乎就在幾天之前,筆者就見到過類似的新聞。或許,這是當人逐漸變老之後揮之不去的感覺吧——渴望保持健康以及健美的感覺。不管怎麼說,健康與健美是一個重要話題。技術的進步,尤其是移動應用與硬體世界的不斷提高,正為這個似乎日益成長的話題帶來全新的契機。
healthkit 是蘋果公司推出的一款移動應用平台,旨在為重要、可追蹤的健康資料與注重健康、熱衷鍛煉的科技消費者搭起橋梁。這很酷。使用者可以輕松地追蹤一段時間内可測量的健身與健康資料。除了了解自身的健康資料,看到圖表中喜人的增長曲線也的确鼓舞人心。
作為開發者,我們需要征求許可才能從/向 healthkit 讀取/寫入資料。實際上,我們需要明确地聲明打算讀取或改變的資料。此外,任何使用 healthkit 的應用都必須包含隐私政策,這樣一來,使用者才能對其資訊的處理感到更加放心。
在本文中,我們将打造一個有趣的小應用,它會從 healthkit 讀取資料,也會向其寫入新資料。來見一見 onehourwalker 吧。

onehourwalker 是一款追蹤使用者在一個小時内行走或跑步之距離的健身應用。使用者可以将距離與 healthkit 分享,之後就能在健康應用中讀取之。我知道,一個小時聽起來有點過于樂觀了(至少筆者本人可能無法堅持下去)。是以,使用者也可以提早中止計數,并分享距離。
額,到目前為止,似乎 onehourwalker 隻會向 healthkit 寫入資料。我們需要讀取什麼資料呢?
好問題!在步行鍛煉時,我喜歡選擇鄉間或林間小路。常常,我會遇到樹枝低垂的區域。而我是一條身高 193cm 的漢子,這真的讓我很苦惱。解決辦法是:從 healthkit 讀取使用者的身高資料,将之列印為應用的一個标簽。這個标簽可以作為對使用者的善意提醒,這樣,他們就能避免在步行時被樹枝打到。
首先,在我們的應用中啟用 healthkit。在項目導航中,點選 onehourwalker,之後點選 targets 下面的 onehourwalker,之後選擇螢幕頂部的 capabilities 選項。
檢視 capabilities 清單的底部,啟用 <code>healthkit</code>。這一簡單的操作會将 healthkit 權限添加到 app id,将 healthkit 鍵添加到 info plist 檔案,将 healthkit 權限添加到授權檔案,并且與 <code>healthkit.framework</code> 相連接配接。就是這麼簡單。
接下來,跳轉到 <code>timerviewcontroller.swift</code>,開始将 healthkit 引入 onehourwalker。首先,建立一個 healthkitmanager 執行個體。
所有 healthkit 工作都會在 <code>healthkitmanager.swift</code> 中進行。它會包含重要的方法,我們很快就會談到。
正如在前文介紹部分所述,我們需要取得使用者的許可,才能讀取并修改他們的健康資料。在 <code>viewdidload()</code>中,我們就得這麼做。
<code>gethealthkitpermission()</code> 方法會調用 manager 的 <code>authorizehealthkit()</code>方法。如果一切順利,我們便能調用<code>setheight()</code>方法。不過,我們很快會在後文中談到此方法。
在 healthkitmanager.swift 中,我們會建立 authorizehealthkit() 方法。然而,除此之外,我們需要建立 healthkit 存儲,用于連接配接應用與 healthkit 的資料。
在請求擷取使用者健康資料的授權時,我們需要明确指定打算讀取以及修改的資訊。對本例而言,我們需要讀取使用者的身高,進而幫助他們躲避有危險的低垂枝丫。我們希望 healthkit 能提供一個可以轉化為可了解的身高的 hkobject 量。此外,我們還要獲得修改 hkobject 量的許可,以記錄使用者的行走及跑步距離。
在處理好 onehourwalker 與 ipad 通信的可能性後,我們做出官方請求。
在 <code>healthkitmanager.swift</code> 中,建立從 healthkit 讀取使用者身高資料的 <code>getheight()</code> 方法。
查詢身高資料的第一步是建立一個斷言以定義時間參數。我們是在請求一段時間内的所有身高資料——與目前日期相距甚遠的一個過去的日期。顯然,這會傳回一個數組。然而,我們隻想要最近期的身高,是以,我們請求資料時可以讓最新的資料排在數組的最前頭。
在建構這一查詢時,我們會把數組的長度限制為1。在考慮好出現錯誤的可能性後,我們會将結果中的首個也即唯一一個數組項目配置設定給 lastheight。接下來,完善 getheight() 方法。最後,針對使用者的健康資料執行查詢。
回到 <code>timerviewcontroller.swift</code>,在 app 真正投入使用之前,假設使用者授權了适當的許可,則 <code>setheight()</code> 方法會被 <code>gethealthkitpermission()</code> 調用。
首先,我們需要為 hkquantitysample 執行個體聲明一個身高變量。
在 <code>share()</code> 方法之上,我們會建立 <code>setheight()</code> 方法。我們請求的身高資料樣本以 <code>hkquantity</code> 傳回,辨別符 <code>hkquantitytypeidentifierheight</code> 知道這一對象。
接下來,調用在 manager 中建立的 <code>getheight()</code> 方法。有了身高樣本,我們還需要将之翻譯為恰當的字元串以展示在标簽中。與往常一樣,考慮所有可能的錯誤情況是很重要的。
到此,使用者就可以打開 app,檢視他們的身高(如果他的健康應用中記錄着身高資料),開啟計時器,追蹤他跑步或行走的距離了。接下來,我們要處理将距離資料寫入健康應用的過程,這樣,使用者才能在同一個應用中儲存其所有的健身資料。
在使用者結束外出鍛煉之後,不管有沒有到60分鐘,他可能會使用 share(分享)按鈕将其辛苦賺得的運動距離發送到健康應用。是以,在 share() 方法中,我們需要調用 <code>healthkitmanager.swift</code> 的 <code>savedistance()</code> 方法來實作這一過程。在這個方法中,我們會發送運動距離以及取得該距離的日期。這樣,使用者便能在第二天争取更好的成績。
接下來,回到 manager,我們要在此處建立 <code>savedistance()</code> 方法。首先,我們要讓 healthkit 知道我們打算寫入一個代表步行及跑步距離的量。之後,将度量機關設定為英裡,并指派官方的樣本量。healthkit 的 <code>saveobject()</code> 方法會将此資料寫入使用者的健康資料。
跳轉到健康應用,所記錄的資料會出現在 walking + running distance(行走+跑步距離)一行(如果已經啟用)。此外,依照下面的路徑,我們可以看到詳細的樣本資料:health data tab(健康資料頁籤) > fitness(健身) > walking + running distance(行走+跑步距離) > show all data(顯示所有資料)。我們的資料就在此清單中。輕擊一個單元,我們的圖示(目前還未設定)就會與距離一同出現。再次點選此單元,就能看到完整的細節資料。
借助 onehourwalker,我們便能為全世界 ios 使用者的身體健康貢獻一份力量。然而,這隻是一個開始。在使用 healthkit 讀取并修改健康資料的道路上,還有非常多的可能性。
當然,對使用者而言,擁有這些可追蹤資料的好處很多。人們可以輕松地按照日期、星期進行比較,進而激勵自己朝着目标努力。不過,真正的偉大之處在于,開發者可以提供全新的,富有創造力的有趣方法來擷取資料。