譯文:使用Swift通過HealthKit框架進行睡眠分析

Using Sleep Analysis in HealthKit With Swift

使用Swift通過HealthKit框架進行睡眠分析

作者:ANUSHK MITTAL,原文鏈接,原文日期:2016-06-18

Today, Sleep Revolution is a fad and users are curious than ever to not only know about the the time they’ve been asleep but also to analyze the data gathered over a period to reveal their sleeping trends. Advancements in technology including hardwares, and mobiles in particular have brought this seemingly ever-growing subject into a whole new light.

目前脑融,睡眠革命成為一種狂潮,人們比以往更加關注,不僅要知道他們睡眠的時間庸毫,還要分析一段時間內收集的數(shù)據(jù)以觀察睡眠趨勢冠跷。隨著科技特別是硬件和手機的不斷發(fā)展,人們看到了新的曙光厨诸。

Apple provides a cool way to communicate with user’s personal health information in a secure manner and store the information securely through the built-in Health app. Not only can you use HealthKit to build a fitness app
, the framework also allows you access sleep analysis data.

蘋果提供了一種很炫酷的方式來讓用戶個人健康信息在安全的方式下傳遞镶殷,并且通過內置的Health應用安全的存儲信息。你不僅可以使用HealthKit創(chuàng)建一個健康應用微酬,也使用框架訪問睡眠分析數(shù)據(jù)绘趋。

In this tutorial, I will give you a quick introduction to the HealthKit framework, and demonstrate how you can build a simple app for sleep analysis.

在這篇指南,我會讓你對HealthKit框架進行一個快速的入門颗管,并且演示如何創(chuàng)建一個睡眠分析的簡單應用陷遮。

Introduction

介紹

The HealthKit framework provides a structure to save data in an encrypted database called the HealthKit store. You can access this database using the HKHealthStore class. Both iPhone and Apple Watch have their own HealthKit store. Health data is synced between Apple Watch and iPhone; however, old data is periodically purged from Apple Watch to save space. HealthKit and the Health app are unavailable on iPad.

HealthKit框架提供了一種結構來存儲數(shù)據(jù)到被稱為HealthKit store的加密數(shù)據(jù)庫。你可以使用HKHealthStore類來訪問這個數(shù)據(jù)庫垦江。iPhone和Apple Watch都有他們各自的HealthKit store帽馋。健康數(shù)據(jù)在Apple Watch和iPhone之間進行同步;然而比吭,舊的數(shù)據(jù)會被定期清理以節(jié)省空間绽族。HealthKit和Health應用均不支持iPad。

HealthKit is a powerful tool if you want to create an iOS or watchOS app based on health data. It is designed to manage data from a wide range of sources, automatically merging the data from different sources based on user’s preferences. Apps can also access the raw data for each source, and merge the data themselves. Not only for body measurements, fitness or nutrition, the data can also be used for sleep analysis.

如果你想開發(fā)一款基于健康數(shù)據(jù)的iOS或watchOS應用梗逮,那么HealthKit無疑是一個強有力的工具项秉。HealthKit被設計用于管理大范圍的數(shù)據(jù)來源,并根據(jù)用戶設定自動合并處理慷彤。應用也可以訪問每一個來源的raw數(shù)據(jù)娄蔼,并且自己合并數(shù)據(jù)怖喻。這些數(shù)據(jù)不僅用于身體測量、健康或營養(yǎng)岁诉,還可以被用來做睡眠分析锚沸。

For the rest of the article, I will show you how to make use of the HealthKit framework for saving and accessing sleep analysis data on iOS. The same methods are applicable for watchOS applications as well. Please note that the tutorial is written using Swift 2.0 and Xcode 7. So make sure you use Xcode 7 (or up) to follow the tutorial.

文章的剩下部分,我將向你展示如何利用HealthKit框架來保存和訪問iOS上的睡眠數(shù)據(jù)涕癣。在watchOS上可以用相同的方法哗蜈。請注意這篇指南是基于Swift 2.0和Xcode 7寫作的。所以請您遵守指南使用Xcode7(或以上)版本坠韩。

Before moving on, download the starter project and unzip it. I have already created the user interface with basic functionalities for you. When you run the starter project, you will see a timer UI that shows the time elapsed after you push the start button.

在開始之前距潘,下載上手項目并解壓。我已經(jīng)為你創(chuàng)建了基本功能的用戶界面只搁。當你運行上手項目音比,你按下按鈕后將會看到按下按鈕之后經(jīng)過時間的計數(shù)器界面。

Working with the HealthKit Framework

使用HealthKit框架

Our aim with the application is to save sleep analysis information and retrieve the data using the Start & Stop buttons. To use HealthKit, you must begin by granting the HealthKit capabilities to your app bundle. In your app project, navigate to your current target -> capabilities and turn on HealthKit.

我們應用的目標是使用StartStop按鈕保存睡眠分析信息和獲取數(shù)據(jù)氢惋。你必須在應用bundle中打開允許獲取HealthKit的權限方可使用HealthKit洞翩。在你的應用項目,選擇當前的target -> capabilities并且打開HealthKit焰望。

Next, you will need to create an instance of HKHealthStore in the ViewController class using the following code:

接下來骚亿,你需要使用下面的代碼在ViewController中創(chuàng)建一個HKHealthStore實例:

let healthStore = HKHealthStore()

Later we will use the HKHealthStore instance to access the HealthKit store.

然后我們使用HKHealthStore實例訪問HealthKit store。

As mentioned, HealthKit grants users control over their health data. So you have to first request users’ permission before you can gain access (write/read) to the Sleep Analysis data of the user. To do so, first import the built-in HealthKit framework and update the viewDidLoad method like this:

需要提及一點的是HealthKit收集健康數(shù)據(jù)是根據(jù)用戶的設置熊赖。所以你必須在你第一次獲取讀寫睡眠分析數(shù)據(jù)的時候請求用戶權限来屠。要做到這點,首先導入內置的HealthKit框架秫舌,并且按如下更新viewDidLoad方法:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let typestoRead = Set([
        HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis)!
        ])
    
    let typestoShare = Set([
        HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis)!
        ])
    
    self.healthStore.requestAuthorizationToShareTypes(typestoShare, readTypes: typestoRead) { (success, error) -> Void in
        if success == false {
            NSLog(" Display not allowed")
        }
    }
}

This code will prompt the user to allow or deny the requested permissions. With the completion block, you can handle success or error and get the final result. It is not necessary that the user grants your app all the requested permissions. You must handle the errors gracefully in your app.

這段代碼可以提示用戶允許或者拒絕權限請求的妖。通過completion block绣檬,你可以處理success或者error信息并且得到最后的結果足陨。并不需要用戶獲得所有的請求權限。你必須在應用優(yōu)雅的處理錯誤信息娇未。

But for testing purpose, you must have to select the “Allow” option to grant the app permission to access the health data on your device.

但是對于測試目的墨缘,你必須選擇“Allow”選項來授權應用獲取你設備上健康數(shù)據(jù)的訪問權限。

Writing Sleep Analysis Data

存儲睡眠分析數(shù)據(jù)

First, how can we retrieve the sleep analysis data? According to Apple’s documentation, each sleep analysis sample can have only one value. To represent the user being both in bed and asleep, HealthKit uses two or more samples with overlapping times. By comparing the start and end times of these samples, apps can calculate a number of secondary statistics:

首先零抬,我們如何獲取睡眠分析數(shù)據(jù)镊讼?根據(jù)蘋果的文檔,每一個睡眠分析樣本只有1個值平夜。為了展示用戶躺在床上和睡眠的時間蝶棋,HealthKit使用2個或更多的重疊時間。通過比較開始和結束的樣本忽妒,應用可以計算出大量的次級統(tǒng)計數(shù)據(jù):

  • the amount of time it takes for the user to fall asleep(用戶睡著的時間)
  • the percentage of time in bed that the user actually sleeps(用戶在床上真正睡眠時間所占的比例)
  • the number of times the user wakes up while still in bed(用戶躺在床上醒來的次數(shù))
  • the total amount of time spent both in bed and asleep(躺在床上和睡眠的總時間)

In brief, you follow the below approach to save sleep analysis data to the HealthKit store:

簡而言之玩裙,你可以遵循下面方式來保存睡眠分析數(shù)據(jù)到HealthKit sotore

  1. We need to define two NSDate objects corresponding to the start time and the end time.(我們需要定義兩個跨越開始時間和結束時間的NSDate對象)
  2. We then create an instance of HKObjectType using HKCategoryTypeIdentifierSleepAnalysis.(下來我們使用HKCategoryTypeIdentifierSleepAnalysis來創(chuàng)建HKObjectType實例)
  3. We need to create a new object of the HKCategorySample type. You normally use category samples to record sleep data. Individual samples represent time periods when the user is in bed or asleep. So we will create both an in-bed sample and an asleep sample with overlapping times.( 我們需要創(chuàng)建一個HKCategorySample類型兼贸。你通常需要使用category samples記錄睡眠數(shù)據(jù)。用戶可以個性化的展示躺在床上或者睡眠的時間段吃溅。所以我們將要創(chuàng)建躺在床上和睡眠的重疊時間溶诞。)
  4. Finally, we’ll save the object using saveObject of HKHealthStore.(最后我們需要使用HKHealthStoresaveObject來保存對象)

Editor’s note: For the type of the sample, you can look it up in HealthKit Constants Reference.

編者注: 對于樣本的類型, 你可以在HealthKit Constants Reference里面查詢.

If you translate the above into Swift, here is the code snippet to save sleep analysis data for both in bed and asleep values. Please insert the method in the ViewController class:

如果你將上面所述轉換為Swift,這段代碼可以保存在床上和睡眠的分析數(shù)據(jù)决侈。請?zhí)砑釉摲椒ǖ?code>ViewController類:

func saveSleepAnalysis() {
    
    // alarmTime and endTime are NSDate objects
    // alarmTime和endTime是NSDate對象
    if let sleepType = HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis) {
        
        // we create our new object we want to push in Health app
        //我們創(chuàng)建新對象push到Health應用
        let object = HKCategorySample(type:sleepType, value: HKCategoryValueSleepAnalysis.InBed.rawValue, startDate: self.alarmTime, endDate: self.endTime)
        
        // at the end, we save it
        //在最后螺垢,我們保存它
        healthStore.saveObject(object, withCompletion: { (success, error) -> Void in
            
            if error != nil {
                // something happened
                return
            }
            
            if success {
                print("My new data was saved in HealthKit")
                
            } else {
                // something happened again
            }
            
        })
        
        
        let object2 = HKCategorySample(type:sleepType, value: HKCategoryValueSleepAnalysis.Asleep.rawValue, startDate: self.alarmTime, endDate: self.endTime)
        
        healthStore.saveObject(object2, withCompletion: { (success, error) -> Void in
            if error != nil {
                // something happened
                return
            }
            
            if success {
                print("My new data (2) was saved in HealthKit")
            } else {
                // something happened again
            }
            
        })
        
    }
    
}

This function can be called at the time we want to save the Sleep Analysis data to HealthKit.

每當我們想要保存睡眠分析數(shù)據(jù)到HealthKit的時候都可以調用。

Reading Sleep Analysis Data

讀取睡眠分析數(shù)據(jù)

To read the sleep analysis data, we will need to create a query. You should begin by defining the HKObjectType category to HKCategoryTypeIdentifierSleepAnalysis. You may also want to use a predicate to filter the retrieved data using startDate and endDate which are NSDate objects corresponding to the time range that you may want to retrieve. You will also need to create a sortDescriptor for sorting the retrieved queries to select the desired result.

為了獲取睡眠分析數(shù)據(jù)赖歌,我們需要創(chuàng)建一個查詢(query)枉圃。你應該通過定義HKCategoryTypeIdentifierSleepAnalysis的類目HKObjectType。你可能也需要使用predicete來過濾獲取的數(shù)據(jù)庐冯,使用startDateendDateNSDate對象檢索你可能需要的時間范圍讯蒲。你可能也需要創(chuàng)建一個sortDescriptos來對獲取的查詢進行排序以得到想要的結果。

Your code for retrieving sleep analysis data should look like this:

你獲取睡眠合理數(shù)據(jù)的代碼可能如下:

func retrieveSleepAnalysis() {
    // first, we define the object type we want
    // 首先肄扎,我們定義我們想要的對象
    if let sleepType = HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis) {
        
        // Use a sortDescriptor to get the recent data first
        // 首先使用一個sortDescriptos獲取最近的數(shù)據(jù)
        let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
        
        // we create our query with a block completion to execute
        //我們創(chuàng)建一個blcok來查詢
        let query = HKSampleQuery(sampleType: sleepType, predicate: nil, limit: 30, sortDescriptors: [sortDescriptor]) { (query, tmpResult, error) -> Void in
            
            if error != nil {
                
                // something happened
                // 某些情況
                return
                
            }
            
            if let result = tmpResult {
                
                // do something with my data
                //對數(shù)據(jù)做一些處理
                for item in result {
                    if let sample = item as? HKCategorySample {
                        let value = (sample.value == HKCategoryValueSleepAnalysis.InBed.rawValue) ? "InBed" : "Asleep"
                        print("Healthkit sleep: \(sample.startDate) \(sample.endDate) - value: \(value)")
                    }
                }
            }
        }
        
        // finally, we execute our query
        healthStore.executeQuery(query)
    }

This code queries the HealthKit to get all Sleep Analysis data and then sorts it down to descending order. Then each query is printed with the startDate and endDate along with the type of value i.e. In Bed or Asleep. I have set the limit to 30 to retrieve the last 30 recorded samples. You can also use the predicate method to choose your custom start and end dates.

這段代碼通過HealthKit獲得全部睡眠分析數(shù)據(jù)墨林,然后做降序。接下來對每一個查詢按照在床上或者睡眠的開始和結束日期打印值犯祠。我設置限制最多30條以獲取最近的30條數(shù)據(jù)旭等。你也可以使用predicate方法來自定義開始和結束日期。

App Testing

App 測試

For the demo application, I have used an NSTimer to show the time elapsed since you push the start button. The NSDate objects are created on the start and end buttons to save sleep analysis data as the elapsed time. In the stop action method, you can invoke the saveSleepAnalysis() and retrieveSleepAnalysis() methods to save and get the sleep data.

對于Demo應用衡载,我已經(jīng)用一個NSTimer來展示自從你按下開始按鈕所經(jīng)過的時間搔耕。NSDate對象在按下開始按鈕的創(chuàng)建,在按結束按鈕的時候保存睡眠分析數(shù)據(jù)痰娱。在stop方法中弃榨,你可以調用saveSleepAnalysis()retrieveSleepAnalysis()方法來保存和獲取睡眠數(shù)據(jù)。

@IBAction func stop(sender: AnyObject) {
    endTime = NSDate()
    saveSleepAnalysis()
    retrieveSleepAnalysis()
    timer.invalidate()
}

In your apps, you may want to change the NSDate objects to choose relevant start and end times (probably different) for saving the in bed and asleep values.

在你的應用中梨睁,你可能想要想要NSDate對象來選擇有意義的開始和結束的時間段(可能不同)來存儲躺在床上和睡眠的值鲸睛。

Once you’ve made the changes, you can run the demo app and start the timer. Let it run for a few minutes and then tap the Stop button. After that, open the Health app. You’ll find the sleep data in there.

一旦你做出改變,你可以運行demo應用并開啟計時器坡贺。讓它跑幾分鐘官辈,然后按下stop按鈕。接下來打開Health應用遍坟,你將會在里面找到睡眠數(shù)據(jù)拳亿。

Some Advices for HealthKit Apps

對HealthKit 應用的一些建議

HealthKit is designed to provide a common platform for app developers to share and access user’s data easily and avoids any possible duplication or inconsistency in data. Apple review guidelines are very specific for apps using the HealthKit and requesting read/write permissions without a clear demonstration of their use might result in the app being rejected.

HealthKit被設計為公共平臺讓應用開發(fā)者更方便分享和訪問避免可能的重復和不一致的數(shù)據(jù)。蘋果審核指南中對于使用HealthKit和請求讀寫權限愿伴,但是沒有一個明確的聲明可能會被拒絕肺魁。

Apps that save fake or incorrect data to the Health App would also be rejected. This means, that you cannot be na?ve with your algorithms for calculating different health values like sleep analysis in this tutorial. You should try using the inbuilt sensor data for reading and manipulating any parameters to avoid calculating false data.

應用保存無效或者錯誤的數(shù)據(jù)到Health App也可能會被拒絕。這就意味著隔节,你不能像指南中的睡眠數(shù)據(jù)一樣用你的算法計算不同的健康值鹅经。你應該嘗試去讀和操作內置的傳感器數(shù)據(jù)胡桨,以避免錯誤的數(shù)據(jù)。

For the complete Xcode project, you can get it here.

對于完整的Xcode項目瞬雹,你可以在這里獲取昧谊。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酗捌,隨后出現(xiàn)的幾起案子呢诬,更是在濱河造成了極大的恐慌,老刑警劉巖胖缤,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尚镰,死亡現(xiàn)場離奇詭異,居然都是意外死亡哪廓,警方通過查閱死者的電腦和手機狗唉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涡真,“玉大人分俯,你說我怎么就攤上這事《吡希” “怎么了缸剪?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長东亦。 經(jīng)常有香客問我杏节,道長,這世上最難降的妖魔是什么典阵? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任奋渔,我火速辦了婚禮,結果婚禮上壮啊,老公的妹妹穿的比我還像新娘嫉鲸。我一直安慰自己,他們只是感情好他巨,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布充坑。 她就那樣靜靜地躺著,像睡著了一般染突。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辈灼,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天份企,我揣著相機與錄音,去河邊找鬼巡莹。 笑死司志,一個胖子當著我的面吹牛甜紫,可吹牛的內容都是我干的。 我是一名探鬼主播骂远,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼囚霸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了激才?” 一聲冷哼從身側響起拓型,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瘸恼,沒想到半個月后劣挫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡东帅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年压固,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片靠闭。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡帐我,死狀恐怖,靈堂內的尸體忽然破棺而出愧膀,到底是詐尸還是另有隱情焚刚,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布扇调,位于F島的核電站矿咕,受9級特大地震影響,放射性物質發(fā)生泄漏狼钮。R本人自食惡果不足惜碳柱,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熬芜。 院中可真熱鬧莲镣,春花似錦、人聲如沸涎拉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼓拧。三九已至半火,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間季俩,已是汗流浹背钮糖。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酌住,地道東北人店归。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓阎抒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親消痛。 傳聞我的和親對象是個殘疾皇子且叁,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,471評論 5 6
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,491評論 0 23
  • 在一座深山的南坡頂上,有一塊大石頭秩伞。 石頭左邊的枯草堆里住著一窩刺猬——刺猬爸爸逞带,刺猬媽媽,還有一只刺猬寶寶稠歉。 石...
    繭破閱讀 482評論 0 3
  • 十點左右掰担,做幾組深刻的瑜伽,清晨怒炸,走出大門外带饱,心兒歡呼雀躍,身體輕快得想要飛飄起來阅羹,肆意抬起雙臂勺疼,飛啊,飛啊捏鱼,繞到...
    冬天的雪娃娃快樂閱讀 213評論 0 0
  • 首先祝賀你經(jīng)歷了高考順利進入大學执庐,算是對你前階段努力的回報,相信你也一定對大學充滿著無限憧憬导梆,大學是一個可以自由發(fā)...
    Hades_閱讀 184評論 0 0