Using PebbleKit iOS
PebbleKit iOS is a framework provided with the Pebble SDK that can be embedded in any iOS application. Using the classes and methods in this framework, your app can find and communicate with Pebble.
This section of the Mobile App Developer Guide assumes that you have a basic knowledge of Objective-C. the delegate pattern and blocks .
As you walk through this guide, you may want to keep a tab opened to the PebbleKit iOS Reference .
Understanding the limitations of PebbleKit on iOS
The iOS platform imposes some restrictions on what apps can do with accessories. It also limits the capabilities of apps that are in the background. It is critical to understand these limitations when developing an app that relies on PebbleKit.
Whitelisting your Pebble iOS app
Pebble is an accessory registered in the Apple MFI program. This means that Pebble can talk to iOS applications over Bluetooth and that the Pebble applications enjoy some special privileges, including the ability to be started by Pebble and to run in the background.
To communicate with Pebble, your app uses the PebbleKit library, which sends and receives Bluetooth messages using the External Accessory Framework. This requires an extra step before submission, namely, that your app must be whitelisted by Pebble.
Please refer to Whitelisting iOS applications for more information about whitelisting.
On iOS, all communication between a mobile app and Pebble is managed through a communication session. This communication session is a protocol specific to iOS, with notable limitations that you should know and understand when developing your iOS app for Pebble.
Only a single session is available for third-party apps. This single session has to be shared among all third-party apps that want to communicate with Pebble, excluding the official Pebble iOS app.
The session can only be opened from the phone app. This means that the iOS app has to start “talking” to the watch first in order to open the communications channel; the other way around is not possible. Most methods provided in PebbleKit iOS, like Ping, Version, Sports, Golf and AppMessages, all implicitly open the shared communication session.
iOS doesn’t currently provide a reliable method for managing how one shared session is used or accessed. In practice, the last iOS app to try to open the session wins, and gets to use it.
During a session only the watchapp in the foreground can send and receive messages from the mobile app.
Getting started with PebbleKit iOS
Using PebbleKit on iOS only requires a few simple steps:
Drag PebbleKit.framework into your project (from
Drag in PebbleVendor.framework into the project, or drag the PebbleVendor.xcodeproj into the project if you need to control the third-party components needed for PebbleKit.
Figure 1 Project content after adding both PebbleKit.framework and PebbleVendor.framework .
Link ExternalAccessory.framework. libz.dylib. CoreBluetooth.framework. CoreMotion.framework. CFNetwork.framework and MessageUI.framework .
Figure 2 Linked framework and Libraries after adding PebbleKit.framework dependencies.
Now add the -ObjC linker flag to your project’s build settings.
Figure 3 Adding the -ObjC flag to your project’s build settings.
Add the value com.getpebble.public to the “Supported external accessory protocols” (UISupportedExternalAccessoryProtocols) array in your app’s Info.plist .
Figure 4 The array added to your app’s Info.plist
Pebble recommends that you add the value “App communicates with an accessory” (external-accessory) to the “Required background modes” ( UIBackgroundModes ) array in your app’s Info.plist. This allows your app to keep the connection with Pebble active when running in the background.
Finally, you’ll want to import the PebbleKit header file in the classes that will interact with Pebble:
Overview of PebbleKit iOS
PebbleKit is built around two core Objective-C classes:
PBPebbleCentral. This class allows you to find and connect to Pebble. It also maintains a list of all the Pebbles to which the user connected, and can send events to a delegate when a new Pebble appears or when a Pebble disconnects.
PBWatch. This class allows you to get information and communicate with a Pebble. This is the key class in PebbleKit and the one you will spend the most time with. There are different ways to get a PBWatch object: you should keep a reference to it as long as the app is running.
The PBPebbleCentral class should not be instantiated directly. Instead, always use the singleton provided by [PBPebbleCentral defaultCentral] .
Connecting to the last known Pebble
In most cases, you’ll want to connect to the last seen Pebble. This can be easily accomplished with [[PBPebbleCentral defaultPebbleCentral] lastConnectedWatch]. which returns a pointer to a PBWatch object.
Detecting Pebble connection and disconnection
Your application can also detect when a Pebble connects or disconnects. To do this, you must provide a PBPebbleCentralDelegate to [[PBPebbleCentral defaultCentral] setDelegate:] .
In iOS, delegation serves as a powerful design pattern that enables one object in a program to act on behalf of, or in coordination with, another object. The delegate may respond to a message by updating the appearance or state of itself or other objects in the app. For more information on delegation, refer to Cocoa Core Competencies .
This delegate will get two callbacks: -pebbleCentral:watchDidConnect:isNew: and pebbleCentral:watchDidDisconnect: every time a Pebble connects or disconnects.
You won’t get callbacks if the Pebble is already connected when you set the delegate.
To get the list of connected Pebbles at startup, use [[PBPebbleCentral defaultPebbleCentral] connectedWatches] or lastConnectedWatch .
Gathering information on Pebble
Using the PBWatch object, you can get the name and the serial number of this Pebble.
You can also get information about the firmware running on Pebble with getVersionInfo. This is an asynchronous call (because it requires communication with Pebble), and you will get the reply passed to a block:
This is what the output looks like with firmware 2.0-DP3-rc5 :
Communication with a Pebble app
To communicate between the mobile app and your watchapp, you use the appMessagePushUpdate:onSent: and appMessagesAddReceiveUpdateHandler: methods discussed in this section.
The messages that you exchange are arbitrary sets of key/value pairs. On the iOS side, you use NSDictionary objects and on the Pebble side, you use Dictionary objects as described in Integrating Watchapps With Phone Apps .
To send and receive messages, the Pebble app can use the AppMessage API or the AppSync API .
The maximum buffer size for AppMessage is currently 124 bytes. This means that no messages that you send or receive can be bigger than 124 bytes once transformed into a Pebble Dictionary object.
You will need to split your data in smaller chunks if you want to send a larger volume of data.
Targeting your companion app on Pebble
Before you start or exchange messages with a companion app on Pebble, you need to give PebbleKit a way to identify your companion app. The UUID of your app (which is defined in appinfo.json. see Anatomy of a Pebble app for more information) is used for that purpose.
To define the UUID of your companion app, you need to send the message setAppUUID: to a PBPebbleCentral. A simple way to transform a UUID in standard representation (the one used in appinfo.json ) to bytes is shown here:
Launching and killing your Pebble app
Using PebbleKit, you can start and stop your companion Pebble app with the appMessageLaunch: and appMessageKill: messages. Both take one parameter: a block that is called when the command is sent or if an error occurred.
Checking compatibility with AppMessage
First of all, you should always make sure that this Pebble supports messaging with appMessagesGetIsSupported. Just like the getVersionInfo: call, this is an asynchronous call and takes a block as argument. The block will be called with two arguments: the first one is a pointer to the PBWatch object and the second a boolean that indicates whether this Pebble supports app messages.
All Pebble with firmware higher than 1.10 will support app messages. If you are already checking the firmware version somewhere else – or if your companion app only works on 2.x, you can safely ignore this step.
To send a message, prepare a NSDictionary object with the data that you would like to send.
And push this dictionary to the watch, using appMessagesPushUpdate:onSent. The first argument is the update to send and the second argument is a block that will be called when the data has been acknowledged by the watch or if an error occurs.
To receive messages from the watchapp, you register a receive handler (a block) with appMessagesAddReceiveUpdateHandler. This block will be called with two parameters: a pointer to a PBWatch object describing the Pebble that sent the message and a NSDictionary with the message received.
You should always return YES in your handler. This informs PebbleKit to automatically send an ACK to Pebble.
Closing the session
When you’re finished exchanging information with your Pebble app, you can release the communication channel with closeSession.
Using the Sports APIs
The Pebble Sports APIs allow you to control the Sports and the Golf apps. Those apps are embedded in every Pebble but are hidden until a mobile app opens a session with them.
You interact with both apps, using messages on PBWatch. The Sports and Golf apps allow you to:
- Define the title and icon that will appear in the Pebble menu
- Launch and stop the Sports apps
- Control the information displayed on the screen (each app provides a set of predefined fields)
- Receive events when the user interacts with the apps on Pebble
For more information, refer to the API reference documentation for PebbleKit iOS (Sports methods and Golf methods ) and the Examples (Sports in Examples/sports-demo/SportsDemo-iOS and Golf in Examples/golf-demo/GolfDemo-iOS ).
Collecting data with Data Logging
Data Logging is a new framework available in SDK 2.0.
Related topics and sample code
Please refer to PebbleKit iOS Reference documentation for more information on PebbleKit iOS.
To take advantage of PebbleKit iOS and integrate your phone app with your Pebble app, you may want to explore some of the available sample code in the Pebble SDK 2:
The weather app in
/pebble-dev/PebbleSDK-2.1.1/Examples/weather/ shows how to update the display of a Pebble app to show the local weather, based on the user location and weather information collected from a public JSON web service.
The Sports app and the Golf app in
/pebble-dev/PebbleSDK-2.1.1/Examples/golf-demo/GolfDemo-iOS demonstrate how to interact with the Sports and the Golf application on Pebble.
The Ocean Survey app in
/pebble-dev/PebbleSDK-2.1.1/Examples/data-logging-demo/OceanSurveyDemo-iOS demonstrates how to process information sent from a Pebble app using data logging.