SlideShare une entreprise Scribd logo
1  sur  43
Télécharger pour lire hors ligne
PebbleKit
Introducing 2-way communication
Available in Pebble Kit 1.1
Download from developer.getpebble.com
Requires Pebble firmware 1.10.2
New opportunities for developers!
• Watchfaces augmented with data from the internet
• Remote controls for internet connected devices
• Multi-player Pebble games
• 4sq/Facebook/Yelp Check-in Apps
• Sports/Weather/News/Traffic tickers
• Emergency beacon activator
• Deeper sports integration
• Bitcoin price trackers
TWO-WAY COMMUNICATION OVERVIEW
Both sides can push updates
Updates are key-value pairs (dictionary)
{
/* icon */ 0: (uint8) 3,
/* temp */ 1: “42°C”
}
Key must be an integer
Value can only be a string, bytes, int or int8
App-channels identified by a shared UUID
42c86ea4-1c3e-4a07-b889-2cccca914198
Acknowledgements provided by the framework
Not all apps require two-way communication
CURRENT LIMITATIONS
Only the watchapp in the foreground can
send and receive notifications
Communication must be initiated by the
phone
Only one 3rd-party app at a time
Apps need to be whitelisted by Pebble
USING TWO-WAY COMMUNICATION
Pebble
AppMessage PBWatch Intent Bus
AndroidiOS
AppMessage Generic updates exchange
static void s_main(void *params) {
static PebbleAppHandlers s_handlers = {
...
.messaging_info = {
.buffer_sizes = {
.inbound = 64, // inbound buffer size in bytes
.outbound = 16, // outbound buffer size in bytes
},
},
};
app_event_loop(params, &s_handlers);
}
AppMessage
Declare in/out buffer sizes in your PebbleAppHandlers struct
static void s_main(void *params) {
static PebbleAppHandlers s_handlers = {
/* ... */
.messaging_info = {
/* ... */
.default_callbacks.callbacks = {
.out_sent = my_out_sent_handler,
.out_failed = my_out_fail_handler,
.in_received = my_in_rcv_handler,
.in_dropped = my_in_drp_handler,
},
},
};
app_event_loop(params, &s_handlers);
}
Declare four new callbacks
AppMessage
void my_in_rcv_handler(DictionaryIterator *received, void *context) {
// incoming message received
}
void my_in_drp_handler(void *context, AppMessageResult reason) {
// incoming message dropped
}
void my_out_sent_handler(DictionaryIterator *sent, void *context) {
// outgoing message was delivered
}
void my_out_fail_handler(DictionaryIterator *failed, AppMessageResult reason,
void *context) {
// outgoing message failed
}
Implement your callbacks
AppMessage
DictionaryIterator *iter;
// Reserve the output buffer
app_message_out_get(&iter);
// Fill the buffer
dict_write_*(iter, ...);
dict_write_end(iter);
// Send the message
app_message_out_send();
// Release the output buffer
app_message_out_release();
Send messages
AppMessage
// Write data directly
dict_write_data(iter, KEY_DATA, data, sizeof(data));
dict_write_cstring(iter, KEY_STR, string);
dict_write_int(iter, KEY_INT, value, sizeof(value) /*bytes*/, true /*signed*/);
dict_write_uint8(iter, KEY_INT8, value8);
// Or use the Tuplet* constructs
Tuplet tuplet = TupletInteger(CMD_KEY, value);
dict_write_tuplet(iter, &tuplet);
Writing into a dictionary
Dictionary
Tuple *tuple = dict_read_first(&iter);
while (tuple) {
switch (tuple->key) {
case KEY_TO_A_DATA_VALUE:
foo(tuple->value->data, tuple->length);
break;
case KEY_TO_A_STRING_VALUE:
bar(tuple->value->cstring);
break;
case KEY_TO_A_INT32_VALUE:
foobar(tuple->value->int32);
break;
case KEY_TO_A_UINT8_VALUE:
foobar(tuple->value->uint8);
break;
}
tuple = dict_read_next(&iter);
}
Reading from a dictionary
Dictionary
dict_calc_buffer_size(2, sizeof(uint8_t), sizeof(char) * 8);
Evaluate the size of a dictionary
Dictionary
size = 1 + nTuples * 7 + Size1 + Size2 + ...
Evaluate the size of a dictionary
Dictionary
iOS Using AppMessage on iOS
[watch appMessagesGetIsSupported:^(PBWatch *watch, BOOL isAppMessagesSupported) {
if (isAppMessagesSupported) {
uint8_t bytes[] = {0x42, 0xc8, /* ... */, 0x91, 0x41, 0x98};
NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)];
[watch appMessagesSetUUID:uuid];
}
}];
Find out if the watch supports two-way communication
Register your channel with the shared UUID
iOS
NSNumber *iconKey = @(0);
NSNumber *temperatureKey = @(1);
NSDictionary *update = @{ iconKey:[NSNumber numberWithUint8:weatherIconID],
temperatureKey: @"42°C" };
[_targetWatch appMessagesPushUpdate:update
onSent:^(PBWatch *watch, NSDictionary *update, NSError *error) {
if (!error) {
// :)
}
}
];
Push updates to the watch
iOS
id updateHandler;
/* ... */
[ourWatch appMessagesGetIsSupported:
^(PBWatch *watch, BOOL isAppMessagesSupported) {
if(updateHandler)
[ourWatch appMessagesRemoveUpdateHandler:updateHandler];
updateHandler = [watch appMessagesAddReceiveUpdateHandler:
^BOOL(PBWatch *watch, NSDictionary *update) {
/* process message */
return YES;
}
];
}];
Receive updates from the watch
iOS
Android Using AppMessage on Android
if (PebbleKit.areAppMessagesSupported()) {
PebbleDictionary data = new PebbleDictionary();
data.addUint8(ICON_KEY, (byte) weatherIconId);
data.addString(TEMP_KEY, "42°C");
PebbleKit.sendDataToPebble(getApplicationContext(), UUID, data);
}
Find out if the watch supports two-way communication
Push an update to the watch
Android
public class MyDataReceiver extends PebbleDataReceiver {
@Override
public void receiveData(final Context context,
final int transactionId,
final PebbleDictionary data)
{
/* Process data */
PebbleKit.sendAckToPebble(getApplicationContext(), transactionId);
}
}
/* ... */
PebbleDataReceiver receiver = new PebbleDataReceiver(UUID);
PebbleKit.registerReceivedDataHandler(getApplicationContext(), receiver);
Register to receive updates
You must acknowledge updates
Android
Pebble
AppMessage PBWatch Intent Bus
AndroidiOS
AppSync
AppSync Synchronize watch fields
AppMessage
AppSync
A convenience layer on top of AppMessage
Maintains and updates a Dictionary
Provides a callback called whenever the Dictionary changes
static void s_main(void *params) {
static PebbleAppHandlers s_handlers = {
...
.messaging_info = {
.buffer_sizes = {
.inbound = 64, // inbound buffer size in bytes
.outbound = 16, // outbound buffer size in bytes
},
},
};
app_event_loop(params, &s_handlers);
}
You still need to declare the input / output buffers
Tuplet initial_values[] = {
TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1),
TupletCString(WEATHER_TEMPERATURE_KEY, "42°C"),
};
Prepare the initial values of your data
#include <...>
AppSync sync;
uint8_t sync_buffer[32];
Reserve global memory to store a AppSync struct
Reserve global memory to store your dictionary
app_sync_init(&sync, sync_buffer, sizeof(sync_buffer),
initial_values, ARRAY_LENGTH(initial_values),
sync_tuple_changed_callback, sync_error_callback, NULL);
Initialize the synchronization
void sync_tuple_changed_callback(const uint32_t key,
const Tuple* new_tuple, const Tuple* old_tuple, void* context)
{
// Update your layers
// Do not forget to call layer_mark_dirty()
}
Process the first (and subsequent) update
Tuplet new_tuples[] = {
TupletInteger(WEATHER_ICON_KEY, (uint8_t) 3),
TupletCString(WEATHER_TEMPERATURE_KEY, "73°C"),
};
app_sync_set(&sync, new_tuples, 2);
You can update the value on the Watch side
The callback will be called when the app has acknowledged
Pebble
AppMessage PBWatch Intent Bus
AndroidiOS
AppSync
THANK YOU!
@pebbledev
THANK YOU!
@pebbledev

Contenu connexe

Plus de Pebble Technology

#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
#PDR15 Creating Pebble Apps for Aplite, Basalt, and ChalkPebble Technology
 
#PDR15 - Developing for Round
#PDR15 - Developing for Round#PDR15 - Developing for Round
#PDR15 - Developing for RoundPebble Technology
 
#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble#PDR15 - Designing for Pebble
#PDR15 - Designing for PebblePebble Technology
 
Overlay Technique | Pebble Developer Retreat 2014
Overlay Technique | Pebble Developer Retreat 2014Overlay Technique | Pebble Developer Retreat 2014
Overlay Technique | Pebble Developer Retreat 2014Pebble Technology
 
Overlay & Libraries | Pebble Meetup Oct. 2014
Overlay & Libraries | Pebble Meetup Oct. 2014Overlay & Libraries | Pebble Meetup Oct. 2014
Overlay & Libraries | Pebble Meetup Oct. 2014Pebble Technology
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the WorldPebble Technology
 
Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Pebble Technology
 
Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Pebble Technology
 
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Pebble Technology
 
Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Pebble Technology
 
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Pebble Technology
 

Plus de Pebble Technology (16)

#PDR15 - Pebble Graphics
#PDR15 - Pebble Graphics#PDR15 - Pebble Graphics
#PDR15 - Pebble Graphics
 
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
 
#PDR15 - Developing for Round
#PDR15 - Developing for Round#PDR15 - Developing for Round
#PDR15 - Developing for Round
 
#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble
 
#PDR15 Kick-Off
#PDR15 Kick-Off#PDR15 Kick-Off
#PDR15 Kick-Off
 
Pebble Slate Workshop
Pebble Slate WorkshopPebble Slate Workshop
Pebble Slate Workshop
 
Overlay Technique | Pebble Developer Retreat 2014
Overlay Technique | Pebble Developer Retreat 2014Overlay Technique | Pebble Developer Retreat 2014
Overlay Technique | Pebble Developer Retreat 2014
 
Overlay & Libraries | Pebble Meetup Oct. 2014
Overlay & Libraries | Pebble Meetup Oct. 2014Overlay & Libraries | Pebble Meetup Oct. 2014
Overlay & Libraries | Pebble Meetup Oct. 2014
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the World
 
Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014
 
Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014
 
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
 
Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014
 
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
 
Pebble wearables devcon
Pebble wearables devconPebble wearables devcon
Pebble wearables devcon
 
Announcing Pebble SDK 2.0
Announcing Pebble SDK 2.0Announcing Pebble SDK 2.0
Announcing Pebble SDK 2.0
 

Dernier

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 

Dernier (20)

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 

Pebble Development - Using AppMessage for two way communication

  • 2. Available in Pebble Kit 1.1 Download from developer.getpebble.com Requires Pebble firmware 1.10.2
  • 3. New opportunities for developers! • Watchfaces augmented with data from the internet • Remote controls for internet connected devices • Multi-player Pebble games • 4sq/Facebook/Yelp Check-in Apps • Sports/Weather/News/Traffic tickers • Emergency beacon activator • Deeper sports integration • Bitcoin price trackers
  • 5. Both sides can push updates
  • 6. Updates are key-value pairs (dictionary)
  • 7. { /* icon */ 0: (uint8) 3, /* temp */ 1: “42°C” } Key must be an integer Value can only be a string, bytes, int or int8
  • 8. App-channels identified by a shared UUID 42c86ea4-1c3e-4a07-b889-2cccca914198
  • 10. Not all apps require two-way communication
  • 12. Only the watchapp in the foreground can send and receive notifications
  • 13. Communication must be initiated by the phone Only one 3rd-party app at a time Apps need to be whitelisted by Pebble
  • 17. static void s_main(void *params) { static PebbleAppHandlers s_handlers = { ... .messaging_info = { .buffer_sizes = { .inbound = 64, // inbound buffer size in bytes .outbound = 16, // outbound buffer size in bytes }, }, }; app_event_loop(params, &s_handlers); } AppMessage Declare in/out buffer sizes in your PebbleAppHandlers struct
  • 18. static void s_main(void *params) { static PebbleAppHandlers s_handlers = { /* ... */ .messaging_info = { /* ... */ .default_callbacks.callbacks = { .out_sent = my_out_sent_handler, .out_failed = my_out_fail_handler, .in_received = my_in_rcv_handler, .in_dropped = my_in_drp_handler, }, }, }; app_event_loop(params, &s_handlers); } Declare four new callbacks AppMessage
  • 19. void my_in_rcv_handler(DictionaryIterator *received, void *context) { // incoming message received } void my_in_drp_handler(void *context, AppMessageResult reason) { // incoming message dropped } void my_out_sent_handler(DictionaryIterator *sent, void *context) { // outgoing message was delivered } void my_out_fail_handler(DictionaryIterator *failed, AppMessageResult reason, void *context) { // outgoing message failed } Implement your callbacks AppMessage
  • 20. DictionaryIterator *iter; // Reserve the output buffer app_message_out_get(&iter); // Fill the buffer dict_write_*(iter, ...); dict_write_end(iter); // Send the message app_message_out_send(); // Release the output buffer app_message_out_release(); Send messages AppMessage
  • 21. // Write data directly dict_write_data(iter, KEY_DATA, data, sizeof(data)); dict_write_cstring(iter, KEY_STR, string); dict_write_int(iter, KEY_INT, value, sizeof(value) /*bytes*/, true /*signed*/); dict_write_uint8(iter, KEY_INT8, value8); // Or use the Tuplet* constructs Tuplet tuplet = TupletInteger(CMD_KEY, value); dict_write_tuplet(iter, &tuplet); Writing into a dictionary Dictionary
  • 22. Tuple *tuple = dict_read_first(&iter); while (tuple) { switch (tuple->key) { case KEY_TO_A_DATA_VALUE: foo(tuple->value->data, tuple->length); break; case KEY_TO_A_STRING_VALUE: bar(tuple->value->cstring); break; case KEY_TO_A_INT32_VALUE: foobar(tuple->value->int32); break; case KEY_TO_A_UINT8_VALUE: foobar(tuple->value->uint8); break; } tuple = dict_read_next(&iter); } Reading from a dictionary Dictionary
  • 23. dict_calc_buffer_size(2, sizeof(uint8_t), sizeof(char) * 8); Evaluate the size of a dictionary Dictionary
  • 24. size = 1 + nTuples * 7 + Size1 + Size2 + ... Evaluate the size of a dictionary Dictionary
  • 26. [watch appMessagesGetIsSupported:^(PBWatch *watch, BOOL isAppMessagesSupported) { if (isAppMessagesSupported) { uint8_t bytes[] = {0x42, 0xc8, /* ... */, 0x91, 0x41, 0x98}; NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)]; [watch appMessagesSetUUID:uuid]; } }]; Find out if the watch supports two-way communication Register your channel with the shared UUID iOS
  • 27. NSNumber *iconKey = @(0); NSNumber *temperatureKey = @(1); NSDictionary *update = @{ iconKey:[NSNumber numberWithUint8:weatherIconID], temperatureKey: @"42°C" }; [_targetWatch appMessagesPushUpdate:update onSent:^(PBWatch *watch, NSDictionary *update, NSError *error) { if (!error) { // :) } } ]; Push updates to the watch iOS
  • 28. id updateHandler; /* ... */ [ourWatch appMessagesGetIsSupported: ^(PBWatch *watch, BOOL isAppMessagesSupported) { if(updateHandler) [ourWatch appMessagesRemoveUpdateHandler:updateHandler]; updateHandler = [watch appMessagesAddReceiveUpdateHandler: ^BOOL(PBWatch *watch, NSDictionary *update) { /* process message */ return YES; } ]; }]; Receive updates from the watch iOS
  • 30. if (PebbleKit.areAppMessagesSupported()) { PebbleDictionary data = new PebbleDictionary(); data.addUint8(ICON_KEY, (byte) weatherIconId); data.addString(TEMP_KEY, "42°C"); PebbleKit.sendDataToPebble(getApplicationContext(), UUID, data); } Find out if the watch supports two-way communication Push an update to the watch Android
  • 31. public class MyDataReceiver extends PebbleDataReceiver { @Override public void receiveData(final Context context, final int transactionId, final PebbleDictionary data) { /* Process data */ PebbleKit.sendAckToPebble(getApplicationContext(), transactionId); } } /* ... */ PebbleDataReceiver receiver = new PebbleDataReceiver(UUID); PebbleKit.registerReceivedDataHandler(getApplicationContext(), receiver); Register to receive updates You must acknowledge updates Android
  • 32. Pebble AppMessage PBWatch Intent Bus AndroidiOS AppSync
  • 34. AppMessage AppSync A convenience layer on top of AppMessage Maintains and updates a Dictionary Provides a callback called whenever the Dictionary changes
  • 35. static void s_main(void *params) { static PebbleAppHandlers s_handlers = { ... .messaging_info = { .buffer_sizes = { .inbound = 64, // inbound buffer size in bytes .outbound = 16, // outbound buffer size in bytes }, }, }; app_event_loop(params, &s_handlers); } You still need to declare the input / output buffers
  • 36. Tuplet initial_values[] = { TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), TupletCString(WEATHER_TEMPERATURE_KEY, "42°C"), }; Prepare the initial values of your data
  • 37. #include <...> AppSync sync; uint8_t sync_buffer[32]; Reserve global memory to store a AppSync struct Reserve global memory to store your dictionary
  • 38. app_sync_init(&sync, sync_buffer, sizeof(sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL); Initialize the synchronization
  • 39. void sync_tuple_changed_callback(const uint32_t key, const Tuple* new_tuple, const Tuple* old_tuple, void* context) { // Update your layers // Do not forget to call layer_mark_dirty() } Process the first (and subsequent) update
  • 40. Tuplet new_tuples[] = { TupletInteger(WEATHER_ICON_KEY, (uint8_t) 3), TupletCString(WEATHER_TEMPERATURE_KEY, "73°C"), }; app_sync_set(&sync, new_tuples, 2); You can update the value on the Watch side The callback will be called when the app has acknowledged
  • 41. Pebble AppMessage PBWatch Intent Bus AndroidiOS AppSync