We are IoTalabs and we are a group of Internet of Things enthusiasts that love hacking together different devices. We've been working on many projects. Check out our current project:
After receiving several follow-up questions about our previous Bluetooth guide, we've decided to expand on it.
You can find our previous guide on our profile page, and we recommend you check it our first, as this guide will assume understanding of the concepts went over previously. Let's get started!
Step 1: Enabling Background Processing
If you want your app to performing actions such as scanning for new peripherals, receiving characteristic updates, and connecting to devices, you need to enable background activity for your device. Once you know how, it is very easy to alter your devices property list to enable this.
First, click the Info.plist file in the menu bar on the left side of your app. For those of you have never had to use this file before, it is structured text file that contains essential configuration information for when you run your app. In general, you can simply think of it as a settings dictionary. The setting we want to add to this settings dictionary is the ability to do background processing.
First, control click the table and toggle "Show Raw Keys/Values" on.
Second, control click the table and click "add row".
Third, select UIBackgroundModes as the key for the new item.
Fourth, if it did not change automatically, change the type for this row to "Array".
Fifth, for item 0 of the array, set the type as string
Lastly, type in "bluetooth-central".
When you app launches, this new setting will let it know that this app needs access to background bluetooth processing.
Step 2: Finding a Peripheral That We Have Already Connected To
Often times when using the CoreBluetooth framework, you will need to access information about a peripheral's characteristics, naming, or other properties. If you don't have it saved anywhere in particular, don't worry, there is still a way to retrieve it!
Since we set the myManager property is strong reference to the central controller object, we should still have access to it. If we pass in the service we want (we can also store that earlier in the program), this function uses the retrieveConnectedPeripheralsWithServices method of the CBCentralManager class to find a specific peripheral. In this case, we are searching for a device named "DOT", but we can search by other names or better yet by UUID strings shows in the earlier tutorial.
Right now, the function simply iterates through the peripherals with the selected service to return whether or not it exists, but we could easily create other methods that make use of this functionality.
Step 3: Monitoring Changes to a Characteristic
In the first Bluetooth tutorial, we subscribed to the value of the transmission characteristic. When we send a message writing over the value of the characteristic, the method didWriteValue for characteristic. Right now, all the function does is let us know that the message was received, and gives us an error message if there was one.
Subscribing has many more uses other than error detection however. For example, with the Dot we subscribe to the rx characteristic, which is designed to let us receive information from the peripheral. This "subscribe" functionality is central to how we use the button. Whenever the user presses a button on the Dot peripheral, the rx characteristic is updated and the didUpdateValueForCharacteristic method is triggered. Because we are subscribed to the characteristic's value, we are notified of the change. Once we receive the message, we record the time the button was pressed, whether or not it was double clicked or held down, and other useful information.
Subscribing to a characteristic's value allows your app to be responsive to external factors (such as button presses) and monitor errors.
Step 4: Reconnecting to a Peripheral
Often times, it can be very useful to automatically reconnect to peripherals once we've lost our connection. If we step out of distance, the peripheral runs out of battery, or other external factors occur, we want to be able to reconnect quickly.
One cheap workaround is to simply call for a reconnect when the didDisconnectPeripheral callback is triggered (shown above). In CoreBluetooth, a request to connect to a peripheral can never time out so long as the app is not shut off. So if you have a device that automatically unlocks your door when your phone gets in range, you can set your program to automatically reconnect when you step out of range. If your app is turned off or your phone is shut down, there are other more advanced techniques we can use, but that is out of the scope of this short tutorial.
A second method is to simple keep track of the peripherals you have connected with using the retrievePeripheralsWithIdentifiers method of the CBCentralManager class, or retrieve by using services as discussed earlier.