LightBlue Bean and iOS — A Tutorial
Here are a few of the things that make the Bean truly magical:
- Over the air code uploading
- Easy support for ultra-low-power sleep mode with just a simple `Bean.sleep()`
- So power efficient a Bean can run off of a single coin cell for months
- Onboard temperature sensor and accelerometer
- Onboard RGB LED
- Virtual Serial (we’ll get to that)
- Well-documented iOS SDK
I’m going to be mainly going over that last point— the iOS SDK. For someone who’s had a fair bit of iOS experience, the SDK is pretty easy to grasp. However, for beginners, it’s can be difficult to understand what’s going on. So, I’m going to provide you with a sample app and walk you through how the SDK works. To follow this tutorial, you’ll need a Mac with Xcode installed.
Head over to the GitHub repository for this tutorial and select “Clone or Download” then “Download Zip.”
Firstly, open up the file
BeanDemo.xcworkspace. The Bean SDK is linked to this Xcode project via a dependency manager called CocoaPods. CocoaPods makes it really easy to add SDKs like the Bean one to projects. The downside is that now you have to open the Xcode Workspace file instead of the regular Xcode project file.
Now that that’s sorted out, expand the folders under BeanDemo in the left-most window of Xcode. Click on
The AppDelegate is one of the key files in any iOS app, Objective-C or Swift. The AppDelegate has methods that are called just as your app is loading, and right before it terminates. You can think of the AppDelegate class as running in the background regardless of what view is on-screen. This makes it a perfect place to put all of the code that manages the Bean. I want to draw your attention to the code snippet below:
This method is the first piece of Bean-related code that’s called inside of the app. It checks to see if the Bean Manager is powered on. If so, it will immediately scan for available Beans. If it can’t do that (for example if BLE is off or not available) it will display an error message telling you what’s wrong.
Next is the method that’s called when a Bean is actually discovered:
When the Bean Manager discovers some nearby Bean it will then attempt to connect to it (line 12). Upon a successful connection, the code below is then triggered:
There’s a bunch of things going on here that I’ll try to explain. Firstly, if there’s some connection error the user will be notified and the rest of this method will be aborted.
The next pertinent piece of code is on lines 23–27 of the above gist. This section posts something called an NSNotification. Any class inside of the app can post an observer for that notification. When the notification is called, a method inside of that observing class will be triggered, running some code. For example, the ViewController class that manages the view on-screen observes when a bean is connected. When a bean does connect, you could have ViewController update a label with the name of that Bean.
The code below is triggered when a Bean disconnects:
You can see that there’s another notification being called: “BeanDisconnected.” The ViewController also has an observer for this. If this gets called, you could change that same label to have a text of “Disconnected” to indicate that there’s no longer a connected Bean. There’s one more method I want to call your attention to:
This is how you can actually send data from your Bean to your iPhone. Without it, you wouldn’t have much need for an iPhone app! Every time you call `Serial.print()` on the Bean, the string you pass in as an argument gets ASCII encoded then sent out as a Bluetooth signal. If a device like a phone is listening for that signal, it can pick up the binary data then decode it. This is what the above method does — it gets some raw binary, then converts it back into a string. For your convenience, the String is printed out to the console via
NSLog(), but you can do pretty much anything with the data.
Now click on ViewController.m.
The UIViewController class is used to control and manage various screens of your application. The startup screen for this app is simply a blank white page, managed by ViewController. Once the initial app view is loaded after beginning all that stuff in the AppDelegate, the method
viewDidLoad is called.
Inside of this method is where we’re placing all of those observers I mentioned earlier. The observers have to be tied to methods to be useful, so all those methods (
gotAcceleration, beanConnected, beanDisconnected) are included in ViewController. Here’s the whole process for what happens when a Bean connects:
- The Bean Manager notices, and tells the AppDelegate
- The AppDelegate will then post a “BeanConnected” notification
- If the ViewController’s view is on screen, the ViewController’s observer will receive that notification
- Lastly, the observer will call its associated method, which in this case is
To make this whole notification structure useful to you, you’ll need to add new notifications inside of AppDelegate. For example, a great place to put a notification would be at the end of
serialDataReceived. After you’re done processing the data that comes in you can make it available to other classes. That can be done, you guessed it, by posting a notification. This is just one example — there’s plenty more you can do!
The next thing I reccomend is that you go and read the PunchThrough Design documentation (https://punchthrough.com/files/bean/sdk-docs/index.html and https://punchthrough.com/bean/docs/guides/). It will give you a much better idea what’s available!
Now you’ve hopefully got a pretty good grasp of what’s going on, and how you can interface with Beans from your iOS device. If you’ve got any questions, feel free to contact me at info[at]coniferapps.com. I love helping people with this stuff so don’t hesitate to shoot me an email or comment below! You can check out all of my projects and work at www.AlexWulff.com.