how to build a compelling apple watch app
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
kristina.io
http://kristina.io