SlideShare une entreprise Scribd logo
1  sur  128
Télécharger pour lire hors ligne
Pebble Watch
matthewmorey.com | @xzolian
matthewmorey.com | @xzolian
http://buoyexplorer.com
☐ What is the Pebble
☐ Why you should develop for the Pebble
☐ How to develop for the Pebble
Agenda
Demo
vs
ARM Cortex-M3 MCU
120 MHz
Apple A6
ARMv7 1.3 GHz
Dual Core
128 KB RAM
Up to 8 apps
1 GB RAM
Up to 64 GB storage
144 x 168 pixels
1-bit color
“e-paper”
1,136 × 640 pixels
24-bit Color
“Retina”
Pebble iPhone 5
CPU
Memory
Screen
Bluetooth 2.1 and
4.0 LE
Bluetooth 4.0
802.11a/b/g/n Wi-Fi
Cellular LTE
3-axis accelerometer
Ambient light
Magnetometer
Three-axis gyro
Accelerometer
Proximity sensor
Ambient light sensor
4 buttons
Vibration
Screen backlight
Touch screen
Buttons
Vibration
Camera
Pebble iPhone 5
Comm.
Sensors
IO
2 to 14 days ~1 day
FreeRTOS
Pebble SDK
PebbleKit
iOS
iOS SDK
5 ATM water
resistance
22 mm watch band
Not water resistant
Can’t wear on wrist
Pebble iPhone 5
Battery
Software
Other
Issues
☑ What is the Pebble
☐ Why you should develop for the Pebble
☐ How to develop for the Pebble
Agenda
LunaTik
“I agree to wear you
around and share a
lot of personal data
with you.”
- Customers
$10,266,846 - Pebble Watch (design)
$8,596,475 - OUYA (Android console)
$5,702,153 - Veronica Mars (movie)
$4,188,927 - Torment: Tides of Numenera (game)
$3,986,929 - Project Eternity (game)
$6 Billion
per year
Units Sold
Pebble iPhone
>100,000
>250 Million
iOS 7
☑ What is the Pebble
☑ Why you should develop for the Pebble
☐ How to develop for the Pebble
Agenda
Pebble SDK
1. Pebble SDK dependencies
2. Pebble SDK
3. ARM dependencies
4. Pebble ARM toolchain
Install
Hello World
$ create_pebble_project.py 
> PebbleSDK-1.12/Pebble/sdk 
> hello_world
1 #include "pebble_os.h"
2 #include "pebble_app.h"
3 #include "pebble_fonts.h"
4
5 #define MY_UUID {
6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49,
7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6,
8 0x50, 0x16
9 }
10
11 PBL_APP_INFO(
12 MY_UUID,
13 "Hello World",
14 "Acme Corp",
15 1, 0, /* App version */
16 DEFAULT_MENU_ICON,
17 APP_INFO_STANDARD_APP
18 );
1 #include "pebble_os.h"
2 #include "pebble_app.h"
3 #include "pebble_fonts.h"
4
5 #define MY_UUID {
6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49,
7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6,
8 0x50, 0x16
9 }
10
11 PBL_APP_INFO(
12 MY_UUID,
13 "Hello World",
14 "Acme Corp",
15 1, 0, /* App version */
16 DEFAULT_MENU_ICON,
17 APP_INFO_STANDARD_APP
18 );
1 #include "pebble_os.h"
2 #include "pebble_app.h"
3 #include "pebble_fonts.h"
4
5 #define MY_UUID {
6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49,
7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6,
8 0x50, 0x16
9 }
10
11 PBL_APP_INFO(
12 MY_UUID,
13 "Hello World",
14 "Acme Corp",
15 1, 0, /* App version */
16 DEFAULT_MENU_ICON,
17 APP_INFO_STANDARD_APP
18 );
20 Window window;
21
22 void handle_init(AppContextRef ctx) {
23 window_init(&window, "Window Name");
24 window_stack_push(&window,true/*Animated*/);
25 }
26
27
28 void pbl_main(void *params) {
29 PebbleAppHandlers handlers = {
30 .init_handler = &handle_init
31 };
32 app_event_loop(params, &handlers);
33 }
20 Window window;
21
22 void handle_init(AppContextRef ctx) {
23 window_init(&window, "Window Name");
24 window_stack_push(&window,true/*Animated*/);
25 }
26
27
28 void pbl_main(void *params) {
29 PebbleAppHandlers handlers = {
30 .init_handler = &handle_init
31 };
32 app_event_loop(params, &handlers);
33 }
20 Window window;
21
22 void handle_init(AppContextRef ctx) {
23 window_init(&window, "Window Name");
24 window_stack_push(&window,true/*Animated*/);
25 }
26
27
28 void pbl_main(void *params) {
29 PebbleAppHandlers handlers = {
30 .init_handler = &handle_init
31 };
32 app_event_loop(params, &handlers);
33 }
20 Window window;
21
22 void handle_init(AppContextRef ctx) {
23 window_init(&window, "Window Name");
24 window_stack_push(&window,true/*Animated*/);
25 }
26
27
28 void pbl_main(void *params) {
29 PebbleAppHandlers handlers = {
30 .init_handler = &handle_init
31 };
32 app_event_loop(params, &handlers);
33 }
15 TextLayer hello_layer;
16
17 void handle_init(AppContextRef ctx) {
18
19 window_init(&window, "Window Name");
20 window_stack_push(&window, true /* Animated */);
21
22 text_layer_init(&hello_layer, GRect(0, 65, 144, 30));
23 text_layer_set_text_alignment(&hello_layer,GTextAlignmentCenter);
24 text_layer_set_text(&hello_layer, "Hello World!");
25 text_layer_set_font(
26 &hello_layer,
27 fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21)
28 );
29
30 layer_add_child(&window.layer, &hello_layer.layer);
31
32 }
15 TextLayer hello_layer;
16
17 void handle_init(AppContextRef ctx) {
18
19 window_init(&window, "Window Name");
20 window_stack_push(&window, true /* Animated */);
21
22 text_layer_init(&hello_layer, GRect(0, 65, 144, 30));
23 text_layer_set_text_alignment(&hello_layer,GTextAlignmentCenter);
24 text_layer_set_text(&hello_layer, "Hello World!");
25 text_layer_set_font(
26 &hello_layer,
27 fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21)
28 );
29
30 layer_add_child(&window.layer, &hello_layer.layer);
31
32 }
$ ./waf configure
$ ./waf build
$ python -m SimpleHTTPServer 8000
$ ./waf configure
$ ./waf build
$ python -m SimpleHTTPServer 8000
Demo
PBW File
hello_world.pbw (zip archive)
app_resources.pbpack (binary)
manifest.json (txt/json)
pebble-app.bin (binary)
App Watch Face
Sports Apps
Event Handlers
On-screen Layers
Resources
Window Stack
View Lifecycle
load
appear
disappear
unload
viewDidLoad
viewWillAppear
viewDidAppear
viewWillDisappear
viewDidDisappear
Pebble iOS
Layers
Layers
10
Layers
20
10
Frame
Layers
20
20
Frame
Layers
-10
0
Bounds
Layers
60
20
Bounds
animation_init()
...
animation_schedule()
.update called
.update called
...
.update called
Animation scheduled
.stopped called
App Pebble OS
Animation
Animation stopped
.started called
Input Handlers
Resources
raw
png
png-trans
font
Debugging
app_log
vibes_short_pulse
vibes_double_pulse
vibes_long_pulse
light_enable_interaction
Watch <=> Phone
app_message_out_send() Dictionary
ACK.out_sent called
Accepted
app_message_out_send() Dictionary
NACK.out_failed called
Rejected
Pebble Phone
AppMessage
.in_received called Dictionary
ACK
Sending
Pebble Phone
AppMessage
.in_received called Dictionary
NACK
Sending
app_sync_set(...)
tuple_changed
Accepted
Sending
Pebble Phone
AppSync
190 - (void)setTargetWatch:(PBWatch*)watch {
191
192 self.watch = watch;
193
194 // Test if the Pebble's firmware supports AppMessages
195 [watch appMessagesGetIsSupported:
^(PBWatch *watch, BOOL isAppMessagesSupported) {
196
197 if (isAppMessagesSupported) {
198
199 // Configure communications channel to target the weather app:
200 uint8_t bytes[] = {
201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07,
202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98};
203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)];
204 [watch appMessagesSetUUID:uuid];
205
206 [self updateWatch];
207
208 }
209
210 }];
211 }
iOS
190 - (void)setTargetWatch:(PBWatch*)watch {
191
192 self.watch = watch;
193
194 // Test if the Pebble's firmware supports AppMessages
195 [watch appMessagesGetIsSupported:
^(PBWatch *watch, BOOL isAppMessagesSupported) {
196
197 if (isAppMessagesSupported) {
198
199 // Configure communications channel to target the weather app:
200 uint8_t bytes[] = {
201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07,
202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98};
203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)];
204 [watch appMessagesSetUUID:uuid];
205
206 [self updateWatch];
207
208 }
209
210 }];
211 }
iOS
190 - (void)setTargetWatch:(PBWatch*)watch {
191
192 self.watch = watch;
193
194 // Test if the Pebble's firmware supports AppMessages
195 [watch appMessagesGetIsSupported:
^(PBWatch *watch, BOOL isAppMessagesSupported) {
196
197 if (isAppMessagesSupported) {
198
199 // Configure communications channel to target the weather app:
200 uint8_t bytes[] = {
201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07,
202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98};
203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)];
204 [watch appMessagesSetUUID:uuid];
205
206 [self updateWatch];
207
208 }
209
210 }];
211 }
iOS
259 - (void)updateWatch {
260
261 NSDictionary *update = @{
262 kKeyWatchIcon:[NSNumber numberWithUint8:1],
263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”]
264 };
265
266 [self.watch appMessagesPushUpdate:update onSent:
^(PBWatch *watch, NSDictionary *update, NSError *error) {
267
268 if (error) {
269 // Message was not sent
270 } else {
271 // Message was sent
272 }
273
274 }];
275
276 }
iOS
259 - (void)updateWatch {
260
261 NSDictionary *update = @{
262 kKeyWatchIcon:[NSNumber numberWithUint8:1],
263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”]
264 };
265
266 [self.watch appMessagesPushUpdate:update onSent:
^(PBWatch *watch, NSDictionary *update, NSError *error) {
267
268 if (error) {
269 // Message was not sent
270 } else {
271 // Message was sent
272 }
273
274 }];
275
276 }
iOS
259 - (void)updateWatch {
260
261 NSDictionary *update = @{
262 kKeyWatchIcon:[NSNumber numberWithUint8:1],
263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”]
264 };
265
266 [self.watch appMessagesPushUpdate:update onSent:
^(PBWatch *watch, NSDictionary *update, NSError *error) {
267
268 if (error) {
269 // Message was not sent
270 } else {
271 // Message was sent
272 }
273
274 }];
275
276 }
iOS
296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message {
299
300 if ([message objectForKey:kKeyWatchRequestUpdate]) {
301 NSLog(@"Forecast update requested");
303 return YES;
304 }
305
306 return NO;
307
308 }
402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler:
^BOOL(PBWatch *watch, NSDictionary *update) {
403 return [self handleWatchUpdate:watch message:update];
404 }];
iOS
296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message {
299
300 if ([message objectForKey:kKeyWatchRequestUpdate]) {
301 NSLog(@"Forecast update requested");
303 return YES;
304 }
305
306 return NO;
307
308 }
402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler:
^BOOL(PBWatch *watch, NSDictionary *update) {
403 return [self handleWatchUpdate:watch message:update];
404 }];
iOS
296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message {
299
300 if ([message objectForKey:kKeyWatchRequestUpdate]) {
301 NSLog(@"Forecast update requested");
303 return YES;
304 }
305
306 return NO;
307
308 }
402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler:
^BOOL(PBWatch *watch, NSDictionary *update) {
403 return [self handleWatchUpdate:watch message:update];
404 }];
iOS
171 void pbl_main(void *params) {
172
173 PebbleAppHandlers handlers = {
174
175 .init_handler = &app_init,
176 .deinit_handler = &app_deinit,
177 .messaging_info = {
178 .buffer_sizes = {
179 .inbound = 64,
180 .outbound = 16,
181 }
182 },
183 // Handle time updates
184 .tick_info = {
185 .tick_handler = &handle_minute_tick,
186 .tick_units = MINUTE_UNIT
187 }
188 };
189
190 app_event_loop(params, &handlers);
191
192 }
Pebble
171 void pbl_main(void *params) {
172
173 PebbleAppHandlers handlers = {
174
175 .init_handler = &app_init,
176 .deinit_handler = &app_deinit,
177 .messaging_info = {
178 .buffer_sizes = {
179 .inbound = 64,
180 .outbound = 16,
181 }
182 },
183 // Handle time updates
184 .tick_info = {
185 .tick_handler = &handle_minute_tick,
186 .tick_units = MINUTE_UNIT
187 }
188 };
189
190 app_event_loop(params, &handlers);
191
192 }
Pebble
171 void pbl_main(void *params) {
172
173 PebbleAppHandlers handlers = {
174
175 .init_handler = &app_init,
176 .deinit_handler = &app_deinit,
177 .messaging_info = {
178 .buffer_sizes = {
179 .inbound = 64,
180 .outbound = 16,
181 }
182 },
183 // Handle time updates
184 .tick_info = {
185 .tick_handler = &handle_minute_tick,
186 .tick_units = MINUTE_UNIT
187 }
188 };
189
190 app_event_loop(params, &handlers);
191
192 }
Pebble
171 void pbl_main(void *params) {
172
173 PebbleAppHandlers handlers = {
174
175 .init_handler = &app_init,
176 .deinit_handler = &app_deinit,
177 .messaging_info = {
178 .buffer_sizes = {
179 .inbound = 64,
180 .outbound = 16,
181 }
182 },
183 // Handle time updates
184 .tick_info = {
185 .tick_handler = &handle_minute_tick,
186 .tick_units = MINUTE_UNIT
187 }
188 };
189
190 app_event_loop(params, &handlers);
191
192 }
Pebble
171 void pbl_main(void *params) {
172
173 PebbleAppHandlers handlers = {
174
175 .init_handler = &app_init,
176 .deinit_handler = &app_deinit,
177 .messaging_info = {
178 .buffer_sizes = {
179 .inbound = 64,
180 .outbound = 16,
181 }
182 },
183 // Handle time updates
184 .tick_info = {
185 .tick_handler = &handle_minute_tick,
186 .tick_units = MINUTE_UNIT
187 }
188 };
189
190 app_event_loop(params, &handlers);
191
192 }
Pebble
116 static void app_init(AppContextRef c) {
117
118 resource_init_current_app(&WEATHER_APP_RESOURCES);
119
120 Window* window = &s_data.window;
121 window_init(window, "PebbleWeather");
122 window_set_background_color(window, GColorBlack);
123 window_set_fullscreen(window, true);
124
...
149 // Watch <--> Phone communication
150 Tuplet initial_values[] = {
151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1),
152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"),
153 };
154 app_sync_init(&s_data.sync,
s_data.sync_buffer,
sizeof(s_data.sync_buffer),
initial_values,
ARRAY_LENGTH(initial_values),
sync_tuple_changed_callback, sync_error_callback, NULL);
155
156 window_stack_push(window, true);
157
168 }
Pebble
116 static void app_init(AppContextRef c) {
117
118 resource_init_current_app(&WEATHER_APP_RESOURCES);
119
120 Window* window = &s_data.window;
121 window_init(window, "PebbleWeather");
122 window_set_background_color(window, GColorBlack);
123 window_set_fullscreen(window, true);
124
...
149 // Watch <--> Phone communication
150 Tuplet initial_values[] = {
151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1),
152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"),
153 };
154 app_sync_init(&s_data.sync,
s_data.sync_buffer,
sizeof(s_data.sync_buffer),
initial_values,
ARRAY_LENGTH(initial_values),
sync_tuple_changed_callback, sync_error_callback, NULL);
155
156 window_stack_push(window, true);
157
168 }
Pebble
116 static void app_init(AppContextRef c) {
117
118 resource_init_current_app(&WEATHER_APP_RESOURCES);
119
120 Window* window = &s_data.window;
121 window_init(window, "PebbleWeather");
122 window_set_background_color(window, GColorBlack);
123 window_set_fullscreen(window, true);
124
...
149 // Watch <--> Phone communication
150 Tuplet initial_values[] = {
151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1),
152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"),
153 };
154 app_sync_init(&s_data.sync,
s_data.sync_buffer,
sizeof(s_data.sync_buffer),
initial_values,
ARRAY_LENGTH(initial_values),
sync_tuple_changed_callback, sync_error_callback, NULL);
155
156 window_stack_push(window, true);
157
168 }
Pebble
116 static void app_init(AppContextRef c) {
117
118 resource_init_current_app(&WEATHER_APP_RESOURCES);
119
120 Window* window = &s_data.window;
121 window_init(window, "PebbleWeather");
122 window_set_background_color(window, GColorBlack);
123 window_set_fullscreen(window, true);
124
...
149 // Watch <--> Phone communication
150 Tuplet initial_values[] = {
151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1),
152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"),
153 };
154 app_sync_init(&s_data.sync,
s_data.sync_buffer,
sizeof(s_data.sync_buffer),
initial_values,
ARRAY_LENGTH(initial_values),
sync_tuple_changed_callback, sync_error_callback, NULL);
155
156 window_stack_push(window, true);
157
168 }
Pebble
104 // Send message to phone asking for a weather update
105 void request_weather_update() {
106
107 vibes_double_pulse();
108
109 Tuplet values[] = {
110 TupletInteger(WEATHER_FORECAST_REQUEST_KEY, 1),
111 };
112 app_sync_set(&s_data.sync, values, ARRAY_LENGTH(values));
113
114 }
Pebble
104 // Send message to phone asking for a weather update
105 void request_weather_update() {
106
107 vibes_double_pulse();
108
109 Tuplet values[] = {
110 TupletInteger(WEATHER_FORECAST_REQUEST_KEY, 1),
111 };
112 app_sync_set(&s_data.sync, values, ARRAY_LENGTH(values));
113
114 }
Pebble
65 // Tuple changed
66 static void sync_tuple_changed_callback(
const uint32_t key,
const Tuple* new_tuple,
const Tuple* old_tuple,
void* context) {
67
68 switch (key) {
69 case WEATHER_ICON_KEY:
70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]);
71 bitmap_layer_set_bitmap(
&s_data.icon_layer,
&s_data.icon_bitmap.bmp
);
72 break;
73
74 case WEATHER_TEMPERATURE_KEY:
75 text_layer_set_text(
&s_data.temperature_layer,
new_tuple->value->cstring
);
76 break;
77
78 default:
79 return;
80 }
81 }
Pebble
65 // Tuple changed
66 static void sync_tuple_changed_callback(
const uint32_t key,
const Tuple* new_tuple,
const Tuple* old_tuple,
void* context) {
67
68 switch (key) {
69 case WEATHER_ICON_KEY:
70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]);
71 bitmap_layer_set_bitmap(
&s_data.icon_layer,
&s_data.icon_bitmap.bmp
);
72 break;
73
74 case WEATHER_TEMPERATURE_KEY:
75 text_layer_set_text(
&s_data.temperature_layer,
new_tuple->value->cstring
);
76 break;
77
78 default:
79 return;
80 }
81 }
Pebble
65 // Tuple changed
66 static void sync_tuple_changed_callback(
const uint32_t key,
const Tuple* new_tuple,
const Tuple* old_tuple,
void* context) {
67
68 switch (key) {
69 case WEATHER_ICON_KEY:
70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]);
71 bitmap_layer_set_bitmap(
&s_data.icon_layer,
&s_data.icon_bitmap.bmp
);
72 break;
73
74 case WEATHER_TEMPERATURE_KEY:
75 text_layer_set_text(
&s_data.temperature_layer,
new_tuple->value->cstring
);
76 break;
77
78 default:
79 return;
80 }
81 }
Pebble
☑ What is the Pebble
☑ Why you should develop for the Pebble
☑ How to develop for the Pebble
Agenda
Questions?
matthewmorey.com | @xzolian
Credits
Pictures
Pebble, Pebble Forums, Pebble SubReddit,
iFixIt, Wired, Verge, Lifehacker, BBC,
MyPebbleFaces, Kickstarter, indiegogo,
Wikipedia

Contenu connexe

Similaire à Pebble Watch iOS SDK Overview

Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
PL dream
 
1606015 m1 yamamoto
1606015 m1 yamamoto1606015 m1 yamamoto
1606015 m1 yamamoto
robo_lab
 
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NCAndroid Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
Jim Tochterman
 

Similaire à Pebble Watch iOS SDK Overview (20)

Øredev2013 - FirefoxOS - the platform HTML5 deserves
Øredev2013 - FirefoxOS - the platform HTML5 deservesØredev2013 - FirefoxOS - the platform HTML5 deserves
Øredev2013 - FirefoxOS - the platform HTML5 deserves
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
Platform agnostic information systems development
Platform agnostic information systems developmentPlatform agnostic information systems development
Platform agnostic information systems development
 
Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?Google's HTML5 Work: what's next?
Google's HTML5 Work: what's next?
 
Wt oep visiting card
Wt oep visiting cardWt oep visiting card
Wt oep visiting card
 
mobl
moblmobl
mobl
 
FGS 2011: Flash+ A Whole New Dimension for Games
FGS 2011: Flash+ A Whole New Dimension for GamesFGS 2011: Flash+ A Whole New Dimension for Games
FGS 2011: Flash+ A Whole New Dimension for Games
 
1606015 m1 yamamoto
1606015 m1 yamamoto1606015 m1 yamamoto
1606015 m1 yamamoto
 
jQuery Mobile & PhoneGap
jQuery Mobile & PhoneGapjQuery Mobile & PhoneGap
jQuery Mobile & PhoneGap
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with Wings
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?
 
Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5
 
Firefox OS - HTML5 for a truly world-wide-web
Firefox OS - HTML5 for a truly world-wide-webFirefox OS - HTML5 for a truly world-wide-web
Firefox OS - HTML5 for a truly world-wide-web
 
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NCAndroid Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
Android Development w/ ArcGIS Server - Esri Dev Meetup - Charlotte, NC
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
Firefox OS and the Internet of Things - NDC London 2014
Firefox OS and the Internet of Things - NDC London 2014Firefox OS and the Internet of Things - NDC London 2014
Firefox OS and the Internet of Things - NDC London 2014
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Html5 Overview
Html5 OverviewHtml5 Overview
Html5 Overview
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 

Pebble Watch iOS SDK Overview

  • 4.
  • 5. ☐ What is the Pebble ☐ Why you should develop for the Pebble ☐ How to develop for the Pebble Agenda
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12. vs
  • 13. ARM Cortex-M3 MCU 120 MHz Apple A6 ARMv7 1.3 GHz Dual Core 128 KB RAM Up to 8 apps 1 GB RAM Up to 64 GB storage 144 x 168 pixels 1-bit color “e-paper” 1,136 × 640 pixels 24-bit Color “Retina” Pebble iPhone 5 CPU Memory Screen
  • 14. Bluetooth 2.1 and 4.0 LE Bluetooth 4.0 802.11a/b/g/n Wi-Fi Cellular LTE 3-axis accelerometer Ambient light Magnetometer Three-axis gyro Accelerometer Proximity sensor Ambient light sensor 4 buttons Vibration Screen backlight Touch screen Buttons Vibration Camera Pebble iPhone 5 Comm. Sensors IO
  • 15. 2 to 14 days ~1 day FreeRTOS Pebble SDK PebbleKit iOS iOS SDK 5 ATM water resistance 22 mm watch band Not water resistant Can’t wear on wrist Pebble iPhone 5 Battery Software Other
  • 16.
  • 17.
  • 19. ☑ What is the Pebble ☐ Why you should develop for the Pebble ☐ How to develop for the Pebble Agenda
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42. “I agree to wear you around and share a lot of personal data with you.” - Customers
  • 43.
  • 44.
  • 45.
  • 46. $10,266,846 - Pebble Watch (design) $8,596,475 - OUYA (Android console) $5,702,153 - Veronica Mars (movie) $4,188,927 - Torment: Tides of Numenera (game) $3,986,929 - Project Eternity (game)
  • 49.
  • 50. iOS 7
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56. ☑ What is the Pebble ☑ Why you should develop for the Pebble ☐ How to develop for the Pebble Agenda
  • 58. 1. Pebble SDK dependencies 2. Pebble SDK 3. ARM dependencies 4. Pebble ARM toolchain Install
  • 59. Hello World $ create_pebble_project.py > PebbleSDK-1.12/Pebble/sdk > hello_world
  • 60. 1 #include "pebble_os.h" 2 #include "pebble_app.h" 3 #include "pebble_fonts.h" 4 5 #define MY_UUID { 6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49, 7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6, 8 0x50, 0x16 9 } 10 11 PBL_APP_INFO( 12 MY_UUID, 13 "Hello World", 14 "Acme Corp", 15 1, 0, /* App version */ 16 DEFAULT_MENU_ICON, 17 APP_INFO_STANDARD_APP 18 );
  • 61. 1 #include "pebble_os.h" 2 #include "pebble_app.h" 3 #include "pebble_fonts.h" 4 5 #define MY_UUID { 6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49, 7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6, 8 0x50, 0x16 9 } 10 11 PBL_APP_INFO( 12 MY_UUID, 13 "Hello World", 14 "Acme Corp", 15 1, 0, /* App version */ 16 DEFAULT_MENU_ICON, 17 APP_INFO_STANDARD_APP 18 );
  • 62. 1 #include "pebble_os.h" 2 #include "pebble_app.h" 3 #include "pebble_fonts.h" 4 5 #define MY_UUID { 6 0x20, 0xD9, 0xFB, 0x8F, 0xBE, 0xCF, 0x49, 7 0x94, 0xA9, 0xE8, 0x70, 0xC0, 0xEA, 0xC6, 8 0x50, 0x16 9 } 10 11 PBL_APP_INFO( 12 MY_UUID, 13 "Hello World", 14 "Acme Corp", 15 1, 0, /* App version */ 16 DEFAULT_MENU_ICON, 17 APP_INFO_STANDARD_APP 18 );
  • 63. 20 Window window; 21 22 void handle_init(AppContextRef ctx) { 23 window_init(&window, "Window Name"); 24 window_stack_push(&window,true/*Animated*/); 25 } 26 27 28 void pbl_main(void *params) { 29 PebbleAppHandlers handlers = { 30 .init_handler = &handle_init 31 }; 32 app_event_loop(params, &handlers); 33 }
  • 64. 20 Window window; 21 22 void handle_init(AppContextRef ctx) { 23 window_init(&window, "Window Name"); 24 window_stack_push(&window,true/*Animated*/); 25 } 26 27 28 void pbl_main(void *params) { 29 PebbleAppHandlers handlers = { 30 .init_handler = &handle_init 31 }; 32 app_event_loop(params, &handlers); 33 }
  • 65. 20 Window window; 21 22 void handle_init(AppContextRef ctx) { 23 window_init(&window, "Window Name"); 24 window_stack_push(&window,true/*Animated*/); 25 } 26 27 28 void pbl_main(void *params) { 29 PebbleAppHandlers handlers = { 30 .init_handler = &handle_init 31 }; 32 app_event_loop(params, &handlers); 33 }
  • 66. 20 Window window; 21 22 void handle_init(AppContextRef ctx) { 23 window_init(&window, "Window Name"); 24 window_stack_push(&window,true/*Animated*/); 25 } 26 27 28 void pbl_main(void *params) { 29 PebbleAppHandlers handlers = { 30 .init_handler = &handle_init 31 }; 32 app_event_loop(params, &handlers); 33 }
  • 67. 15 TextLayer hello_layer; 16 17 void handle_init(AppContextRef ctx) { 18 19 window_init(&window, "Window Name"); 20 window_stack_push(&window, true /* Animated */); 21 22 text_layer_init(&hello_layer, GRect(0, 65, 144, 30)); 23 text_layer_set_text_alignment(&hello_layer,GTextAlignmentCenter); 24 text_layer_set_text(&hello_layer, "Hello World!"); 25 text_layer_set_font( 26 &hello_layer, 27 fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21) 28 ); 29 30 layer_add_child(&window.layer, &hello_layer.layer); 31 32 }
  • 68. 15 TextLayer hello_layer; 16 17 void handle_init(AppContextRef ctx) { 18 19 window_init(&window, "Window Name"); 20 window_stack_push(&window, true /* Animated */); 21 22 text_layer_init(&hello_layer, GRect(0, 65, 144, 30)); 23 text_layer_set_text_alignment(&hello_layer,GTextAlignmentCenter); 24 text_layer_set_text(&hello_layer, "Hello World!"); 25 text_layer_set_font( 26 &hello_layer, 27 fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21) 28 ); 29 30 layer_add_child(&window.layer, &hello_layer.layer); 31 32 }
  • 69. $ ./waf configure $ ./waf build $ python -m SimpleHTTPServer 8000
  • 70. $ ./waf configure $ ./waf build $ python -m SimpleHTTPServer 8000
  • 71.
  • 72.
  • 73. Demo
  • 74.
  • 75.
  • 76. PBW File hello_world.pbw (zip archive) app_resources.pbpack (binary) manifest.json (txt/json) pebble-app.bin (binary)
  • 88. animation_init() ... animation_schedule() .update called .update called ... .update called Animation scheduled .stopped called App Pebble OS Animation Animation stopped .started called
  • 92.
  • 93.
  • 95.
  • 96. app_message_out_send() Dictionary ACK.out_sent called Accepted app_message_out_send() Dictionary NACK.out_failed called Rejected Pebble Phone AppMessage
  • 97. .in_received called Dictionary ACK Sending Pebble Phone AppMessage .in_received called Dictionary NACK Sending
  • 99.
  • 100.
  • 101.
  • 102. 190 - (void)setTargetWatch:(PBWatch*)watch { 191 192 self.watch = watch; 193 194 // Test if the Pebble's firmware supports AppMessages 195 [watch appMessagesGetIsSupported: ^(PBWatch *watch, BOOL isAppMessagesSupported) { 196 197 if (isAppMessagesSupported) { 198 199 // Configure communications channel to target the weather app: 200 uint8_t bytes[] = { 201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07, 202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98}; 203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)]; 204 [watch appMessagesSetUUID:uuid]; 205 206 [self updateWatch]; 207 208 } 209 210 }]; 211 } iOS
  • 103. 190 - (void)setTargetWatch:(PBWatch*)watch { 191 192 self.watch = watch; 193 194 // Test if the Pebble's firmware supports AppMessages 195 [watch appMessagesGetIsSupported: ^(PBWatch *watch, BOOL isAppMessagesSupported) { 196 197 if (isAppMessagesSupported) { 198 199 // Configure communications channel to target the weather app: 200 uint8_t bytes[] = { 201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07, 202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98}; 203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)]; 204 [watch appMessagesSetUUID:uuid]; 205 206 [self updateWatch]; 207 208 } 209 210 }]; 211 } iOS
  • 104. 190 - (void)setTargetWatch:(PBWatch*)watch { 191 192 self.watch = watch; 193 194 // Test if the Pebble's firmware supports AppMessages 195 [watch appMessagesGetIsSupported: ^(PBWatch *watch, BOOL isAppMessagesSupported) { 196 197 if (isAppMessagesSupported) { 198 199 // Configure communications channel to target the weather app: 200 uint8_t bytes[] = { 201 0x42, 0xc8, 0x6e, 0xa4, 0x1c, 0x3e, 0x4a, 0x07, 202 0xb8, 0x89, 0x2c, 0xcc, 0xca, 0x91, 0x41, 0x98}; 203 NSData *uuid = [NSData dataWithBytes:bytes length:sizeof(bytes)]; 204 [watch appMessagesSetUUID:uuid]; 205 206 [self updateWatch]; 207 208 } 209 210 }]; 211 } iOS
  • 105. 259 - (void)updateWatch { 260 261 NSDictionary *update = @{ 262 kKeyWatchIcon:[NSNumber numberWithUint8:1], 263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”] 264 }; 265 266 [self.watch appMessagesPushUpdate:update onSent: ^(PBWatch *watch, NSDictionary *update, NSError *error) { 267 268 if (error) { 269 // Message was not sent 270 } else { 271 // Message was sent 272 } 273 274 }]; 275 276 } iOS
  • 106. 259 - (void)updateWatch { 260 261 NSDictionary *update = @{ 262 kKeyWatchIcon:[NSNumber numberWithUint8:1], 263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”] 264 }; 265 266 [self.watch appMessagesPushUpdate:update onSent: ^(PBWatch *watch, NSDictionary *update, NSError *error) { 267 268 if (error) { 269 // Message was not sent 270 } else { 271 // Message was sent 272 } 273 274 }]; 275 276 } iOS
  • 107. 259 - (void)updateWatch { 260 261 NSDictionary *update = @{ 262 kKeyWatchIcon:[NSNumber numberWithUint8:1], 263 kKeyWatchTemperature:[NSString stringWithFormat:@"%.1f u00B0F", @”90”] 264 }; 265 266 [self.watch appMessagesPushUpdate:update onSent: ^(PBWatch *watch, NSDictionary *update, NSError *error) { 267 268 if (error) { 269 // Message was not sent 270 } else { 271 // Message was sent 272 } 273 274 }]; 275 276 } iOS
  • 108. 296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message { 299 300 if ([message objectForKey:kKeyWatchRequestUpdate]) { 301 NSLog(@"Forecast update requested"); 303 return YES; 304 } 305 306 return NO; 307 308 } 402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler: ^BOOL(PBWatch *watch, NSDictionary *update) { 403 return [self handleWatchUpdate:watch message:update]; 404 }]; iOS
  • 109. 296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message { 299 300 if ([message objectForKey:kKeyWatchRequestUpdate]) { 301 NSLog(@"Forecast update requested"); 303 return YES; 304 } 305 306 return NO; 307 308 } 402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler: ^BOOL(PBWatch *watch, NSDictionary *update) { 403 return [self handleWatchUpdate:watch message:update]; 404 }]; iOS
  • 110. 296 - (BOOL)handleWatchUpdate:(PBWatch *)watch message:(NSDictionary *)message { 299 300 if ([message objectForKey:kKeyWatchRequestUpdate]) { 301 NSLog(@"Forecast update requested"); 303 return YES; 304 } 305 306 return NO; 307 308 } 402 self.updateHandler = [self.watch appMessagesAddReceiveUpdateHandler: ^BOOL(PBWatch *watch, NSDictionary *update) { 403 return [self handleWatchUpdate:watch message:update]; 404 }]; iOS
  • 111.
  • 112. 171 void pbl_main(void *params) { 172 173 PebbleAppHandlers handlers = { 174 175 .init_handler = &app_init, 176 .deinit_handler = &app_deinit, 177 .messaging_info = { 178 .buffer_sizes = { 179 .inbound = 64, 180 .outbound = 16, 181 } 182 }, 183 // Handle time updates 184 .tick_info = { 185 .tick_handler = &handle_minute_tick, 186 .tick_units = MINUTE_UNIT 187 } 188 }; 189 190 app_event_loop(params, &handlers); 191 192 } Pebble
  • 113. 171 void pbl_main(void *params) { 172 173 PebbleAppHandlers handlers = { 174 175 .init_handler = &app_init, 176 .deinit_handler = &app_deinit, 177 .messaging_info = { 178 .buffer_sizes = { 179 .inbound = 64, 180 .outbound = 16, 181 } 182 }, 183 // Handle time updates 184 .tick_info = { 185 .tick_handler = &handle_minute_tick, 186 .tick_units = MINUTE_UNIT 187 } 188 }; 189 190 app_event_loop(params, &handlers); 191 192 } Pebble
  • 114. 171 void pbl_main(void *params) { 172 173 PebbleAppHandlers handlers = { 174 175 .init_handler = &app_init, 176 .deinit_handler = &app_deinit, 177 .messaging_info = { 178 .buffer_sizes = { 179 .inbound = 64, 180 .outbound = 16, 181 } 182 }, 183 // Handle time updates 184 .tick_info = { 185 .tick_handler = &handle_minute_tick, 186 .tick_units = MINUTE_UNIT 187 } 188 }; 189 190 app_event_loop(params, &handlers); 191 192 } Pebble
  • 115. 171 void pbl_main(void *params) { 172 173 PebbleAppHandlers handlers = { 174 175 .init_handler = &app_init, 176 .deinit_handler = &app_deinit, 177 .messaging_info = { 178 .buffer_sizes = { 179 .inbound = 64, 180 .outbound = 16, 181 } 182 }, 183 // Handle time updates 184 .tick_info = { 185 .tick_handler = &handle_minute_tick, 186 .tick_units = MINUTE_UNIT 187 } 188 }; 189 190 app_event_loop(params, &handlers); 191 192 } Pebble
  • 116. 171 void pbl_main(void *params) { 172 173 PebbleAppHandlers handlers = { 174 175 .init_handler = &app_init, 176 .deinit_handler = &app_deinit, 177 .messaging_info = { 178 .buffer_sizes = { 179 .inbound = 64, 180 .outbound = 16, 181 } 182 }, 183 // Handle time updates 184 .tick_info = { 185 .tick_handler = &handle_minute_tick, 186 .tick_units = MINUTE_UNIT 187 } 188 }; 189 190 app_event_loop(params, &handlers); 191 192 } Pebble
  • 117. 116 static void app_init(AppContextRef c) { 117 118 resource_init_current_app(&WEATHER_APP_RESOURCES); 119 120 Window* window = &s_data.window; 121 window_init(window, "PebbleWeather"); 122 window_set_background_color(window, GColorBlack); 123 window_set_fullscreen(window, true); 124 ... 149 // Watch <--> Phone communication 150 Tuplet initial_values[] = { 151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), 152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"), 153 }; 154 app_sync_init(&s_data.sync, s_data.sync_buffer, sizeof(s_data.sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL); 155 156 window_stack_push(window, true); 157 168 } Pebble
  • 118. 116 static void app_init(AppContextRef c) { 117 118 resource_init_current_app(&WEATHER_APP_RESOURCES); 119 120 Window* window = &s_data.window; 121 window_init(window, "PebbleWeather"); 122 window_set_background_color(window, GColorBlack); 123 window_set_fullscreen(window, true); 124 ... 149 // Watch <--> Phone communication 150 Tuplet initial_values[] = { 151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), 152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"), 153 }; 154 app_sync_init(&s_data.sync, s_data.sync_buffer, sizeof(s_data.sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL); 155 156 window_stack_push(window, true); 157 168 } Pebble
  • 119. 116 static void app_init(AppContextRef c) { 117 118 resource_init_current_app(&WEATHER_APP_RESOURCES); 119 120 Window* window = &s_data.window; 121 window_init(window, "PebbleWeather"); 122 window_set_background_color(window, GColorBlack); 123 window_set_fullscreen(window, true); 124 ... 149 // Watch <--> Phone communication 150 Tuplet initial_values[] = { 151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), 152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"), 153 }; 154 app_sync_init(&s_data.sync, s_data.sync_buffer, sizeof(s_data.sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL); 155 156 window_stack_push(window, true); 157 168 } Pebble
  • 120. 116 static void app_init(AppContextRef c) { 117 118 resource_init_current_app(&WEATHER_APP_RESOURCES); 119 120 Window* window = &s_data.window; 121 window_init(window, "PebbleWeather"); 122 window_set_background_color(window, GColorBlack); 123 window_set_fullscreen(window, true); 124 ... 149 // Watch <--> Phone communication 150 Tuplet initial_values[] = { 151 TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), 152 TupletCString(WEATHER_TEMPERATURE_KEY, "-u00B0C"), 153 }; 154 app_sync_init(&s_data.sync, s_data.sync_buffer, sizeof(s_data.sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL); 155 156 window_stack_push(window, true); 157 168 } Pebble
  • 121. 104 // Send message to phone asking for a weather update 105 void request_weather_update() { 106 107 vibes_double_pulse(); 108 109 Tuplet values[] = { 110 TupletInteger(WEATHER_FORECAST_REQUEST_KEY, 1), 111 }; 112 app_sync_set(&s_data.sync, values, ARRAY_LENGTH(values)); 113 114 } Pebble
  • 122. 104 // Send message to phone asking for a weather update 105 void request_weather_update() { 106 107 vibes_double_pulse(); 108 109 Tuplet values[] = { 110 TupletInteger(WEATHER_FORECAST_REQUEST_KEY, 1), 111 }; 112 app_sync_set(&s_data.sync, values, ARRAY_LENGTH(values)); 113 114 } Pebble
  • 123. 65 // Tuple changed 66 static void sync_tuple_changed_callback( const uint32_t key, const Tuple* new_tuple, const Tuple* old_tuple, void* context) { 67 68 switch (key) { 69 case WEATHER_ICON_KEY: 70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]); 71 bitmap_layer_set_bitmap( &s_data.icon_layer, &s_data.icon_bitmap.bmp ); 72 break; 73 74 case WEATHER_TEMPERATURE_KEY: 75 text_layer_set_text( &s_data.temperature_layer, new_tuple->value->cstring ); 76 break; 77 78 default: 79 return; 80 } 81 } Pebble
  • 124. 65 // Tuple changed 66 static void sync_tuple_changed_callback( const uint32_t key, const Tuple* new_tuple, const Tuple* old_tuple, void* context) { 67 68 switch (key) { 69 case WEATHER_ICON_KEY: 70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]); 71 bitmap_layer_set_bitmap( &s_data.icon_layer, &s_data.icon_bitmap.bmp ); 72 break; 73 74 case WEATHER_TEMPERATURE_KEY: 75 text_layer_set_text( &s_data.temperature_layer, new_tuple->value->cstring ); 76 break; 77 78 default: 79 return; 80 } 81 } Pebble
  • 125. 65 // Tuple changed 66 static void sync_tuple_changed_callback( const uint32_t key, const Tuple* new_tuple, const Tuple* old_tuple, void* context) { 67 68 switch (key) { 69 case WEATHER_ICON_KEY: 70 load_bitmap(WEATHER_ICONS[new_tuple->value->uint8]); 71 bitmap_layer_set_bitmap( &s_data.icon_layer, &s_data.icon_bitmap.bmp ); 72 break; 73 74 case WEATHER_TEMPERATURE_KEY: 75 text_layer_set_text( &s_data.temperature_layer, new_tuple->value->cstring ); 76 break; 77 78 default: 79 return; 80 } 81 } Pebble
  • 126. ☑ What is the Pebble ☑ Why you should develop for the Pebble ☑ How to develop for the Pebble Agenda
  • 128. Credits Pictures Pebble, Pebble Forums, Pebble SubReddit, iFixIt, Wired, Verge, Lifehacker, BBC, MyPebbleFaces, Kickstarter, indiegogo, Wikipedia