Chapter    16

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.

9781484214893_Fig16-01.jpg

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.

  • The central is the boss that wants information from one or more workers in order to accomplish a specific task.
  • The peripheral is the worker that sends and receives data that is consumed by the central devices. The peripheral has the data the central wants.

9781484214893_Fig16-02.jpg

Figure 16-2. Understanding central and peripheral devices

Peripheral Advertising

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.

Peripheral Data Structure

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:

  • A service is a collection of data and associated behaviors describing a specific function or feature of a device. A device can have more than one service. The heart rate monitor exposing heart rate data from the monitor’s heart rate sensor is a great example of this.
  • A characteristic provides additional details about a peripheral’s service. A service can have more than one characteristic. The heart rate service, for example, may contain a characteristic that describes the intended body location of the device’s heart rate sensor and an additional characteristic that transmits heart rate measurement data.

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.

9781484214893_Fig16-03.jpg

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:

  • How set up your heart rate monitor
  • How to request permissions to access and store HealthKit data
  • How to read Bluetooth Low Energy (BLE) data and format it to show in the Health app
  • How the Core Bluetooth Framework works
  • How to display information from the heart rate BLE monitor (see Figure 16-4)

9781484214893_Fig16-04.jpg

Figure 16-4. The Heart Rate Monitor app

  1. Create a Single View Application, as shown in Figure 16-5.

    9781484214893_Fig16-05.jpg

    Figure 16-5. Creating a single view application

  2. Name your app and save the project, as shown in Figure 16-6.

    9781484214893_Fig16-06.jpg

    Figure 16-6. Naming the project

  3. Change the bundle identifier to the identifier you are going to use to submit to the App Store and include the HealthKit.framework. Also, select your developer team, as shown in Figure 16-7.

    9781484214893_Fig16-07.jpg

    Figure 16-7. Adding your own bundle identifier, team, and HealthKit.framework

  4. In order use HealthKit, you need to add the HealthKit entitlement. Change the project’s capabilities to add HealthKit, as shown in Figure 16-8.

    9781484214893_Fig16-08.jpg

    Figure 16-8. Including the HealthKit capabilities in the project

  5. The app doesn’t automatically get access to the HealthKit data, so it first needs to ask permission. Open the ViewController.swift file to add all of the related code this app needs.
  6. Import the Core Bluetooth and HealthKit frameworks, add the Core Bluetooth delegate protocols, and declare the instance variables, as shown in Listing 16-1. The ViewController needs to implement the CBCentralManagerDelegate protocol to enable the delegate to monitor the discovery, connectivity, and retrieval of peripheral BLE devices. The ViewController also needs to implement the CBPeripheralDelegate protocol so it can monitor the discovery, exploration, and interaction of a remote peripheral’s services and properties.

    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.

  7. Add the Heart.png and Human.png files from the Chapter 16 project to this project. Then create the outlets for the labels, as shown in Figure 16-9.

    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.

    9781484214893_Fig16-09.jpg

    Figure 16-9. Creating the HealthKitStore object and setting the variables

  8. Add the viewDidAppear method as shown in Listing 16-2. You need to instantiate the centralManager and request authorization to the HealthKit store.
  9. Add the centralManagerDidUpdateState function as shown in Listing 16-3. This ensures that the device is BLE compliant and it can be used as the central device object of the CBCentralManager. If the state of the central manager is powered on, the app will receive a state of CBCentralManagerStatePoweredOn. If the state changes to CBCentralManagerStatePoweredOff, all peripheral objects that have been obtained from the central manager become invalid and must be rediscovered.
  10. The next step is to determine if you have established a connection to the heart rate monitor. Add the didDiscoverPeripheral and didDiscoverServices functions. When you establish a local connection to a peripheral, the central manager object calls the didConnectPeripheral method of its delegate object.

    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.

  11. Now add the didDiscoverCharacteristicsForService function, as shown in Listing 16-5.

    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.

  12. Add the pulse function. Output the value of BPM to your bpmOutlet UILabel. Set up a timer object that calls pulse at 0.8-second intervals; this performs the basic animation that simulates the beating of a heart through the use of Core animation, as shown in Listing 16-7.
  13. Now add the didUpdateValueForCharacteristic function, as shown in Listing 16-8. The didUpdateValueForCharacteristic function will be called when CBPeripheral reads a value or updates a value periodically. We need to implement this method to check to see which characteristic’s value has been updated, and then call one of the helper methods to read in the value.
  14. Add the saveHeartRateIntoHealthStore function, as shown in Listing 16-9.

    In this function, you first create a sample object using HKQuantitySample. In order to create this sample, you need:

    • A Quantity type object, like HKQuantityType, initialized using the proper sample type.
    • A Quantity sample, like HKQuantity’s start and end date, which in this case is the current date and time in both cases.
  15. Add the requestAuthorizationForHealthStore function as shown in Listing 16-10. You’re creating a Set with all the types you need to read from the HealthKit store. Characteristics (blood type, sex, and birthday), samples (body mass and height), and workouts.

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.

9781484214893_Fig16-10.jpg

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.

9781484214893_Fig16-11.jpg

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.

9781484214893_Fig16-12.jpg

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.

9781484214893_Fig16-13.jpg

Figure 16-13. Free live Swift 2.0 training videos and forum

Good luck and have fun!

Exercises

  • Enable the app to read data from the HealthKit store
  • Enable the app to connect and disconnect to the heart rate monitor
  • Enable the users to set visual and audible alarms when their heart rate gets too high
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset