how to build a compelling apple watch app

63
HOW TO BUILD A COMPELLING WATCH APP KRISTINA THAI @kristinathai

Upload: kristina-thai

Post on 20-Jan-2017

1.417 views

Category:

Software


1 download

TRANSCRIPT

  • HOW TO BUILD A COMPELLING WATCH APP

    KRISTINA THAI

    @kristinathai

  • @kristinathaiHI. IM KRISTINA

  • HOW TO BUILD A COMPELLING WATCH APP

    KRISTINA THAI

  • HOW TO BUILD A COMPELLING WATCH APP

  • COMPELLINGevoking interest, attention, or admiration in a powerfully irresistible way

  • 1. FIND A GOOD USE CASEOr dont build one at all.

  • @kristinathai

  • @kristinathai

  • @kristinathai

    THEY'RE LIKE DIET VERSIONS OF THE FULL SMARTPHONE APP, AND THEY MAKE NO SENSE ON THE WATCH.

    Steve Kovach

    APPLE WATCH APPS ARE BAD - BUSINESS INSIDER

    businessinsider.com/apple-watch-apps-are-bad-2015-5

    http://businessinsider.com/apple-watch-apps-are-bad-2015-5

  • @kristinathai

  • 2. USE ANIMATIONS

  • @kristinathai

    Simple Designs

  • @kristinathai

  • @kristinathai

  • @kristinathai

  • @kristinathai

    @IBOutlet var spacerGroup: WKInterfaceGroup! @IBAction func animate() { animateWithDuration(0.3, animations: { self.spacerGroup.setWidth(0) }) }

    @IBAction func reset() { self.spacerGroup.setWidth(100) }

  • @kristinathai

  • @kristinathai @IBOutlet var animateButton: WKInterfaceButton! @IBOutlet var buttonSpacerGroup: WKInterfaceGroup! var buttonMoved: Bool!

    @IBAction func animateMovingButton() { if (buttonMoved != true) { animateWithDuration(0.3, animations: { self.buttonSpacerGroup.setHeight(100) }) buttonMoved = true animateButton.setTitle("Reset") } else { animateWithDuration(0.3, animations: { self.buttonSpacerGroup.setHeight(0) }) buttonMoved = false animateButton.setTitle("Animate!") } }

  • 3. DICTATION IS KEY

  • @kristinathai

    http://www.imore.com/apple-watch-usage-survey-study-2015-q2

  • @kristinathai

  • @kristinathai

    let suggestions = ["Hello", "Self", "Conference"] presentTextInputControllerWithSuggestions(suggestions, allowedInputMode: .AllowEmoji)

    { (input) -> Void in if let userInput = input?.first { // Do something with user input here self.contentLabel.setText(userInput as? String) } }

  • @kristinathai

    presentTextInputControllerWithSuggestions(nil, allowedInputMode: .Plain)

    { (input) -> Void in if let userInput = input?.first { // Do something with user input here self.contentLabel.setText(userInput as? String) } }

  • 4. DEVICE-TO-DEVICE COMMUNICATION

  • WATCH CONNECTIVITY

  • @kristinathaiWATCH CONNECTIVITY

    WCSESSION

    Facilitates communication between WatchKit extension & companion iOS app

    Needs to be configured on both devices

  • @kristinathaiWATCH CONNECTIVITY

    WCSESSION CONFIGURATIONimport WatchConnectivity

    class InterfaceController: WKInterfaceController, WCSessionDelegate {

    }

    private let session : WCSession? = WCSession.isSupported() ? WCSession.defaultSession() : nil

    override init() { super.init() session?.delegate = self session?.activateSession() }

  • @kristinathaiWATCH CONNECTIVITY

    SENDER AND RECEIVER

    applicationData

  • @kristinathaiWATCH CONNECTIVITY

    SENDER AND RECEIVER

    applicationDatatransferUserInfo( )

  • @kristinathaiWATCH CONNECTIVITY

    SENDER AND RECEIVER

    applicationDatatransferUserInfo( ) didReceiveUserInfo( )

    transferUserInfo( ) didReceiveUserInfo(

    applicationData)

  • @kristinathaiWATCH CONNECTIVITY

    COMMUNICATION CATEGORIES

    Background transfers Interactive messaging

    Information isnt needed immediately

    Information needed immediately

    Operating system determines the most suitable time to send

    the data

    Requires reachable state

    Content is queued for transfer

  • @kristinathaiWATCH CONNECTIVITY

    SENDER AND RECEIVERS - BACKGROUND TRANSFERS

    Data Type Sender Receiver

    Dictionary (overwrite latest data) updateApplicationContext didReceiveApplicationContext

    Dictionary (keep all data - FIFO) transferUserInfo didReceiveUserInfo

    File, Dictionary (metadata) transferFile didReceiveFile

  • @kristinathaiWATCH CONNECTIVITY

    SENDER AND RECEIVERS - INTERACTIVE MESSAGING

    Data Type Sender Receiver

    Dictionary sendMessage didReceiveMessage

    NSData sendMessageData didReceiveMessageData

  • 5. CLOCKKIT

  • COMPLICATIONSCLOCKKIT

  • @kristinathai

  • @kristinathai

  • @kristinathai

    https://theswiftdev.com/2016/04/28/clockkit-complications-cheat-sheet/

    CLKComplicationTemplate

  • @kristinathai

  • @kristinathai

  • @kristinathaiCLOCKKIT

    TEXT PROVIDERS

    Smartly truncate & display text in watch complications

    Available for most data types

  • @kristinathaiCLOCKKIT - TEXT PROVIDERS

    CLKSimpleTextProvider

    let textProvider =

    CLKSimpleTextProvider(text: "your string here", shortText: "string")

  • @kristinathaiCLOCKKIT - TEXT PROVIDERS

    CLKDateTextProviderThursday, January 14, 2016

    Thursday, January 14

    Thursday, Jan 14

    Thurs, Jan 14

    Jan 14

    14

    let textProvider = CLKDateTextProvider(date: NSDate(), units: .Day)

  • @kristinathaiCLOCKKIT - TEXT PROVIDERS

    CLKTextProvider - Custom text provider

    CLKSimpleTextProvider *textProvider1 = [CLKSimpleTextProvider textProviderWithText:@"your string here" shortText:@"string"];

    CLKTextProvider *textProvider = [CLKTextProvider textProviderWithFormat:@"%@ & %@", textProvider1, textProvider2];

    CLKSimpleTextProvider *textProvider2 = [CLKSimpleTextProvider textProviderWithText:@"your string here" shortText:@"string"];

  • DATA POPULATIONCLOCKKIT

  • @kristinathaiCOMPLICATION TIMELINE

    https://developer.apple.com/videos/play/wwdc2015/209/

  • @kristinathai

  • @kristinathai

    // MARK: - Timeline Population

    func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) {

    // Call the handler with the current timeline entry

    handler(nil)

    }

    1: CURRENT TIMELINE ENTRY

  • @kristinathai

    func getTimelineEntriesForComplication(complication: CLKComplication, beforeDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {

    // Call the handler with the timeline entries prior to the given date

    handler(nil)

    }

    2: PREVIOUS TIMELINE ENTRIES

  • @kristinathai

    func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {

    // Call the handler with the timeline entries after to the given date

    handler(nil)

    }

    3: LATER TIMELINE ENTRIES

  • @kristinathai

    // MARK: - Timeline Population

    func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) {

    // Call the handler with the current timeline entry

    handler(nil)

    }

    1: CURRENT TIMELINE ENTRY

  • FETCH NEW DATACLOCKKIT

  • @kristinathai

    func getNextRequestedUpdateDateWithHandler(handler: (NSDate?) -> Void) {

    // Call the handler with the date when you would next like to be given the opportunity to update your complication content

    handler(nil);

    }

    May be unreliable to give you the date that you want

    May exhaust your limited update budget

  • @kristinathaiIN YOUR MAIN IOS PARENT APP

    BACKGROUND FETCH

    func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {

    // use Watch Connectivity to transfer data back to watch in here getUpdatedWatchComplicationData()

    completionHandler(UIBackgroundFetchResult.NewData)

    }

  • 6. ACCESSIBILITY = INCLUSIVITY

  • @kristinathai

    15% OF THE WORLDS POPULATION LIVES WITH SOME FORM OF DISABILITY

    World Health Organization

    WORLD REPORT ON DISABILITY

    http://www.who.int/disabilities/world_report/2011/report/en/

  • @kristinathai

    https://twitter.com/dstorey/status/649636741033279488

  • @kristinathai

  • @kristinathai

    @IBOutlet var userInputButton: WKInterfaceButton! override func awakeWithContext(context: AnyObject?) { super.awakeWithContext(context) // Configure interface objects here. userInputButton.setAccessibilityLabel("Take user input") userInputButton.setAccessibilityHint("Open dictation") }

  • @kristinathaiRESOURCES

    ANIMATIONS & DICTATION

    http://kristina.io/watchos-2-tutorial-animations-using-groups/

    http://natashatherobot.com/watchkit-text-input-dictation-api/

    http://develop.watch/text-input-in-watchkit/

    http://kristina.io/watchos-2-tutorial-animations-using-groups/http://natashatherobot.com/watchkit-text-input-dictation-api/http://develop.watch/text-input-in-watchkit/

  • @kristinathaiRESOURCES

    WATCH CONNECTIVITY & ACCESSIBILITY

    http://kristina.io/watchos-2-how-to-communicate-between-devices-using-watch-connectivity/

    http://kristina.io/watchos-2-tutorial-using-sendmessage-for-instantaneous-data-transfer-watch-connectivity-1/

    http://kristina.io/watchos-2-tutorial-using-application-context-to-transfer-data-watch-connectivity-2/

    https://www.youtube.com/watch?v=nqX2rNbZSyg (Apple Watch Accessibility by Paul Adam)

    http://kristina.io/watchos-2-how-to-communicate-between-devices-using-watch-connectivity/http://kristina.io/watchos-2-tutorial-using-sendmessage-for-instantaneous-data-transfer-watch-connectivity-1/http://kristina.io/watchos-2-tutorial-using-application-context-to-transfer-data-watch-connectivity-2/https://www.youtube.com/watch?v=nqX2rNbZSyg

  • @kristinathaiRESOURCES

    CLOCKKIT

    http://kristina.io/clockkit-tutorial-add-complication-to-an-already-existing-watch-project-clockkit-1/

    http://kristina.io/clockkit-deep-dive-text-providers-clockkit-2/

    http://code.tutsplus.com/tutorials/an-introduction-to-clockkit--cms-24247

    https://theswiftdev.com/2016/04/28/clockkit-complications-cheat-sheet/

    http://kristina.io/clockkit-tutorial-add-complication-to-an-already-existing-watch-project-clockkit-1/http://kristina.io/clockkit-deep-dive-text-providers-clockkit-2/http://code.tutsplus.com/tutorials/an-introduction-to-clockkit--cms-24247https://theswiftdev.com/2016/04/28/clockkit-complications-cheat-sheet/

  • THANKS! @kristinathai

    [email protected]

    kristina.io

    http://kristina.io