Watchkit Communication

Watchkit Communication

Video of the talk is available at https://vimeo.com/119606531

The Watchkit architecture makes for some interesting challenges regarding getting data out of your main app and onto the watch. This covers the architectural and lifecycle basics before diving into the methods we have available to move data around to the watch.

9b54e5324785eb939bcc8f15c724baf9?s=128

Curtis Herbert

February 12, 2015
Tweet

Transcript

  1. Curtis Herbert (.com) @parrots WatchKit Communication

  2. What can we do in early 2015? Glance Notification App

    https://developer.apple.com/watchkit/
  3. What can we do in early 2015? Glance Notification App

    https://developer.apple.com/watchkit/ You can provide users with timely read-only information that they care about with a Glance — a quick and lightweight view of your app.
  4. What can we do in early 2015? Glance Notification App

    https://developer.apple.com/watchkit/ Actionable notifications built and designed with WatchKit let users take action right from their wrists.
  5. What can we do in early 2015? Glance Notification App

    https://developer.apple.com/watchkit/ Your app on Apple Watch contains a full user interface. Users can launch, control, and interact with your app in ways unique to Apple Watch.
  6. What Makes Up a WatchKit App?

  7. Parent App Delivered with your app

  8. Parent App E Watch Extension Delivered with your app

  9. Parent App E Watch Extension Just the UI Watch “App”

    Delivered with your app
  10. Parent App E Watch Extension Just the UI Watch “App”

    Delivered with your app
  11. None
  12. None
  13. None
  14. Parent App E Watch Extension Separate processes

  15. Parent App E Watch Extension Separate processes

  16. Parent App E Watch Extension setters getters ui events Bluetooth

  17. Parent App E Watch Extension App can’t wake extension

  18. Watchkit app made of 2 parts - “App” and extension

    Extension <-> watch app is a lightweight channel Extension <-> parent app can only be started by the extension Architectural Takeaways
  19. A WatchKit App Lifecycle

  20. E Watch Extension Initial Launch Watch “App” User launches app

    Load storyboard init awakeWithContext: Show UI willActivate
  21. E Watch Extension Interaction willActivate didDeactivate …various UI-triggered actions…

  22. E Watch Extension Interaction willActivate didDeactivate …various UI-triggered actions…

  23. E Watch Extension Interaction willActivate didDeactivate …various UI-triggered actions…

  24. Stay lightweight in watch extension, especially init and awake UI

    updates when screen isn’t active are dropped on the floor Lifecycle Takeaways
  25. Communication

  26. openParentApplication:reply:

  27. Polo! Marco?

  28. [WKInterfaceController openParentApplication:@{...} reply:^(NSDictionary *replyInfo, NSError *error) { if (error) {

    NSLog(@"Error from parent: %@", error); } else { //do something with the reply info.... } }]; E Any WKInterfaceController
  29. - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply { reply(@{...}); }

    AppDelegate
  30. openParentApplication:reply: • Will launch your parent app! • Great way

    to send actions / triggers Pros • Can’t do too many back-to-back (serialized queue) • Launches parent in background mode-only • Have fun with your app lifecycle Cons
  31. App Group & NSUserDefaults

  32. Parent App E iOS 8 Extension Extension data sharing ex:

    “com.consumedbycode.slopes.group” App groups x
  33. Parent App E iOS 8 Extension Extension data sharing ex:

    “com.consumedbycode.slopes.group” App groups x
  34. Parent App E iOS 8 Extension Extension data sharing ex:

    “com.consumedbycode.slopes.group” App groups x
  35. Anywhere NSUserDefaults *defaults = [NSUserDefaults initWithSuite:@“my.group.name”]; [defaults setInteger:4 forKey@"myKey"]; [defaults

    synchronize];
  36. NSUserDefaults *defaults = [NSUserDefaults initWithSuite:@“my.group.name"]; NSInteger myInt = [defaults integerForKey@"myKey"];

    E Anywhere
  37. initWithSuite is separate from standardUserDefaults

  38. NSUserDefaults • Simple API to serialize and read data Pros

    • No KVO Cons
  39. App Groups & Core Data

  40. NSURL *directory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *storeURL

    = [directory URLByAppendingPathComponent:@“myApp.sqlite"]; //init persistent store, etc..
  41. Anywhere NSURL *directory = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@“ my.group.name”]; NSURL *storeURL

    = [directory URLByAppendingPathComponent:@“myApp.sqlite"]; //init persistent store, etc.. E
  42. Core Data • Reuse existing model • Set up for

    multi-threading • KVO Pros • Core Data (I kid, I kid) • Bad place to store one-off values to pass around • Need to move DB to App Group container Cons
  43. App Groups & Darwin Notification Center

  44. pod ‘MMWormhole’

  45. Anywhere MMWormhole *wormhole = [[MMWormhole alloc] initWithApplicationGroupIdentifier:@"my.group.name" optionalDirectory:@"wormhole"]; //whenever the

    data changes… [wormhole passMessageObject:@(5.5) identifier:@"currentSpeed"]; E
  46. Anywhere //get the current value NSNumber *currentSpeed = [wormhole messageWithIdentifier:@"currentSpeed"];

    //...or subscribe for updates [wormhole listenForMessageWithIdentifier:@"currentSpeed" listener:^(id messageObject) { //do something with the speed }]; E
  47. Anywhere [wormhole stopListeningForMessageWithIdentifier:@"currentSpeed"]; E

  48. WKInterfaceController - (void)willActivate { [super willActivate]; [self.wormhole listenForMessageWithIdentifier:@"currentSpeed" listener:^(id messageObject)

    { //do something with the speed, update a label, etc }]; } - (void)didDeactivate { [super didDeactivate]; [self.wormhole stopListeningForMessageWithIdentifier:@"currentSpeed"]; } E
  49. MMWormhole • KVO • Great for one-off values Pros •

    Separate data you have to keep in sync from your model layer Cons
  50. openParentApplication:reply: great for actions, bad for lots of data fetching

    NSUserDefaults: great for data, but no notification of changes CoreData: great for sharing existing model data, bad for one-off messages Darwin Notification Center: consider in place of NSUserDefaults Communication Takeaways
  51. Demo time

  52. https://developer.apple.com/watchkit/ https://github.com/mutualmobile/MMWormhole http://infinitapps.com/bezel/ Resources