Introducing Pebble SDK 2.0November 6th 2013
New Tools SDK Overhaul New APIs
A MAJOR UPDATE
If you are watching live, you can ask questions
On our IRC channel: #pebble on irc.freenode.net
During our AMA on Reddit at 12pm PST today
This is recorded and will be available on our YouTube channel and on the developer web site
Friendly warning: This presentation is mostly intended for developers
Introducing Pebble SDK 2.0
New Tools
Improving the developer experience
CloudPebble Simplified build system
Deploying from the command line Application logs Documentation
Now open-sourced and hosted by Pebble Technology
CloudPebbleNew Tools
CloudPebbleNew Tools
No installation - From zero to first installed app in 60 seconds
One tool for all your Pebble development
Simplified build systemNew Tools
$ pebble new-project helloworldCreating new project hello-world$ cd helloworld$ pebble buildMemory usage:=============Total app footprint in RAM: 822 bytes / ~24kbFree RAM available (heap): 23754 bytes'build' finished successfully (0.351s)
Simplified build systemNew Tools
Use the Pebble mobile application to install and debug apps.
Developer ConnectionNew Tools
$ export PEBBLE_PHONE=192.168.1.42$ pebble install --logs[INFO ] Installation successful[INFO ] Enabling application logging...[INFO ] Displaying logs ... Ctrl-C to interrupt.[INFO ] D helloworld.c:58 Done initializing
Developer Connection
A very simple and reliable way to install and watch log messages
New Tools
We have re-written almost all of Pebble Documentation
Pebble documentation now includes: • A Getting Started Guide • Pebble Developer Guide with 11 chapters • Pebble Mobile Developer Guide • Pebble 2.0 Migration Guide • API Reference for Pebble, iOS and Android
DocumentationNew Tools
Improving the developer experience
CloudPebble Simplified build system
Deploying from the command line Application logs Documentation
New Tools
SDK Overhaul
Getting ready for bigger applications and an evolving SDK
Pebble 2.0 is a major evolution of Pebble 1.0 with lots of changes in the system and in the SDK
• Pebble 2.0 is not compatible with 1.0 apps
• Developers need to migrate their application to Pebble 2.0
SDK Overhaul
Refer to Pebble 2.0 Migration Guide http://developer.getpebble.com/2/guides/migration-guide.html
Migrating to Pebble 2.0
Pebble application must provide some metadata through a JSON file in the project called appinfo.json
• Application name • UUID • Watchface / Watchapp • Resources • etc
SDK Overhaul Application metadata
In Pebble OS 2.0, all the SDK structures are opaque. This means we can change them without you having to recompile your apps.
You cannot allocate structures as global variables as you did in 1.0. You must use pointers and memory allocated dynamically by the system.
All calls to _init() functions become are replaced by _create() calls
SDK Overhaul Using pointers and dynamic memory
Window my_window;window_init(&my_window);
Window *my_window;my_window = window_create();becomes
• pbl_main() is now called main()
• PblTm is replaced by struct tm
• string_format_time() is replaced by strftime()
• Pebble does not support timezones yet but we introduce gmtime() and localtime() to prepare for timezone support.
• get_time() is replaced by localtime(time(NULL))
SDK Overhaul Getting closer to standards: C/UNIX
Pebble 2.0 relies heavily on Events. You register to events with _register functions.
All Pebble 1.x APIs have been updated: Timer, Tick, AppMessage, etc
SDK Overhaul Enforcing a subscription based Event system
PebbleAppHandlers handlers = { .timer_handler = &handle_timer };
timer = app_timer_register(1500, timer_callback, NULL);
becomes
Introducing two old friends: malloc() and free()
Each application has it’s own heap and is cleaned automatically
You can attach data to layers and windows (layer_create_with_data() and window_set_user_data())
Your total memory is ~24k. Your heap space is 24k minus app size.
Pebble SDK includes tool to help you manage your memory:
SDK Overhaul Dynamic Memory
$ pebble build Memory usage: ============= Total app footprint in RAM: 822 bytes / ~24kb Free RAM available (heap): 23754 bytes !$ pebble logs ... [INFO ] I Heap Usage for <Template App>: Available <23200B> Used <2344B> Still allocated <0B>
Use pebble convert-project to generate the new appinfo.json file
Rename pbl_main() into main()
Use pointers to structures instead of statically allocated structures
Use the SDK APIs to allocate memory and initialize the structs
Check the other APIs for changes
SDK Overhaul Migration in a nutshell
Refer to Pebble 2.0 Migration Guide http://developer.getpebble.com/2/guides/migration-guide.html
Getting ready for bigger applications and an evolving SDK
SDK Overhaul
New Frameworks Event Services
A unique design pattern that communicates with Pebble OS subsystems
New Frameworks Event Services
The App Focus Service lets you know when your app is covered by a modal window
typedef void (*AppFocusHandler)(bool in_focus);!void app_focus_service_subscribe(AppFocusHandler handler);void app_focus_service_unsubscribe();
New Frameworks Event Services
The Bluetooth Connection Service lets you know when the watch is connected to the phone
typedef void (*BluetoothConnectionHandler)(bool connected);void bluetooth_connection_service_subscribe(BluetoothConnectionHandler handler);void bluetooth_connection_service_unsubscribe(void);!bool bluetooth_connection_service_peek(void);
New Frameworks Event Services
The Battery State Service can let you know when the watch is plugged or unplugged
typedef struct { uint8_t charge_percent; bool is_charging; bool is_plugged;} BatteryChargeState; !typedef void (*BatteryStateHandler)(BatteryChargeState charge);void battery_state_service_subscribe(BatteryStateHandler handler);void battery_state_service_unsubscribe();!void battery_state_service_peek(void);
New Frameworks Event Services
A unique design pattern that communicates with Pebble OS subsystems
Bluetooth, App Focus, Battery Status
Refer to Pebble 2.0 Event Services Guide http://developer.getpebble.com/2/guides/event-service-guide.html
New Frameworks Accelerometer
Let’s shake things up ...
The Accelerometer framework is designed with all use cases in mind: user interaction for watchfaces, games, activity monitor, etc
New Frameworks Accelerometer
Hardware accelerometer !
Able to detect taps Perform measurements at a given frequency
Store samples to save CPU time
New Frameworks Accelerometer
The simplest way to use the accelerometer is to register for tap events
Those events are generated by the hardware and use very little energyvoid accel_tap_handler(AccelAxisType axism int32_t direction) { // Process tap on ACCEL_AXIS_X, ACCEL_AXIS_Y or ACCEL_AXIS_Z}!void handle_init() { accel_tap_service_subscribe(&accel_tap_handler);}!void handle_deinit() { accel_tap_service_unsubscribe(); }
You can register to receive raw events one at a time
New Frameworks Accelerometer
void accel_data_handler(AccelData *data, uint32_t num_samples) {process_sample(&data);
}!void handle_init() { accel_data_service_subscribe(1, &accel_data_handler);}!void handle_deinit() { accel_data_service_unsubscribe(); }
The accelerometer API also supports storing samples on the hardware
void accel_data_handler(AccelData *data, uint32_t num_samples) { // Process 10 events - every 1 second}!void handle_init() { accel_data_service_subscribe(10, &accel_data_handler); accel_service_set_sampling_rate(ACCEL_SAMPLING_10HZ);}
New Frameworks Accelerometer
You can also peek at the accelerometer when updating your UI This is the strategy we recommend for game developers
New Frameworks Accelerometer
void tick_handler() { AccelData data; accel_service_peek(&data);}!void handle_init() { accel_data_service_subscribe(0, NULL);}void handle_deinit() { accel_data_service_unsubscribe(); };
New Frameworks Accelerometer
The Accelerometer Service
Tap events - Regular measures - Batch processing - Real time processing
Refer to Pebble 2.0 Accelerometer Guide http://developer.getpebble.com/2/guides/accelerometer.html
New Frameworks Data Logging
A better way to transfer data
The data logging service is a transparent buffer between your watch app and your phone that reliably and efficiently carries your data.
Your watchapp creates one or multiple data logging sessions and pushes data to those sessions.
Using PebbleKit iOS and Android, your mobile app gets events when new data is available for download.
Your data is managed by Pebble OS: saved on the watch filesystem, persisted if the user moves to another app, transferred in batches.
New Frameworks Data Logging
You create a spool with a call to data_logging_create ()
DataSpoolRef my_data_spool;!void handle_init() { logging_session = data_logging_create( /* tag */ 42, /* data type */ DATA_LOGGING_BYTE_ARRAY, /* length */ sizeof(AccelData), /* resume */ true );}
New Frameworks Data Logging
Use data_logging_log() to add data to the spool
New Frameworks
void accel_data_handler(AccelData *data, uint32_t num_samples) { DataLoggingResult r = data_logging_log(logging_session, data, num_samples);}
Data Logging
Finally, use data_logging_finish() when you are done
New Frameworks
void handle_deinit() { data_logging_finish(logging_session);}
Data Logging
You register to data spooling on iOS by providing a delegate to the dataLoggingService
New Frameworks
[[[PBPebbleCentral defaultCentral] dataLoggingService] setDelegate:self];
Data Logging - iOS
The delegate implements methods to consume the data
New Frameworks
- (BOOL)dataLoggingService:(PBDataLoggingService *)service hasUInt32s:(const UInt32 [])data numberOfItems:(UInt16)numberOfItems forDataLoggingSession:(PBDataLoggingSessionMetadata *)sessionMetadata {
// Return YES when the data has been processed.}!- (void)dataLoggingService:(PBDataLoggingService *)service sessionDidFinish:(PBDataLoggingSessionMetadata *)sessionMetadata { // Session closed.}
Data Logging - iOS
New Frameworks Data Logging
A better way to transfer data
The data logging service is a transparent buffer between your watch app and your phone that reliably and efficiently carries your data.
Refer to the Ocean Data Survey example Examples/data-logging-demo
New Frameworks Persistent Storage
Store data on the watch
Persistent storage is perfect to save user settings, cache data from the phone app, high scores, etc
Every application get its own persistent storage space. Its size is limited to 4kB.
Each value is associated to a uint32_t key.
Persistent storage supports saving integers, strings and byte arrays.
The maximum size of byte arrays and strings is defined by PERSIST_DATA_MAX_LENGTH (currently set to 256 bytes)
New Frameworks Persistent Storage
To write data in persistent storage, call one of the persist_write functions:
You should check the return value for error codes (anything but 0 is bad news)
New Frameworks Persistent Storage
void handle_deinit() { persist_write_bool(TRUTH_KEY, true); persist_write_int(DOUGLAS_KEY, 42); persist_write_string(USERNAME_KEY, “thomas”); uint8_t byte_array[42]; persist_write_data(DATA_KEY, sizeof(byte_array), byte_array);}
The function persist_exists(key) returns a boolean indicating if the key exists or not.
To read data from persistent storage, use the persist_read functions
New Frameworks Persistent Storage
void handle_init() { bool truth = persist_read_bool(TRUTH_KEY); int douglas_value = persist_read_int(DOUGLAS_KEY);
char username[20];persist_read_string(USERNAME_KEY, 20, username);
uint8_t byte_array[42]; persist_read_data(DATA_KEY, sizeof(byte_array), byte_array);}
You can use persist_delete() to remove a key from persistent storage
New Frameworks Persistent Storage
New Frameworks Persistent Storage
Store data on the watch
Persistent storage is perfect to save user settings, cache data from the phone app, high scores, etc
Refer to Pebble Persistent Storage Guide http://developer.getpebble.com/2/guides/persistent-storage.html
New Frameworks PebbleKit JavaScript
Expand the reach of your Pebble apps with JavaScript logic running on the phone
Make http calls on the phone, process the reply and send it to your watchapp.
Send notification. Use the phone GPS. Use a webview in the phone to provide a configuration
screen to your application.
Add a pebble-js-app.js file in your project
Or use pebble new-project --javascript
When Pebble mobile application installs your pbw, the JS is extracted and saved on the phone.
Your JavaScript code is started with your watchapp/watchface and will run as long as your app is in the foreground on Pebble.
New Frameworks PebbleKit JavaScript
New Frameworks PebbleKit JavaScript
Pebble sandbox provides API to receive messages from the watch, make http requests, send new messages to the watch, etc.
On the watch, AppMessage APIs are used to receive and send data.
PebbleKit JS is completely independent of the platform (iOS, Android).
The sandbox provides a Pebble.addEventListener function to register for events.
A ‘ready’ event is fired when your JavaScript is ready to execute.
PebbleEventListener.addEventListener("ready", function(e) { startRemoteRequest(); }});
New Frameworks PebbleKit JavaScript
Your JavaScript code can send notifications to the watch: Pebble.showSimpleNotificationOnPebble(title, text)
You can also use the standard console.log() calls to log messages to the Pebble console.
New Frameworks PebbleKit JavaScript
Your JS code can also process messages coming from the watch through the ‘appmessage’ event.
PebbleEventListener.addEventListener("appmessage", function(e) { var temperatureRequest = e.payload.temperatureRequest; if (temperatureRequest) { fetchWeather(); }});
New Frameworks PebbleKit JavaScript
To send messages to the watch, use Pebble.sendAppMessage()
PebbleKit JS automatically transforms JS dictionaries to Pebble’s Dictionary
New Frameworks PebbleKit JavaScript
Pebble.sendAppMessage({ "icon": ICON_SUNNY, "temperature": "28oC"});
The Pebble JavaScript sandbox provides the standard XMLHttpRequest method to make http calls.
var req = new XMLHttpRequest();req.open('GET', 'http://api.openweathermap.org/data/2.1/find/city?lat=37.830310&lon=-122.270831&cnt=1', true);req.onload = function(e) { if (req.readyState == 4 && req.status == 200) { if(req.status == 200) { var response = JSON.parse(req.responseText); var temperature = result.list[0].main.temp; var icon = result.list[0].main.icon; Pebble.sendAppMessage({ "icon":icon, "temperature":temperature + "\u00B0C"}); } else { console.log("Error"); } }}req.send(null);
New Frameworks PebbleKit JavaScript
Pebble sandbox provides several standard APIs:
• HTML5 Geolocation API through navigator.geolocation • Local Storage APIs through window.localStorage
New Frameworks PebbleKit JavaScript
Your application can show a Configure button on the phone screen
When the user clicks on this button, the configure event is fired
The html page can return information: document.location.href = “pebblejs:///close#some-data-set”
Pebble.addEventListener("showConfiguration", function() { console.log("showing configuration"); Pebble.openURL('http://assets.getpebble.com.s3-website-us-east-1.amazonaws.com/pebble-js/configurable.html');});Pebble.addEventListener("webviewclosed", function(e) { console.log("configuration closed");});
New Frameworks PebbleKit JavaScript
New Frameworks PebbleKit JavaScript
Expand the reach of your watchapp with JavaScript logic running on the phone
Make http calls on the phone, process the reply and send it to your watchapp.
Send notification. Use the phone GPS. Use a webview in the phone to provide a configuration
screen to your application.
Refer to Pebble JavaScript Guide http://developer.getpebble.com/2/guides/javascript-guide.html
WRAPPING UP
Updated Tools SDK Overhaul New Frameworks
pebble
Developer Connection
App Metadata
Following Standards
Events based APIs
Dynamic Memory
2.0 Migration Guide
Event Service
Accelerometer
Data Logging
Persistent Storage
PebbleKit JS
Cloud Pebble
Documentation
Application logs
Downloading the new SDK !
Available now on http://developer.getpebble.com/2/
Top Related