Keeping Your Watch App Up to Date



Similar documents
Going Social with ReplayKit and Game Center

Game Center Programming Guide

WakeMyPC technical user guide

Continuous Integration and Code Coverage in Xcode

Advanced Testing and Continuous Integration

What s New in Security

Lotus Notes Traveler User and Troubleshooting Guide for ios Devices. Manage the Settings for your Mail, Calendar, and Contacts Apps

Nintex Workflow for Project Server 2010 Help

Improving Your App with Instruments

Training Manual. Version 6

Lab Exercise SSL/TLS. Objective. Requirements. Step 1: Capture a Trace

IBM BPM V8.5 Standard Consistent Document Managment

here: styleguide.googlecode.com/svn/trunk/javascriptguide.xml.

User Manual Release 1.02

Customize Mobile Apps with MicroStrategy SDK: Custom Security, Plugins, and Extensions

NAS 242 Using AiMaster on Your Mobile Devices

Salesforce Classic Guide for iphone

PM CENTRAL SANDBOX GETTING STARTED GUIDE

Lab 5 Using Remote Worklight Server

Software Development Kit (SDK)

1 Intel Smart Connect Technology Installation Guide:

WHAT ELSE CAN YOUR HOME PHONE DO?

S4 USER GUIDE. Read Me to Get the Most Out of Your Device...

Continuous Integration with Xcode 6

Rochester Institute of Technology. Finance and Administration. Drupal 7 Training Documentation

Kansas City Scout. Subscriber s Guide. Version 1.0

U11 Boys Black March 21st Monday 6:00-7:30 p.m. Damien Training Field 2 March 24th Thursday 4:30-6:00 p.m. Damien Training Field 2 March 28th Monday 6

MultiSite Manager. Setup Guide

ITP 342 Mobile App Development. Notifications

User Guide For ipodder on Windows systems

Supplemental Activity

Event Kit Programming Guide

Live Maps. for System Center Operations Manager 2007 R2 v Installation Guide

Sophos Mobile Control user help. Product version: 6.1

RingCentral for Desktop. UK User Guide

Installing and Running the Google App Engine On Windows

Testing Cloud Application System Resiliency by Wrecking the System

LogMeIn Rescue+Mobile for Android

Network Security EDA /2012. Laboratory assignment 4. Revision A/576, :13:02Z

genie app and genie mobile app

DECEMBER 2015 PTAB Public Hearing Schedule

Zing Vision. Answering your toughest production Java performance questions

ETHERNET IRRIGATION CONTROLLER. Irrigation Caddy Model: ICEthS1. User Manual and Installation Instructions

Advanced Tornado TWENTYONE Advanced Tornado Accessing MySQL from Python LAB

Setup Instructions. For StatBroadcast s Broadcastr and StatCrew Legacy. Last Rev: July 17, 2015 StatBroadcast Systems

Table of Contents. Use. Troubleshooting. Setup. Welcome. 11 How to arm/disarm system/camera(s) 19 Sync Module setup issues. 3 Installing the Blink app

Implementing Endpoint Protection in System Center 2012 R2 Configuration Manager

UP L18 Enhanced MDM and Updated Protection Hands-On Lab

Mobile Operator Notifications and System Events

Jive Connects for Openfire

User Guide. Copyright 2003 Networks Associates Technology, Inc. All Rights Reserved.

T R O U B L E S H O O T I N G T I P S

Field Manager Mobile Worker User Guide for RIM BlackBerry 1

jfqbi= = eqji=qççäâáí= = = aéîéäçééêûë=dìáçé=== oéäé~ëé=oko=

Made Easy Windows Sync App Tutorial

Designing the Process

Dacorum U3A Apple Mac Users Group Agenda TUESDAY 7th July 2015 Time Machine Backups for your MAC & ipad?

User Manual. NETGEAR, Inc. 350 East Plumeria Drive San Jose, CA 95134, USA. December

Jobs Guide Identity Manager February 10, 2012

Lab - Building an Internet of Things Application Hands-On Lab

Cellcom Fleet for Vehicles Getting Started Guide

138 Configuration Wizards

RemoteApp Reference Guide. Outline

You can access OneDrive through your Office 365 account at

Cisco Events Mobile Application

Optimize Your Earning Power with iad

Manage Licenses and Updates

The easy way to accept EFTPOS, Visa and MasterCard payments on the spot. Mobile Users Charging your PayClip. 2. Downloading the PayClip app.

Configuring Secure Socket Layer (SSL) for use with BPM 7.5.x

Configuring a Custom Load Evaluator Use the XenApp1 virtual machine, logged on as the XenApp\administrator user for this task.

How to install and use the File Sharing Outlook Plugin

How to Setup SQL Server Replication

Intel HTML5 Development Environment. Tutorial Building an Apple ios* Application Binary

GRAVITYZONE UNIFIED SECURITY MANAGEMENT. Use Cases for Beta Testers

Daylite Synchronization Guide

CS 326e F2002 Lab 1. Basic Network Setup & Ethereal Time: 2 hrs

Fiery Clone Tool For Embedded Servers User Guide

User Guide SAP SuccessFactors Employee Central Document Version: Q Release July 8 PUBLIC. Time Off

Manual. Netumo NETUMO HELP MANUAL Copyright Netumo 2014 All Rights Reserved

Tizen Web Runtime Update. Ming Jin Samsung Electronics

MOBILE APP TRAINING MANUAL

Sophos Mobile Control as a Service Startup guide. Product version: 3.5

EMC Smarts Integration Guide

Backup Tab. User Guide

NetBeans Profiler is an

Using Microsoft Azure for Students

MiVoice Integration for Salesforce

NEXT Analytics User Guide for Facebook

Configuring ehealth Application Response to Monitor Web Applications

GO!Enterprise MDM Device Application User Guide Installation and Configuration for ios Devices

Real Life Oracle Mobile Application Framework. Things that you don't get from the developer guide

End User Guide. July 22, 2015

Help. F-Secure Online Backup

WNMS Mobile Application

Mobile Iron User Guide

Transcription:

App Frameworks #WWDC16 Keeping Your Watch App Up to Date Session 218 Eric Lanz watchos Engineer Austen Green watchos Engineer 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Overview Walkthrough Scheduling Best Practices Case Study

Overview User model

Overview User model Waiting for Coffee

Overview User model Waiting for Coffee Check Weather

Overview User model Waiting for Coffee Find a Lunch Spot Check Weather

Overview User model Waiting for Coffee Find a Lunch Spot Check Weather Receive Notification

Overview User model Waiting for Coffee Find a Lunch Spot Check Traffic Check Weather Receive Notification

Overview User model Waiting for Coffee Find a Lunch Spot Check Traffic Check Weather Receive Notification Quick Reply

Overview User model Waiting for Coffee Find a Lunch Spot Check Traffic Check Weather Receive Notification Quick Reply

Overview Scheduling Background Foreground Check Weather

Overview Scheduling Background Foreground Check Weather Update UI

Overview Scheduling Background Foreground Check Weather Fetch Data Update UI

Overview Scheduling Background Foreground Check Weather Wake Up Fetch Data Update UI

Tasks watchos Applications Task Task Task Task Task Task Task Task Suspended

Tasks watchos Applications Task Task Task Task Task Task Task Task Active

Tasks watchos Applications Task Task Task Task Task Task Task Task Active

Tasks watchos Applications Task Task func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) Task Task Task Task Task Task Active

Tasks watchos Applications Task Task Task Task Task Task Task Task Suspended

Tasks watchos Applications Task Task Task Task Task Task Task Task Suspended

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Wake up Background Foreground Check Weather Wake Up Fetch Data Update UI Application Task

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Fetch data Background Foreground Check Weather Wake Up Fetch Data Update UI URLSession Task

Snapshots

Snapshots

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Snapshot Background Foreground Check Weather Wake Up Fetch Data Update UI Snapshot Task

Snapshots Meet expectations

Snapshots Optional default state

Snapshots More information Designing Great Apple Watch Experiences Presidio Wednesday 1:40PM

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Summary WKApplicationRefreshBackgroundTask WKExtension: schedulebackgroundrefresh WKURLSessionRefreshBackgroundTask Schedule using URLSession WKSnapshotRefreshBackgroundTask WKExtension: schedulesnapshotrefresh WKWatchConnectivityRefreshBackgroundTask Schedule using Watch Connectivity

Tasks Watch connectivity

Tasks Watch connectivity Complication Context File User Info

Tasks Watch connectivity Is Session Active

Tasks NEW Watch connectivity Is Session Active hascontentpending

Tasks Watch connectivity Is Session Active hascontentpending Complete Task

Schedule Background Runtime

Schedule Background Runtime Receive Tasks

Schedule Background Runtime Receive Tasks Do Work

Schedule More Runtime Schedule Background Runtime Receive Tasks Do Work

Schedule More Runtime Schedule Background Runtime Receive Tasks Do Work Tell System When Done

Be a Good Citizen

Be a Good Citizen User Launches App 3:00 PM

Be a Good Citizen User Launches App Wake Up 3:00 PM 4:00 PM

Be a Good Citizen User Launches App Wake Up 3:50 PM 4:00 PM

Be a Good Citizen User Launches App Wake Up 3:50 PM 4:50 PM

Walkthrough

Walkthrough Football scores 7:00 PM 9:00 PM

Walkthrough Football scores Update Score Update Score Update Score 7:00 PM 9:00 PM 7:30 PM 8:00 PM 8:30 PM

Walkthrough Football scores Update Score Update Score Update Score 7:00 PM 9:00 PM 7:30 PM 8:00 PM 8:30 PM

Walkthrough Football scores Update Score Update Score Update Score 7:00 PM 9:00 PM 7:30 PM 8:00 PM 8:30 PM

Walkthrough Football scores Update Score Update Score Update Score 7:00 PM 9:00 PM 7:30 PM 8:00 PM 8:30 PM

// Scheduling Background Runtime func myschedulenextrefreshtask() { let firedate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes from now let userinfo = ["lastactivedate" : Date(), "reason" : scoreupdate ] // optional last active time // optional reason WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: firedate, userinfo: userinfo) { (error) in if error == nil { // successfully scheduled } } }

// Scheduling Background Runtime func myschedulenextrefreshtask() { let firedate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes from now let userinfo = ["lastactivedate" : Date(), "reason" : scoreupdate ] // optional last active time // optional reason WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: firedate, userinfo: userinfo) { (error) in if error == nil { // successfully scheduled } } }

// Scheduling Background Runtime func myschedulenextrefreshtask() { let firedate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes from now let userinfo = ["lastactivedate" : Date(), "reason" : scoreupdate ] // optional last active time // optional reason WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: firedate, userinfo: userinfo) { (error) in if error == nil { // successfully scheduled } } }

Walkthrough Football scores Wake Up 7:30 PM 7:35 PM 7:30:00

Walkthrough Football scores Wake Up Fetch Data 7:30 PM 7:35 PM 7:30:02

// Fetching Data in the Background func myscheduleurlsession() { let backgroundconfigobject = URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: "com.example.urlsession") let backgroundsession = URLSession(configuration: backgroundconfigobject) let downloadtask = backgroundsession.downloadtask( with: URL(string: "https://example.com/currentscores.json")!) downloadtask.resume() }

// Fetching Data in the Background func myscheduleurlsession() { let backgroundconfigobject = URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: "com.example.urlsession") let backgroundsession = URLSession(configuration: backgroundconfigobject) let downloadtask = backgroundsession.downloadtask( with: URL(string: "https://example.com/currentscores.json")!) downloadtask.resume() }

// Fetching Data in the Background func myscheduleurlsession() { let backgroundconfigobject = URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: "com.example.urlsession") let backgroundsession = URLSession(configuration: backgroundconfigobject) let downloadtask = backgroundsession.downloadtask( with: URL(string: "https://example.com/currentscores.json")!) downloadtask.resume() }

// Fetching Data in the Background func myscheduleurlsession() { let backgroundconfigobject = URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: "com.example.urlsession") let backgroundsession = URLSession(configuration: backgroundconfigobject) let downloadtask = backgroundsession.downloadtask( with: URL(string: "https://example.com/currentscores.json")!) downloadtask.resume() }

Walkthrough Football scores Wake Up Fetch Data 7:30 PM 7:35 PM 7:30:05

Walkthrough Football scores Wake Up Fetch Data Update Model 7:30 PM 7:35 PM 7:33:00

// Handling Background Tasks // WKExtensionDelegate func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) { for task in backgroundtasks { if let urltask = task as? WKURLSessionRefreshBackgroundTask let backgroundconfigobject URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: urltask.sessionidentifier) let backgroundsession = URLSession(configuration: backgroundconfigobject, delegate: self, delegatequeue: nil) // receive data via URLSessionDownloadDelegate pendingbackgroundtasks.append(task) } else { task.settaskcompleted() // make sure to complete all tasks } } }

// Handling Background Tasks // WKExtensionDelegate func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) { for task in backgroundtasks { if let urltask = task as? WKURLSessionRefreshBackgroundTask let backgroundconfigobject URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: urltask.sessionidentifier) let backgroundsession = URLSession(configuration: backgroundconfigobject, delegate: self, delegatequeue: nil) // receive data via URLSessionDownloadDelegate pendingbackgroundtasks.append(task) } else { task.settaskcompleted() // make sure to complete all tasks } } }

// Handling Background Tasks // WKExtensionDelegate func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) { for task in backgroundtasks { if let urltask = task as? WKURLSessionRefreshBackgroundTask let backgroundconfigobject URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: urltask.sessionidentifier) let backgroundsession = URLSession(configuration: backgroundconfigobject, delegate: self, delegatequeue: nil) // receive data via URLSessionDownloadDelegate pendingbackgroundtasks.append(task) } else { task.settaskcompleted() // make sure to complete all tasks } } }

// Handling Background Tasks // WKExtensionDelegate func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) { for task in backgroundtasks { if let urltask = task as? WKURLSessionRefreshBackgroundTask let backgroundconfigobject URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: urltask.sessionidentifier) let backgroundsession = URLSession(configuration: backgroundconfigobject, delegate: self, delegatequeue: nil) // receive data via URLSessionDownloadDelegate pendingbackgroundtasks.append(task) } else { task.settaskcompleted() // make sure to complete all tasks } } }

// Handling Background Tasks // WKExtensionDelegate func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>) { for task in backgroundtasks { if let urltask = task as? WKURLSessionRefreshBackgroundTask let backgroundconfigobject URLSessionConfiguration.backgroundSessionConfiguration( withidentifier: urltask.sessionidentifier) let backgroundsession = URLSession(configuration: backgroundconfigobject, delegate: self, delegatequeue: nil) // receive data via URLSessionDownloadDelegate pendingbackgroundtasks.append(task) } else { task.settaskcompleted() // make sure to complete all tasks } } }

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM 7:33:02

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM 7:30:05

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM 7:34:00

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM 7:34:05

// Completing Snapshot Task func mycompletesnapshottask(snaptask : WKSnapshotRefreshBackgroundTask) { let expiredate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes let userinfo = ["lastactivedate" : Date()] let restoreddefaultstate = false snaptask.settaskcompleted(restoreddefaultstate: restoreddefaultstate, estimatedsnapshotexpiration: expiredate, userinfo: userinfo) }

// Completing Snapshot Task func mycompletesnapshottask(snaptask : WKSnapshotRefreshBackgroundTask) { let expiredate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes let userinfo = ["lastactivedate" : Date()] let restoreddefaultstate = false snaptask.settaskcompleted(restoreddefaultstate: restoreddefaultstate, estimatedsnapshotexpiration: expiredate, userinfo: userinfo) }

// Completing Snapshot Task func mycompletesnapshottask(snaptask : WKSnapshotRefreshBackgroundTask) { let expiredate = Date(timeIntervalSinceNow: 30 * 60) // 30 minutes let userinfo = ["lastactivedate" : Date()] let restoreddefaultstate = false snaptask.settaskcompleted(restoreddefaultstate: restoreddefaultstate, estimatedsnapshotexpiration: expiredate, userinfo: userinfo) }

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM

Walkthrough Football scores Wake Up Fetch Data Update Model Update UI 7:30 PM 7:35 PM 5 seconds 5 seconds 5 seconds

Scheduling Austen Green watchos Engineer

Scheduling Runtime

Scheduling Runtime Always scheduled in foreground

Scheduling Runtime Always scheduled in foreground Usually suspended in background

Scheduling Runtime Always scheduled in foreground Usually suspended in background Targeted runtime for specific tasks

Scheduling Runtime limits

Scheduling Runtime limits On order of seconds

Scheduling Runtime limits On order of seconds Time and CPU considered

Scheduling Runtime limits On order of seconds Time and CPU considered Apps killed for exceeding limits - CPU - 0xc51bad01 - Time - 0xc51bad02

Scheduling Runtime limits On order of seconds Time and CPU considered Apps killed for exceeding limits - CPU - 0xc51bad01 - Time - 0xc51bad02 Different allocations by task WKApplicationRefreshBackgroundTask WKURLSessionRefreshBackgroundTask

Scheduling Complications

Scheduling Complications Multiple updates per hour

Scheduling Complications Multiple updates per hour Request updates through WKExtension

Scheduling Complications Multiple updates per hour Request updates through WKExtension 50 guaranteed pushes

// Scheduling // Complications NEW func modelchangedoniphone() { let session = WCSession.defaultSession() let transfers = session.remainingcomplicationuserinfotransfers let userinfo // Complication data } switch transfers { case 0: // No transfers left. Can still try to send session.transfercurrentcomplicationuserinfo(userinfo) break; case 1...10: // Running low on transfers // Conditionally send if it's really important // Otherwise conserve the transfer for a more significant change break; default: // Send data immediately session.transfercurrentcomplicationuserinfo(userinfo) }

// Scheduling // Complications NEW func modelchangedoniphone() { let session = WCSession.defaultSession() let transfers = session.remainingcomplicationuserinfotransfers let userinfo // Complication data } switch transfers { case 0: // No transfers left. Can still try to send session.transfercurrentcomplicationuserinfo(userinfo) break; case 1...10: // Running low on transfers // Conditionally send if it's really important // Otherwise conserve the transfer for a more significant change break; default: // Send data immediately session.transfercurrentcomplicationuserinfo(userinfo) }

// Scheduling // Complications NEW func modelchangedoniphone() { let session = WCSession.defaultSession() let transfers = session.remainingcomplicationuserinfotransfers let userinfo // Complication data } switch transfers { case 0: // No transfers left. Can still try to send session.transfercurrentcomplicationuserinfo(userinfo) break; case 1...10: // Running low on transfers // Conditionally send if it's really important // Otherwise conserve the transfer for a more significant change break; default: // Send data immediately session.transfercurrentcomplicationuserinfo(userinfo) }

// Scheduling // Complications NEW func modelchangedoniphone() { let session = WCSession.defaultSession() let transfers = session.remainingcomplicationuserinfotransfers let userinfo // Complication data } switch transfers { case 0: // No transfers left. Can still try to send session.transfercurrentcomplicationuserinfo(userinfo) break; case 1...10: // Running low on transfers // Conditionally send if it's really important // Otherwise conserve the transfer for a more significant change break; default: // Send data immediately session.transfercurrentcomplicationuserinfo(userinfo) }

// Scheduling // Complications NEW func modelchangedoniphone() { let session = WCSession.defaultSession() let transfers = session.remainingcomplicationuserinfotransfers let userinfo // Complication data } switch transfers { case 0: // No transfers left. Can still try to send session.transfercurrentcomplicationuserinfo(userinfo) break; case 1...10: // Running low on transfers // Conditionally send if it's really important // Otherwise conserve the transfer for a more significant change break; default: // Send data immediately session.transfercurrentcomplicationuserinfo(userinfo) }

// Scheduling // CLKComplicationDataSource optional public func getnextrequestedupdatedate(handler handler: (NSDate?) -> Void)

// Scheduling // WKExtension public func schedulebackgroundrefresh(withpreferreddate preferredfiredate: Date, userinfo: NSSecureCoding?, scheduledcompletion: (NSError?) -> Swift.Void)

// Scheduling // CLKComplicationDataSource optional public func requestedupdatedidbegin()

// Scheduling // WKExtensionDelegate optional public func handle(_ backgroundtasks: Set<WKRefreshBackgroundTask>)

Scheduling Dock apps

Scheduling Dock apps Minimum one per hour

Scheduling Dock apps Minimum one per hour Distributed budget

Scheduling Dock apps Minimum one per hour Distributed budget

Scheduling Dock apps Minimum one per hour Distributed budget Kept in memory

Scheduling Recent app

Scheduling Recent app Most Recently Used app in dock

Scheduling Recent app Most Recently Used app in dock Treated like a favorite app

Scheduling Recent app Most Recently Used app in dock Treated like a favorite app Home screen apps should not expect regular scheduling

Scheduling System snapshots

Scheduling System snapshots Does not count against budget

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers Complication timeline update

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers Complication timeline update Notification interaction

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers Complication timeline update Notification interaction Foreground > Background

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers Complication timeline update Notification interaction Foreground > Background Default state one hour after backgrounding

Scheduling System snapshots Does not count against budget In addition to app-requested snapshot Triggers Complication timeline update Notification interaction Foreground > Background Default state one hour after backgrounding Boot

Best Practices

Best Practices

Best Practices Schedule as often as needed

Best Practices Schedule as often as needed Do not feel obligated to do work Finish ASAP Defer work

Best Practices Schedule as often as needed Do not feel obligated to do work Finish ASAP Defer work Consider all runtime opportunities Dock and foreground activations Notifications Complication updates Background refresh

Best Practices WKApplicationRefreshBackgroundTask

Best Practices WKApplicationRefreshBackgroundTask Use schedulebackgroundrefresh for general-purpose runtime

Best Practices WKApplicationRefreshBackgroundTask Use schedulebackgroundrefresh for general-purpose runtime Polling

Best Practices WKApplicationRefreshBackgroundTask Use schedulebackgroundrefresh for general-purpose runtime Polling Scheduling future NSURLSessions

Best Practices WKApplicationRefreshBackgroundTask Use schedulebackgroundrefresh for general-purpose runtime Polling Scheduling future NSURLSessions Known time transitions

Best Practices WKApplicationRefreshBackgroundTask Use schedulebackgroundrefresh for general-purpose runtime Polling Scheduling future NSURLSessions Known time transitions Triggering complication updates

Best Practices Snapshots

Best Practices Snapshots Invalidate snapshots appropriately

Best Practices Snapshots Invalidate snapshots appropriately Significant content change

Best Practices Snapshots Invalidate snapshots appropriately Significant content change Avoid high-frequency invalidation

Best Practices Data flow

Best Practices Data flow External Event

Best Practices Data flow External Event Model

Best Practices Data flow External Event Model Update Complication Request Snapshot Request Background URL Session Schedule Background Refresh

Best Practices App lifecycle

Best Practices App lifecycle Finish background tasks ASAP on foreground activation

Best Practices App lifecycle Finish background tasks ASAP on foreground activation Finish foreground work when entering background

Best Practices App lifecycle Finish background tasks ASAP on foreground activation Finish foreground work when entering background NSProcessInfo.performExpiringActivity

Best Practices App lifecycle Finish background tasks ASAP on foreground activation Finish foreground work when entering background NSProcessInfo.performExpiringActivity WatchKit Tips and Tricks WWDC 2015

Best Practices App lifecycle Finish background tasks ASAP on foreground activation Finish foreground work when entering background NSProcessInfo.performExpiringActivity Data protection WatchKit Tips and Tricks WWDC 2015

Best Practices Testing

Best Practices Testing Simulator for iterative development

Best Practices Testing Simulator for iterative development Keep the device on charger

Best Practices Testing Simulator for iterative development Keep the device on charger Test the launch path

Best Practices Testing Simulator for iterative development Keep the device on charger Test the launch path Verify tasks are being completed

Best Practices Testing Simulator for iterative development Keep the device on charger Test the launch path Verify tasks are being completed Live on it

Best Practices Testing Simulator for iterative development Keep the device on charger Test the launch path Verify tasks are being completed Live on it Vary number of apps in the dock

Case Study Stocks

Case Study Stocks

Case Study Stocks Characteristics

Case Study Stocks Characteristics NSURLSession to retrieve server data

Case Study Stocks Characteristics NSURLSession to retrieve server data Has a complication

Case Study Stocks Characteristics NSURLSession to retrieve server data Has a complication Periodic cadence for part of the day

Case Study Stocks Characteristics NSURLSession to retrieve server data Has a complication Periodic cadence for part of the day No updates while markets are closed

Case Study Boot

Case Study Boot Load last data for snapshot

Case Study Boot Load last data for snapshot Schedule a background NSURLSession

Case Study Boot Load last data for snapshot Schedule a background NSURLSession Use NSURLSessionDownloadTask

Case Study Boot Load last data for snapshot Schedule a background NSURLSession Use NSURLSessionDownloadTask NSURLSessionDataTask will fail for background session on app suspension

Case Study NSURLSession

Case Study NSURLSession Update model

Case Study NSURLSession Update model - Trigger a complication update

Case Study NSURLSession Update model - Trigger a complication update - Request a new snapshot for now

Case Study NSURLSession Update model - Trigger a complication update - Request a new snapshot for now - Request a background refresh for next expected model update time

Case Study Background refresh

Case Study Background refresh Schedule the next NSURLSession download

Case Study Stocks activated from the dock

Case Study Stocks activated from the dock Use NSURLSession to update model

Case Study Stocks activated from the dock Use NSURLSession to update model - Request complication update

Case Study Stocks activated from the dock Use NSURLSession to update model - Request complication update - Request new snapshot

Case Study Stocks activated from the dock Use NSURLSession to update model - Request complication update - Request new snapshot - Schedule background refresh for a later time

Case Study Last update after market close

Case Study Last update after market close Data has stopped changing for the day

Case Study Last update after market close Data has stopped changing for the day - Complete update as normal

Case Study Last update after market close Data has stopped changing for the day - Complete update as normal - Schedule next refresh for market open

Summary

Summary Complete your tasks

Summary Complete your tasks Use runtime efficiently

Summary Complete your tasks Use runtime efficiently Tell the system when data changes

Summary Complete your tasks Use runtime efficiently Tell the system when data changes Consider adoption strategies on case-by-case basis

More Information https://developer.apple.com/wwdc16/218

Related Sessions What s New in watchos 3 Presidio Tuesday 5:00PM Quick Interaction Techniques for watchos Presidio Wednesday 11:00AM Designing Great Apple Watch Experiences Presidio Wednesday 1:40PM Architecting for Performance on watchos 3 Mission Thursday 3:00PM

Labs WatchKit and Background Tasks Lab WatchKit and WatchConnectivity Lab Frameworks Lab C Thursday 10:30AM Frameworks Lab B Friday 2:00PM