Practical Core Bluetooth in IoT & Wearable Projects

In recent years, “IoT” (Internet of Things) and “Wearable” have become buzzwords, so you might have interests in building hardware products. But learning how to develop electric circuits, mechanical systems or embedded systems etc. from zero is very difficult.

However, iOS developers can contribute to hardware projects with a knowledge of Core Bluetooth / Bluetooth Low Energy (BLE), even if they are not familiar with hardware layer.

In this session, you can learn the basics of Core Bluetooth / BLE (what it is, why we use it, and how it works), and gain practical knowledge to build apps for hardware products (how to design the apps, how to test without actual hardware prototypes, troubleshooting tips, and how the apps can be reviewed by Apple) which I learned through actual IoT/Wearable projects.

This would be interesting & understandable even if you are not familiar with or have no interests in Core Bluetooth because of the actual examples.


Introduction (0:00)

My name is Shuichi Tsutsumi. I am an iOS engineer working as a freelancer based in Japan. I have been developing iOS apps for almost six years.

Every year, when the new iOS version is announced at WWDC, I create a collection called examples for the new iOS APIs, named iOS Sampler. I publish it as open source on GitHub and they are widely used by developers. I have continued to do this private work for the past three years. Since iOS 7 I’ve created over 100 samples. I have already started to develop the iOS 10 sampler. It will be released at the same time as iOS 10.

Every year I work on this alone. However, if anyone is interested in contributing to this project, please let me know. I’ll invite you to my private repository. As a freelancer, I have worked on more than ten hundred projects, and I also wrote a 500 page book in Japanese about iOS and BLE (Bluetooth Low Energy).

In this session, I want to share with you the basics of Core Bluetooth and some practical tips with concrete examples of actual harder products that I have worked on. First, I want to explain what Bluetooth Low Energy is and why we use it.

Bluetooth Low Energy (BLE) (1:46)

Bluetooth Low Energy is called BLE, or BTLE for short. BLE is a wireless technology. The big difference between WiFi and BLE is that BLE does not need network infrastructure like WiFi does. WiFi requires internet infrastructure, but BLE can connect devices directly without the use of network infrastructures. It is also not compatible with the previous versions of Bluetooth.

The most important thing for iOS developers to know is that the API Core Bluetooth framework is open for developers. Any developer can use this framework. But in order to control Bluetooth, developers require major iPhone certification. It’s difficult to get. So BLE is almost the only way to enable iOS apps to communicate with external hardware without infrastructure or IMEI. That’s why Core Bluetooth is so important in the IOT (Internet of Things) field.

Basics of Core Bluetooth (3:09)

Let’s start with the basics of Core Bluetooth. First, let me introduce a wearable product that uses BLE. It’s a toy called Moth Band. The bands communicate with the Beat iOS app using BLE, and the iOS app plays different sounds according to the user’s gestures and posture, such as a sword or a tennis racket.

I developed the Moth Band mobile app. The company is one of my clients. The Moth Band and the app are connected with BLE. Moth Band has sensors such as gyroscope and accelerator, and it sends the sensor data to the app using BLE. The mobile app analyzes the sensor data, and recognizes the user’s gesture or posture and creates different sounds according to the gesture or posture. That’s how Moth Band works with BLE.

Moth Band is a special use case for BLE. Next I will explain how BLE works with Core Bluetooth.

Step one is scanning, which means it is searching for a nearby BLE devices. The device emits a signal to advertise its presence. Emitting a signal is called advertise in BLE. The app starts scanning using this code.

centralManager.scanForPeripheralsWithServices(nil, options: nil)

It’s very simple. It is just calling one method. When it has discovered the Moth Band, didDiscoverPeripheral is called. In BLE, the app is called central, and the Moth Band is called peripheral.

func centralManager(central: CBCentralManager,
	didDiscoverPeripheral peripheral: CBPeripheral,
	advertisementData: [String : AnyObject],
	RSSI: NSNumber!)
{
	print(Discovered a BLE device!)
}

Step two is connecting. The iOS app connects to the discovered device using this code.

centralManager.connectPeripheral(peripheral, options: nil)
func centralManager(central: CBCentralManager,
	didConnectPeripheral peripheral: CBPeripheral)
{
	print(Connected!)
}

When the connection is established, this direct method didConnectPeripheral is called.

The next step is subscribing. This means being ready to receive data. To explain this step, I have to explain about GATT.

GATT is the Generic Attribute Profile. It defines how to transfer data and the data structure of BLE connections for each product. It has services and services have characteristics.

For example, the Moth Band has a sense service named Moff Service. The service has a sensor characteristic under built-in characteristic. The sensor characteristic has sensor data and the built-in characteristics has the built-in status of the Moth Band.

To start receiving data, the iOS app requests to be notified if the sensor characteristics changes with this code.

peripheral.setNotifyValue(true, forCharacteristic: c)

The last step is notify. When the Moth Band updates, the sensor characteristics vary. The subscribers are notified of the new value.

func peripheral(peripheral: CBPeripheral,
	didUpdateValueForCharacteristic characteristic: CBCharacteristic,
	error: NSError?)
{
	print(Received sensor data!)
}

When each receives the new value, this direct method will update the values code. This is how the app receives the sensor data. Then the app plays different sounds according to that data. That’s how BLE works with Core Bluetooth.

You might ask, “How about the hardware side?” For example, how is notify implemented on the hardware side? I’m sorry. I don’t know. I’m not familiar with the hardware side. Of course, it’s best if you know both sides, but if you only know the iOS side, it’s okay. Us engineers only need to know how to develop iOS apps on BLE. Likewise, hardware engineers only need to know about the hardware side on BLE.

Hardware projects I’ve worked on (7:59)

I was able to work on many hardware projects as an iOS engineer. Let me introduce some hardware projects I have worked on as an iOS engineer.

This is a new wheelchair named WHILL. I developed the app. This app can control the wheelchair remotely. It also lets the user fine tune the wheelchair’s movement without needing to call an engineer. That wheel has users all across the USA. America is a huge country, so this reduces support costs in each country.

BONX provides group conversation systems for outdoor activities such as, snowboarding, cycling, running, climbing, fishing, etcetera. It’s like the GoPro of walkie-talkies. This group conversation system consists of a Bluetooth earphone and iOS app. The app provides voiceover IP function. The app detects the human voice and cuts out all background noise such as wind, traffic, or the sound of a snowboard on snow. It can minimize battery consumption and data transaction volume. Because of this, the user can talk even in areas with poor coverage. In this product, BLE is used to manage the Bluetooth interruption on the iPhone. It’s also used between the apps to search for and invite friends to talk.

SmartDrive is an IOT device for cars. Here, BLE is used to sync data from a car to your iPhone.

This is a “printable open-source humanoid,” PLEN2. Here, BLE users control a robot.

This is another app project I worked on where we created devices for different dancers. Here, each dancer has an iPhone and an external stimulation device. The apps sense commands which are generated from the music to the external stimulation device. Different dancers can actually feel the music.

Those are projects I have worked on as an iOS engineer.

Practical Core Bluetooth (10:28)

Next, I’ll explain the practical side of Core Bluetooth which I learned working on those projects.

At the beginning of each project, we must decide what data will be sent or how it will be sent using BLE. This information is described as a GATT profile, as I explained earlier.

This is a GATT example simulated through the Moth Band. Each service and characteristics have 128 beat UUIDs to identify themselves. In this case, the picker of the device sends the characteristics value to the central device. The properties should be notified. This characteristic value has the x-y-z coordinate of accelerator on gyroscope. Each coordinate value is two bytes. A GATT can contain marked services, and a service can contain marked characteristics.

Here’s another example. This GATT is used to sense button interactions such as, push or release. The iOS app can be notified of the button interactions with this GATT. As the properties are notified, so are the sensor characteristics. The difference is the whole amount of the value. Each can be only 0x01, or 0x00. 0x01 means the button is pushed. 0x00 means the button is released.

This is another example of a GATT profile. In this case, the central app controls the peripheral device. So the data is sent the other way, compared to the sensor characteristics or the button characteristics. In this case, the property of the characteristic is right. When the user controls the UI of the app, the app writes the de-motorized value to the characteristic. In this way, the peripheral device can get the value from the app.

The GATT device for different dancers is similar to the remote control one. However, the format of that value is different. It’s more generic. This is the GATT, and the properties also write because the value is sent from the app to the peripheral device.

The external stimulation device can receive four types of commands such as, changing the pulse frequency, changing the electric current, right channels all off, or left channels all off. But, there’s only one characteristic and the value is only one byte.

In this characteristics value, the first byte and the second byte decide the type of command. For example, when both the first and second bytes are zero, the command changes the pulse frequency of the external stimulation.

How to define GATT (13:52)

I have shown some example of GATT profiles, so I’ll explain how to define those. The first step is creating user IDs for the services and characteristics. UIDs can be generated easily using the UUIDgen command.

$ uuidgen
CEEA31BC-BEAC-4A78-B7ED-FC96B6254D4C

The second step is defining the properties. The property depends upon many factors. For example, if the data is sent from the peripheral device to the central device, the property will be notified.

Next, we define the full amount of the value. The value is usually limited to 20 bytes. You can assign each byte according to your needs. That is how to define GATT.

Another important thing for designing a product using BLE is defining background behaviors of the app. As many iOS engineers know, background behaviors on iOS are very limited. For example, listening to music, getting location data or downloading data. If BLE did not work in the background, to use this wearble walkie-talkie device, you’d have to always keep the app in the foreground while snowboarding. Or with this IOT device for cars, you’d have to run the app to collect data from your car whenever you were driving.

When there are any BLE products, it’s important to know what is possible when BLE is in the background. In the background it can scan for peripherals and connecting to them is also possible. Reading, writing, and receiving notifications are also possible. Almost all functions can be used even in the background.

How to support background mode (16:14)

I’ll explain how to enable Core Bluetooth in the background. It’s very easy. Just check this box. Of course, there are some limitations. For example, the scanning interval becomes longer in the background than in the foreground. There are some more limitations, however we don’t have time to dive into the details here.

There’s another problem. What happens when the app is killed by iOS in the background? iOS sometimes kills background apps when it needs more memory or to conserve power. For example, if you are snowboarding and the app is killed by iOS in the background, the button will not work. So you must take off your gloves and take out your iPhone from your pocket and run the app again. It would be totally impractical.

Don’t worry, there is a fantastic feature in Core Bluetooth. It’s called State Preservation and Restoration. With this feature the system takes over the BLE functions after the app is killed. When the app is killed by the system, the system saves the information needed for restoration and continues the BLE tasks. It reruns the app and calls the corresponding direct method. Using State Preservation and Restoration, the app can handle BLE events appropriately, even if it’s killed by the system.

For example, when snowboarding, the app has been killed by the system to save power. When the user pushes the button, on the peripheral device, the notification is received by the system instead of the app. Then the system reruns the app in the background, and calls the direct method.

func peripheral(peripheral: CBPeripheral,
	didUpdateValueForCharacteristic characteristic: CBCharacteristic,
	error: NSError?)
{
	print(Received the characteristic data!)
}
let options = [
	CBCentralManagerOptionRestoreIdentifierKey: "somekey"
]
centralManager = CBCentralManager(
	delegate: self,
	queue: queue,
	options: options)

The app can process the button interaction properly. This feature is optional, but the implementation is very easy. Just add an option when initializing the CBCentralManager object and implementing this direct method will restore state.

func centralManager(central: CBCentralManager,
	willRestoreState dict: [String : AnyObject])
{
	print("Restored")
}

It’s called when the app is restored. When we test it, we cannot kill our app by double-tapping the home button because when the app kills the app explicity, the app is not restored. We can use the kill function to kill the app as if it was killed by iOS.

kill(getpid(), SIGKILL);

That is defining background behaviors of the app.

How to test without HW prototypes (19:32)

Next, I’ll explain some problems that you might face during development. In most cases, it takes much longer to develop hardware prototypes than iOS apps. Often we have to develop iOS apps without actual devices. In fact, in more than half of the projects that I have helped with, there were no hardware prototypes when I started developing the app. I’ll show some solutions to test the BLE functions of our apps, without the actual hardware prototypes.

One of the solutions is to use the development kit of the BLE module which will be used in the project. This development kit contains the BLE module, display, USB interface, battery box, and other features which are needed to evaluate the BLE module. So we can start development without creating a circuit ourselves. This is by Bluegiga. However, other BLE module manufacturers such as Nordic or Broadcom provide this kind of kit.

I’ll show an actual example. I used this for the remote control app. This is the development kit, and this is the app. The development kit has the same GATT as the actual perihperal device so those can be connected with BLE. Please look at this display. The horizontal value and the vertical value are changing as I control the app. Those values are sent from the app with BLE to the development kit. After this development kit, the app worked fine when the actual device was ready.

The other option is creating an emulator app. This option means creating another app which behaves like the peripheral device, using the CBPeripheralManager class. Although using a development kit has some advantages, the emulator option is easier for iOS engineers.

For example, I created this emulator app for the walkie-talkie device because we didn’t have the prototype devices when I started developing the app. This button works the same as this button on the peripheral device. It has multiple interactions such as, single tap, double tap, long press, or very long press. This button on the emulator app is implemented using gestures only available in the UI kit. That’s how to test without hardware prototypes.

Troubleshooting (22:35)

Let me share some troubleshooting tips. If you have a Bluetooth gadget, you might experience problems like it cannot find the device, or cannot connect, or… There may be many typical problems like these. Of course, those programs will come with more problems then the final products. The hardware is not perfect because it’s in development and there might be bugs on the iOS app side.

To identify which side the problem is on, we can use another iOS app like LightBlue to compare the results with our apps in development. For example, let’s assume that your app cannot find the peripheral. Your app starts scanning, but the real discover method isn’t caught. Instead of using your app, you can use LightBlue. All you have to do is launch this app. It starts scanning automatically, and you can see the discovered peripherals like this.

If LightBlue can’t find the peripheral, you can assume that the problem is on your app. If both your app and the LightBlue cannot find the peripheral, you can assume that the peripheral device has a program it isn’t advertising.

In another case, let’s assume that your app can discover the peripheral, but cannot connect to it. The LightBlue app can connect to peripherals, so you can also identify this problem using LightBlue. You can see the services and characteristics of the peripheral and also check the UIDs, properties, and the values. That’s how to use LightBlue to identify which side the problem is on.

There are some other useful tools for debugging. One is Bluetooth Explorer, a Mac OS app made by Apple. This tool has many functions as you can see. One of those functions is a tool for BLE named Low Energy Devices. You can scan peripheral devices and connect to them. You can see the details of services and the characteristics, and you can also read, write, or subscribe.

In fact, this is possible even with iOS apps like LightBlue. However, there are some advantages of using Bluetooth Explorer.

func centralManager(
	central: CBCentralManager,
	didDiscoverPeripheral peripheral: CBPeripheral,
	advertisementData: [String : AnyObject],
	RSSI: NSNumber!)
{
	print(advertisementData)
}

For example, you can see the advertisement data when a peripheral is discovered, like this code. But, if you use Core Bluetooth on iOS, the advertisement data is already filtered by iOS. So we cannot see all of the advertisement data. Because of this, when we want to check the advertisement data of iBeacon, the manufacturer data field cannot be seen. This field contains the most important information for iBeacon such as, proximity ID, major ID, or minor ID. However, if you use Bluetooth Explorer, you can see all of this data.

Another tool for debugging is Pocket Rover. It’s also a Mac OS app made by Apple. Using this app we can see logs such as BLE advertisement packets from nearby peripherals, or pockets transferred with read or write. With Bluetooth Explorer and LightBlue, we can only see the last advertisement packet. However, with Pocket Rover, we can see the changes of advertisement packets as time goes by because it keeps a log. I used this to check iBeacon’s advertisement packets which changed as time went by.

Both Bluetooth Explorer and Pocket Rover can be obtained in the same way. From the menu you can find the More Developer Tools... menu. When you accept it, the download page of Apple developer tools will be opened in your browser. Download the file named ‘Hardware IO Tools’ and it includes the Bluetooth Explorer and Pocket Rover in it.

Now we have successfully completed the app development. How can the app be reviewed by Apple? Apple might require us to submit the peripheral device. But, the device might be too expensive or it might cost too much to send it, or there might not be enough devices when we want to submit the app.

For this project, we shot a video to show how the app works with the peripheral device. It does not need to be professionally produced, just show that all of the app interactions with the device work fine. I created these kinds of videos for several projects, and only used an iPhone to shoot them and iMovie for editing.

Conclusion (28:42)

To recap, first I explained what Bluetooth Low Energy (BLE) is and why we use it. Next, I explained how BLE works with Core Bluetooth in a wearable product.

I explained the basics of Core Bluetooth, and after introducing some hardware projects I worked on as an iOS engineer, I explained the practical side of Core Bluetooth which I learned working on those projects.

We also covered defining GATT, defining background behaviors of apps, some solutions to test without the actual hardware prototypes, some troubleshooting tips, and about review.

One more thing, I want to introduce some new features of Core Bluetooth in iOS 10. Unfortunately, I could not find interesting changes.

The most important thing is this, after iOS 10 we must include Bluetooth peripheral use description in the Info.plist. It said that if we don’t include this the app will crash. I tried building iOS 10 without including this key yesterday, but it didn’t crash. I hope someone will ask about this at the developer level.

The biggest change is this: the state properties of CBCentralManager and CBPeripheralManager are deprecated. Instead we have to use the CBManager class to access through the state of Bluetooth. You might ask, “How can we access through the states through the CBCentralManager or CBPeripheralManager object in iOS 10?” It’s not difficult. CBCentralManager and CBPeripheralManager are defined as sub-classes of CBManager in iOS 10. So we can access them through the state in the same way as before.

Another new thing, is the new initializer of CBCentralManager and CBPeripheralManager. Those don’t require arguments. With this, we can change our code like this.

The last urgent thing is this constant. It represents the UID of variance descriptor. The descriptor is used to represent the varied minimum or maximum values accepted for characteristic.

Q & A (31:37)

Q: With the Moth Band, are you just getting the numbers from the sensor and then interpreting the data on the iOS side? How do you interpret those numbers as specific movements? Are you using a framework or library for that? Shuichi: Yes. The Moth Band just sends sensor values to the iOS app. And then it’s our original algorithms.

Q: It seems that Bluetooth pairing is always a problem. With your experience, what’s some good advice to improve pairing when working with new devices? Shuichi: You mean pairing with the encrypt option? Okay. Actually, in the project I helped with, I haven’t used the pairing option because it shows the dialog to users, but the users can’t understand what it does. So we didn’t use that option. We used another system for security.

Q: What kind of range do you see with these devices, for example the BONX, if people, or snowboarders get far away, do they start dropping any kind of signal? Shuichi: In the BONX system, BLE is just used for connecting the device to the app. Communication between people is using voice over IP, so it’s possible even when very far away.


Shuichi Tsutsumi

Shuichi Tsutsumi

Shuichi is an iOS Freelancer who has developed many IoT related apps using Bluetooth Low Energy. He co-authored "iOS x BLE Core Bluetooth Programming" (2015) and authored "iOS Programming - Advanced 100 Recipes" (2013). He is the owner of popular OSS repositories such as iOS-9-Sampler, AnimatedTransitionGallery, and many more, ultimately totaling 15,000 stars.