A Swift HealthKit iPhone App
HealthKit enables iOS developers to integrate health and fitness devices with their app and integrate the data with Apple’s easy-to-read dashboard. HealthKit enables health and fitness apps on an iOS device to work together and report device data in the Health app dashboard. See Figure 16-1.
Figure 16-1. The Health app’s dashboard
HealthKit is the accompanying developer SDK included in iOS 8 and newer. The SDK enables other applications to access health data with the user’s permission. For example, a blood pressure application could share its information with the user’s doctor.
A number of companies support HealthKit, including Polar, EPIC, Mayo Clinic, and RunKeeper.
Note To work through this example, you’ll need an active developer account. You won’t be able to enable the HealthKit Capability and access the HealthKit store without one.
Introduction to Core Bluetooth
The Core Bluetooth framework lets your iOS apps communicate with Bluetooth’s low energy devices (Bluetooth LE or BLE, for short). BLE devices include heart rate monitors, digital scales, digital thermostats, and more.
The Core Bluetooth framework is an abstraction of the Bluetooth LE specification and defines a set of protocols for communicating with the Bluetooth LE devices.
Along with learning about HealthKit in this chapter, you’ll learn about the key concepts of the Core Bluetooth framework, including how to use the framework to discover, connect to, and retrieve data from BLE-compatible devices. You will learn these skills by building a heart rate monitoring application that communicates with a BLE heart monitor and displays the information on an animated user interface along with storing the information in Apple’s Health app.
The heart rate monitor we use in this example is the Polar H7 Bluetooth Smart Heart Rate Sensor that can be purchased from Amazon.com. If you don’t have one of these devices, you can still follow along with the tutorial, but you’ll need to modify the code for whatever BLE device you have.
Central and Peripheral Devices
There are two major components involved in BLE communication; the central and the peripheral. See Figure 16-2.
Figure 16-2. Understanding central and peripheral devices
Advertising is the primary way that peripherals make their presence known via BLE.
In addition to advertising their existence, advertising packets can also contain some data, such as the peripheral’s name. The packets can even contain some extra data related to what the peripheral collects. For the heart rate monitor application, the packets also provide heartbeats per minute information.
The central scans for these advertising packets, identifies any peripherals it finds relevant, and connects to individual devices for more information.
Advertising packets are very small and cannot contain large amounts of data, so to get more data, a central needs to connect to a peripheral to obtain all of the data available.
Once the central connects to a peripheral, it needs to choose the data it is interested in. With BLE, data is organized into services and characteristics:
Once a central has established a connection to a peripheral, it is free to discover the full range of services and characteristics of the peripheral, and to read or write the characteristic values of the available services.
CBPeripheral, CBService, and CBCharacteristic
A peripheral is represented by the CBPeripheral object, while the services relating to a specific peripheral are represented by CBService objects. See Figure 16-3.
Figure 16-3. Structure of a peripheral’s services and characteristics object hierarchy
The characteristics of a peripheral’s service are represented by CBCharacteristic objects, which are defined as attribute types containing a single logical value.
Each service and characteristic you create must be identified by a universally unique identifier, or UUID. UUIDs can be 16- or 128-bit values, but if you are building your client-server (central-peripheral) application, you’ll need to create your own 128-bit UUIDs. Also, make sure the UUIDs don’t collide with other potential services in close proximity to your device.
Let’s Get Started and Build the App
We are going to build a simple heart rate monitor app that works with a Bluetooth Low Energy (BLE) heart rate monitor. In the process of building this app, you will learn a lot about HealthKit and Bluetooth Low Energy (BLE), such as:
Figure 16-4. The Heart Rate Monitor app
Figure 16-5. Creating a single view application
Figure 16-6. Naming the project
Figure 16-7. Adding your own bundle identifier, team, and HealthKit.framework
Figure 16-8. Including the HealthKit capabilities in the project
The core of the HealthKit Framework is the HKHealthStore class, as shown on line 18 in Listing 16-1. Now that you’ve created an instance of HKHealthStore, the next step is to request authorization to use it.
The users are the masters of their data, and they control which metrics you can track. This means you don’t request global access to the HealthKit store. Instead, you request access to the specific types of objects the app needs to read or write to the store.
Note You can refer to the Chapter 16 project that can be downloaded from forum.xcelme.com as described in the Introduction. It includes the PNG files used for the app as well as showing you the auto-layout constraints if you need help.
Figure 16-9. Creating the HealthKitStore object and setting the variables
In the implementation, we first set the view controller to be the delegate of the peripheral object so that it can notify the view controller. If no error occurs, we next ask the peripheral to discover the services associated with the device. Then we determine the peripheral’s current state to see if we have established a connection.
This function lets you determine the characteristics the service has. First, we check if the service is the heart rate service. Then, we iterate through the characteristics array and determine if any of the characteristics are a heart rate monitor notification characteristic. If so, we subscribe to this characteristic, which tells the CBCentralManager to notify us when the characteristic changes.
If the characteristic is the body location characteristic, there is no need to subscribe. You just read the value.
If the service is the device info service, look for the manufacturer name and read it.
To understand how to interpret the data from a BLE characteristic, you need to check the Bluetooth specification. For this example, visit https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml.
A heart rate measurement consists of a number of flags, followed by the heart rate measurement itself, energy information, and other data.
Add the update function shown in Listing 16-6. The update function is called each time the peripheral sends new data.
The update function converts the contents of the characteristic value to a data object. Next, you get the byte sequence of the data object. Then, you calculate the bpm variable, which will store the heart rate information.
To calculate the BPM, we obtain the first byte at index 0 in the array as defined by buffer[0] and mask out all but the first bit. The result returned will either be 0, which means that the first bit is not set, or 1 if it is set. If the first bit is not set, retrieve the BPM value at the second byte location at index 1 in the array and convert it to a 16-bit value based on the host’s native byte order.
In this function, you first create a sample object using HKQuantitySample. In order to create this sample, you need:
Then you check if the HealthKit store is available. For universal apps, this is crucial because HealthKit may not be available on every device. Finally, the app performs the actual authorization request; it invokes requestAuthorizationToShareTypes with the previously defined types for reads. Now that your code knows how to request authorization, you need to create a way for your app to invoke it.
App Summary
You are done adding code, so run the app. When the app starts, it asks permission to access the HealthKit store. If this is the first time the app has run, HealthKit store asks the user for permission, as shown in Figure 16-10.
Figure 16-10. HealthKit asking the user permission to access the app
As the app runs and is displaying data, it is also storing data in the HealthKit store. You can see that data by opening the Health App, as shown in Figure 16-11.
Figure 16-11. The heart rate data being stored in the HealthKit store
If you want to view the heart rate data in the Health app’s dashboard (Figure 16-12), you need to enable the Show on Dashboard switch, as shown in Figure 16-11.
Figure 16-12. The heart rate data being displayed in the dashboard
What’s Next?
You did it! You should have a great foundation to write outstanding apps. The best place to start is with your own idea for an app. Start writing it today. You are going to have lots of questions. That is how you are going to continue to learn. Keep moving forward and don’t stop, no matter if you get discouraged sometimes.
If you do get discouraged, visit www.xcelMe.com/forum. There are great resources on this site for finding answers to your questions. There is a topic for this book and each chapter in the book. Feel free to post your own questions. The authors of this book help answer the posts. Also, there are free videos on www.xcelMe.com. In the live sessions, you can ask questions to Gary Bennett. Just click the Free Videos tab at the top of the page, as shown in Figure 16-13.
Figure 16-13. Free live Swift 2.0 training videos and forum
Good luck and have fun!
Exercises