神刀安全网

Using Sleep Analysis in HealthKit with Swift

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.

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 tobuild a fitness app, the framework also allows you access sleep analysis data.

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.

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 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.

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.

Before moving on, download the starter project from here. 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.

Working with the HealthKit Framework

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.

Using Sleep Analysis in HealthKit with Swift

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

let healthStore = HKHealthStore() 

Later we will use the HKHealthStore instance to access the 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:

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.

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.

Using Sleep Analysis in HealthKit with Swift

Writing Sleep Analysis Data

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:

  • 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
  • the total amount of time spent both in bed and asleep

Using Sleep Analysis in HealthKit with Swift

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

  1. We need to define two NSDate objects corresponding to the start time and the end time.
  2. We then create an instance of HKObjectType using HKCategoryTypeIdentifierSleepAnalysis .
  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.
  4. Finally, we’ll save the object using saveObject of HKHealthStore .

Editor’s note:For the type of the sample, you can look it up in 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:

func saveSleepAnalysis() {          // alarmTime and endTime are NSDate objects     if let sleepType = HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis) {                  // we create our new object we want to push in Health app         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.

Reading Sleep Analysis Data

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.

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

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         let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)                  // we create our query with a block completion to execute         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                 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.

App Testing

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.

@IBActionfunc 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.

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.

Using Sleep Analysis in HealthKit with Swift

Some Advices for HealthKit Apps

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.

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.

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

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Using Sleep Analysis in HealthKit with Swift

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址