Native watch apps and third-party complications

Native watch apps and third-party complications

Let's take a practical look at Apple's newest development platform watchOS, by implementing a GitHub streak custom complication and a native Spotify watch app.

9d2ea021919ff81e02d48530aae191bd?s=128

Boris Bügling

July 20, 2015
Tweet

Transcript

  1. BUILDING WATCHOS APPS SWIFT.BERLIN, JULY 2015 BORIS BÜGLING - @NEONACHO

  2. COCOAPODS

  3. CONTENTFUL

  4. None
  5. !!!!

  6. ᴡᴀᴛᴄʜ

  7. WATCHOS 1.X ▸ Notifications ▸ Glances ▸ WatchKit apps

  8. NOTIFICATIONS

  9. GLANCES

  10. WATCHKIT

  11. WATCHOS 2.X ▸ Apps run natively on the watch ▸

    Custom complications
  12. !!!

  13. None
  14. COMPLICATIONS

  15. ARCHITECTURE

  16. None
  17. WATCHOS 2 Extension phone => watch

  18. RESOURCES ▸ Interface.storyboard ▸ Asset catalogs

  19. EXTENSION DELEGATE class ExtensionDelegate: NSObject, WKExtensionDelegate { func applicationDidFinishLaunching() {

    } func applicationDidBecomeActive() { } func applicationWillResignActive() { } }
  20. INTERFACE CONTROLLER class InterfaceController: WKInterfaceController { override func awakeWithContext(context: AnyObject?)

    { super.awakeWithContext(context) } override func willActivate() { super.willActivate() } override func didDeactivate() { super.didDeactivate() } }
  21. WKINTERFACECONTROLLER ▸ Navigation ▸ Presentation ▸ Handoff ▸ Handle notification

    actions ▸ Communicate with parent app
  22. CLKCOMPLICATIONFAMILY enum CLKComplicationFamily : Int { case ModularSmall case ModularLarge

    case UtilitarianSmall case UtilitarianLarge case CircularSmall }
  23. CLKCOMPLICATIONTIMELINEENTRY class CLKComplicationTimelineEntry : NSObject { var date: NSDate @NSCopying

    var complicationTemplate: CLKComplicationTemplate }
  24. CLKCOMPLICATIONTEMPLATE The CLKComplicationTemplate class is a base class for specifying

    the arrangement of data in your custom watch complication.
  25. CLKCOMPLICATIONTEMPLATECIRCULARSMALLRIN GIMAGE

  26. CLKCOMPLICATIONTEMPLATECIRCULARSMALLSI MPLEIMAGE

  27. ...

  28. DESIGN

  29. If you measure interactions with your iOS app in minutes,

    you can expect interactions with your Watch app to be measured in seconds.
  30. PRINCIPLES ▸ Lightweight interactions ▸ Holistic design ▸ Personal communication

  31. LAYOUT ▸ based on horizontal or vertical groups ▸ very

    similar to UIStackView ▸ two device sizes (38mm and 42mm) ▸ edge-to-edge, bezel provides margins
  32. None
  33. SOME EXAMPLES

  34. None
  35. None
  36. None
  37. None
  38. BUILDING A SIMPLE APP

  39. None
  40. WATCHPRESENTER ▸ Remote controls Deckset instead ▸ Direct connection to

    the Mac ▸ Shows a preview of the slides ▸ Measures heartrate to display the "most exciting" slide ▸ Taps you if you're running out of time
  41. MULTIPEER CONNECTIVITY!

  42. AVAILABLE FRAMEWORKS

  43. CFNetwork.framework ClockKit.framework Contacts.framework CoreData.framework CoreFoundation.framework CoreGraphics.framework CoreLocation.framework CoreMotion.framework EventKit.framework Foundation.framework

  44. HealthKit.framework HomeKit.framework ImageIO.framework MapKit.framework MobileCoreServices.framework PassKit.framework Security.framework UIKit.framework WatchConnectivity.framework WatchKit.framework

  45. BT APIS ARE PRIVATE :(

  46. OTHER OPTIONS ▸ NSURLSession via Wi-Fi ▸ WatchConnectivity.framework to talk

    via the phone
  47. HEALTHKIT.FRAMEWORK let anchorValue = Int(HKAnchoredObjectQueryNoAnchor) let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) let

    heartRateQuery = HKAnchoredObjectQuery(type: sampleType!, predicate: nil, anchor: anchorValue, limit: 0) { (query, sampleObjects, deletedObjects, newAnchor, error) -> Void in guard let heartRateSamples = sampleObjects as?[HKQuantitySample] else {return} let sample = heartRateSamples.first let value = sample!.quantity.doubleValueForUnit(self.heartRateUnit) print(value) } heartRateQuery.updateHandler = // ...
  48. None
  49. HEALTHKIT.FRAMEWORK ▸ not usable in the Watch simulator

  50. TAPTIC ENGINE typedef NS_ENUM(NSInteger, WKHapticType) { WKHapticTypeNotification, WKHapticTypeDirectionUp, WKHapticTypeDirectionDown, WKHapticTypeSuccess,

    WKHapticTypeFailure, WKHapticTypeRetry, WKHapticTypeStart, WKHapticTypeStop, WKHapticTypeClick } WK_AVAILABLE_WATCHOS_ONLY(2.0); WKInterfaceDevice.currentDevice().playHaptic(.Start)
  51. BUT ALSO NOT USABLE IN THE SIM

  52. SPOTIFY REMOTE

  53. DEMO

  54. None
  55. None
  56. None
  57. None
  58. TIPS

  59. printf DEBUGGING IS GREAT!

  60. MMWORMHOLE ▸ watchOS 1.0: CFNotificationCenter ▸ watchOS 2.0: WatchConnectivity.framework

  61. FORCE QUIT APPS ▸ Long press until "reboot" menu ▸

    Long press again
  62. IF IN DOUBT, REBOOT THE WATCH :)

  63. WHAT HAVE WE LEARNED? ▸ Code isn't very different from

    iOS apps ▸ But design very much is ▸ Rethink your app for the watch, don't port it ▸ If you can't - maybe you don't need a watch app
  64. Don’t be afraid to not ship. @orta

  65. THANK YOU!

  66. ▸ https://developer.apple.com/watch/human-interface-guidelines/ ▸ https://developer.apple.com/library/prerelease/watchos/ documentation/General/Conceptual/AppleWatch2TransitionGuide/ ▸ https://github.com/shu223/watchOS-2-Sampler ▸ http://www.kristinathai.com/category/watchkit/ ▸

    https://realm.io/news/watchkit-mistakes/
  67. @NeoNacho boris@contentful.com http://buegling.com/talks