Building Great Workout Apps
-
Upload
duongkhuong -
Category
Documents
-
view
312 -
download
2
Transcript of Building Great Workout Apps
![Page 1: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/1.jpg)
© 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
HealthKit APIs and best practices
App Frameworks #WWDC16
Session 235
Building Great Workout Apps
Dash Brittain iOS Software EngineerJorge Moriñigo iOS Software Engineer
![Page 2: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/2.jpg)
![Page 3: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/3.jpg)
![Page 4: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/4.jpg)
![Page 5: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/5.jpg)
![Page 6: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/6.jpg)
Background Running
![Page 7: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/7.jpg)
Background Running
Workout Lifecycle
![Page 8: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/8.jpg)
Background Running
Workout Lifecycle
Activity Rings
![Page 9: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/9.jpg)
Background Running
Workout Lifecycle
Activity Rings
Workouts in iOS 10
![Page 10: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/10.jpg)
Background Running
Workout Lifecycle
Activity Rings
Workouts in iOS 10
Best Practices
![Page 11: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/11.jpg)
Getting Started
![Page 12: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/12.jpg)
HKWorkoutSession
![Page 13: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/13.jpg)
HKWorkoutSession
Motion and calorimetry for activity type
![Page 14: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/14.jpg)
HKWorkoutSession
Motion and calorimetry for activity typeActivity rings
![Page 15: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/15.jpg)
HKWorkoutSession
Motion and calorimetry for activity typeActivity ringsShow app on wake
![Page 16: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/16.jpg)
HKWorkoutSession
Motion and calorimetry for activity typeActivity ringsShow app on wakeBackground running
![Page 17: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/17.jpg)
Background Running NEW
![Page 18: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/18.jpg)
Background Running
Process sensor data
NEW
![Page 19: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/19.jpg)
Background Running
Process sensor dataLive feedback
NEW
![Page 20: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/20.jpg)
Background Running
Process sensor dataLive feedbackQuickly update UI
NEW
![Page 21: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/21.jpg)
// Background Running
// WatchKit Extension Info.plist
<key>WKBackgroundModes</key>
<array>
<string>workout-processing</string>
</array>
NEW
![Page 22: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/22.jpg)
Conserve powerBackground Running NEW
![Page 23: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/23.jpg)
Conserve powerBackground Running
Limit background work
NEW
![Page 24: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/24.jpg)
Conserve powerBackground Running
Limit background workApp may be suspended
NEW
![Page 25: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/25.jpg)
Conserve powerBackground Running
Limit background workApp may be suspendedMeasure background work with tools
NEW
![Page 26: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/26.jpg)
Conserve powerBackground Running
Limit background workApp may be suspendedMeasure background work with tools• CPU Report in Xcode
NEW
![Page 27: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/27.jpg)
Conserve powerBackground Running
Limit background workApp may be suspendedMeasure background work with tools• CPU Report in Xcode• Time Profiler in Instruments
NEW
![Page 28: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/28.jpg)
Conserve powerBackground Running
Limit background workApp may be suspendedMeasure background work with tools• CPU Report in Xcode• Time Profiler in Instruments• Backtrace log
NEW
![Page 29: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/29.jpg)
Starting a Workout
![Page 30: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/30.jpg)
Authorization
Starting a Workout
![Page 31: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/31.jpg)
Authorization Workout Configuration
Starting a Workout
![Page 32: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/32.jpg)
Authorization Workout Configuration
Start Workout Session
Starting a Workout
![Page 33: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/33.jpg)
Authorization
![Page 34: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/34.jpg)
Authorization to write• Workouts
Authorization
![Page 35: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/35.jpg)
Authorization to write• Workouts
Authorization to read• Energy burned• Distance• Heart rate
Authorization
![Page 36: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/36.jpg)
Authorization to write• Workouts
Authorization to read• Energy burned• Distance• Heart rate
Authorization
Getting the Most Out of HealthKit Wednesday
![Page 37: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/37.jpg)
// Workout Configuration
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
![Page 38: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/38.jpg)
// Workout Configuration
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
![Page 39: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/39.jpg)
// Workout Configuration
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
![Page 40: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/40.jpg)
// Start Workout Session
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
healthStore.start(workoutSession)
![Page 41: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/41.jpg)
// Start Workout Session
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
healthStore.start(workoutSession)
![Page 42: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/42.jpg)
// Start Workout Session
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
healthStore.start(workoutSession)
![Page 43: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/43.jpg)
DemoSpeedySloth: Starting a Workout
Dash BrittainiOS Software Engineer
![Page 44: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/44.jpg)
Data Collection and Control
Jorge MoriñigoiOS Software Engineer
![Page 45: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/45.jpg)
Ending and Saving Workout
Data Collection and Control
StartingWorkout
![Page 46: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/46.jpg)
Ending and Saving Workout
Data Collection and Control
StartingWorkout
Start Observing Samples
![Page 47: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/47.jpg)
Start Observing Events
Ending and Saving Workout
Data Collection and Control
StartingWorkout
Start Observing Samples
![Page 48: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/48.jpg)
Start Observing Events
Ending and Saving Workout
Data Collection and Control
StartingWorkout
Start Observing Samples
Running
![Page 49: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/49.jpg)
Start Observing Events
Ending and Saving Workout
Data Collection and Control
StartingWorkout
Start Observing Samples
Paused
Running
![Page 50: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/50.jpg)
Start Observing Events
Ending and Saving Workout
Data Collection and Control
StartingWorkout
Start Observing Samples
Paused
Running
![Page 51: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/51.jpg)
Observing Samples
![Page 52: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/52.jpg)
Observing Samples
Open query for each data type
![Page 53: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/53.jpg)
Observing Samples
Open query for each data typeUpdate your running totals
![Page 54: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/54.jpg)
Observing Samples
Open query for each data typeUpdate your running totalsDisplay live data
![Page 55: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/55.jpg)
Observing Samples
Open query for each data typeUpdate your running totalsDisplay live dataNotify user of reached goals
![Page 56: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/56.jpg)
// Observing Samples
![Page 57: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/57.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
![Page 58: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/58.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
![Page 59: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/59.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
let queryPredicate = CompoundPredicate(andPredicateWithSubpredicates:[datePredicate,
devicePredicate])
![Page 60: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/60.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
let queryPredicate = CompoundPredicate(andPredicateWithSubpredicates:[datePredicate,
devicePredicate])
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?,
NSError?) -> Void = { query, samples, deletedObjects, queryAnchor, error in
// Process samples
}
![Page 61: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/61.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
let queryPredicate = CompoundPredicate(andPredicateWithSubpredicates:[datePredicate,
devicePredicate])
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?,
NSError?) -> Void = { query, samples, deletedObjects, queryAnchor, error in
// Process samples
}
let query = HKAnchoredObjectQuery(type: quantityType,
predicate: queryPredicate,
anchor: nil,
limit: HKObjectQueryNoLimit,
resultsHandler: updateHandler)
![Page 62: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/62.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
let queryPredicate = CompoundPredicate(andPredicateWithSubpredicates:[datePredicate,
devicePredicate])
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?,
NSError?) -> Void = { query, samples, deletedObjects, queryAnchor, error in
// Process samples
}
let query = HKAnchoredObjectQuery(type: quantityType,
predicate: queryPredicate,
anchor: nil,
limit: HKObjectQueryNoLimit,
resultsHandler: updateHandler)
query.updateHandler = updateHandler
![Page 63: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/63.jpg)
// Observing Samples
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil,
options: .strictStartDate)
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
let queryPredicate = CompoundPredicate(andPredicateWithSubpredicates:[datePredicate,
devicePredicate])
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?,
NSError?) -> Void = { query, samples, deletedObjects, queryAnchor, error in
// Process samples
}
let query = HKAnchoredObjectQuery(type: quantityType,
predicate: queryPredicate,
anchor: nil,
limit: HKObjectQueryNoLimit,
resultsHandler: updateHandler)
query.updateHandler = updateHandler
healthStore.execute(query)
![Page 64: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/64.jpg)
Notify user of reached goalObserving Samples
![Page 65: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/65.jpg)
Notify user of reached goalObserving Samples
Play haptic to alert user
![Page 66: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/66.jpg)
Notify user of reached goalObserving Samples
Play haptic to alert userUpdate UI to reflect reached goal
![Page 67: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/67.jpg)
Notify user of reached goalObserving Samples
Play haptic to alert userUpdate UI to reflect reached goal
WKInterfaceDevice.current().play(.notification)
![Page 68: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/68.jpg)
Observing Events
![Page 69: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/69.jpg)
Observing Events
Timestamps to highlight point in session
![Page 70: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/70.jpg)
Observing Events
Timestamps to highlight point in sessionSome events created by your app
![Page 71: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/71.jpg)
Observing Events
Timestamps to highlight point in sessionSome events created by your appSome events created by HealthKit
![Page 72: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/72.jpg)
Observing Events
Timestamps to highlight point in sessionSome events created by your appSome events created by HealthKit
protocol HKWorkoutSessionDelegate
func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent)
![Page 73: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/73.jpg)
Laps and Markers NEW
![Page 74: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/74.jpg)
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 75: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/75.jpg)
Create to store in a workout
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 76: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/76.jpg)
Create to store in a workoutTimestamps for graphs and statistics
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 77: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/77.jpg)
Create to store in a workoutTimestamps for graphs and statisticsLaps for equal distance partitions
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 78: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/78.jpg)
Create to store in a workoutTimestamps for graphs and statisticsLaps for equal distance partitionsMarkers for arbitrary points
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 79: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/79.jpg)
Create to store in a workoutTimestamps for graphs and statisticsLaps for equal distance partitionsMarkers for arbitrary points
Laps and Markers NEW
HKWorkoutEventType.lap
HKWorkoutEventType.marker
![Page 80: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/80.jpg)
Pausing and Resuming
![Page 81: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/81.jpg)
Pausing and Resuming
Users stop their activity
![Page 82: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/82.jpg)
Pausing and Resuming
Users stop their activityPause workouts to save power and space
![Page 83: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/83.jpg)
Pausing and Resuming
Users stop their activityPause workouts to save power and spaceIgnore data while paused
![Page 84: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/84.jpg)
Pausing and Resuming
Users stop their activityPause workouts to save power and spaceIgnore data while pausedHealthKit responds with pause/resume events
![Page 85: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/85.jpg)
Pausing and Resuming
Users stop their activityPause workouts to save power and spaceIgnore data while pausedHealthKit responds with pause/resume eventsAfter pause event, you will stop receiving new events
![Page 86: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/86.jpg)
Pausing and Resuming NEW
class HKHealthStore {
func pause(_ workoutSession: HKWorkoutSession)
func resume(_ workoutSession: HKWorkoutSession)
...
}
![Page 87: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/87.jpg)
Pausing and Resuming NEW
class HKHealthStore {
func pause(_ workoutSession: HKWorkoutSession)
func resume(_ workoutSession: HKWorkoutSession)
...
}
HKWorkoutEventType.pause
HKWorkoutEventType.resume
![Page 88: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/88.jpg)
Motion Events for Running Workouts NEW
![Page 89: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/89.jpg)
Motion Events for Running Workouts NEW
HKWorkoutEventType.motionPaused
HKWorkoutEventType.motionResumed
![Page 90: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/90.jpg)
Motion Events for Running Workouts
Watch detects when motion pauses or resumes
NEW
HKWorkoutEventType.motionPaused
HKWorkoutEventType.motionResumed
![Page 91: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/91.jpg)
Motion Events for Running Workouts
Watch detects when motion pauses or resumesStop collecting data
NEW
HKWorkoutEventType.motionPaused
HKWorkoutEventType.motionResumed
![Page 92: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/92.jpg)
Motion Events for Running Workouts
Watch detects when motion pauses or resumesStop collecting dataDon’t need to manual pause
NEW
HKWorkoutEventType.motionPaused
HKWorkoutEventType.motionResumed
![Page 93: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/93.jpg)
Motion Events for Running Workouts
Watch detects when motion pauses or resumesStop collecting dataDon’t need to manual pause Only for HKWorkoutActivityTypeRunning
NEW
HKWorkoutEventType.motionPaused
HKWorkoutEventType.motionResumed
![Page 94: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/94.jpg)
DemoSpeedySloth: Data Collection and Control
Jorge MoriñigoiOS Software Engineer
![Page 95: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/95.jpg)
Ending and Saving
Dash BrittainiOS Software Engineer
![Page 96: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/96.jpg)
Workouts in Activity NEW
![Page 97: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/97.jpg)
Workouts in Activity
Activity workout list
NEW
![Page 98: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/98.jpg)
Workouts in Activity
Activity workout listActivity Move ring
NEW
![Page 99: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/99.jpg)
Data Collection and Control
Ending and Saving
![Page 100: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/100.jpg)
Data Collection and Control
EndWorkout Session
Ending and Saving
![Page 101: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/101.jpg)
Data Collection and Control
EndWorkout Session
SaveWorkout
Ending and Saving
![Page 102: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/102.jpg)
Data Collection and Control
EndWorkout Session
SaveWorkout
Add Samplesto Workout
Ending and Saving
![Page 103: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/103.jpg)
Ending an HKWorkoutSession
![Page 104: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/104.jpg)
Ending an HKWorkoutSession
healthStore.end(workoutSession)
![Page 105: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/105.jpg)
Ending an HKWorkoutSession
healthStore.end(workoutSession)
func workoutSession(_ workoutSession: HKWorkoutSession,
didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState,
date: Date) {
if toState == .ended {
// Workout ended, time to save
}
}
![Page 106: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/106.jpg)
// Save Workout
let workout = HKWorkout(
![Page 107: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/107.jpg)
// Save Workout
let workout = HKWorkout( activityType: config.activityType,
![Page 108: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/108.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
activityType: config.activityType,
![Page 109: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/109.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
activityType: config.activityType,
![Page 110: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/110.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
workoutEvents: events,
activityType: config.activityType,
![Page 111: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/111.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
workoutEvents: events,
totalEnergyBurned: totalEnergyBurned,
activityType: config.activityType,
![Page 112: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/112.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
workoutEvents: events,
totalEnergyBurned: totalEnergyBurned,
totalDistance: totalDistance,
activityType: config.activityType,
![Page 113: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/113.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
workoutEvents: events,
totalEnergyBurned: totalEnergyBurned,
totalDistance: totalDistance,
metadata: [HKMetadataKeyIndoorWorkout: isIndoor])
activityType: config.activityType,
![Page 114: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/114.jpg)
// Save Workout
let workout = HKWorkout(
start: startDate,
end: endDate,
workoutEvents: events,
totalEnergyBurned: totalEnergyBurned,
totalDistance: totalDistance,
metadata: [HKMetadataKeyIndoorWorkout: isIndoor])
healthStore.save(workout) { (success, error) in
// Workout saved
}
activityType: config.activityType,
![Page 115: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/115.jpg)
Add Samples to Workout
![Page 116: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/116.jpg)
Add Samples to Workout
Creates an association
![Page 117: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/117.jpg)
Add Samples to Workout
Creates an associationQuery later for graphs
![Page 118: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/118.jpg)
Add Samples to Workout
Creates an associationQuery later for graphsActivity Move ring credit
![Page 119: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/119.jpg)
Add Samples to Workout
Creates an associationQuery later for graphsActivity Move ring creditMatch totals on HKWorkout
![Page 120: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/120.jpg)
// Add Samples to Workout
healthStore.add(samples, to: workout) { (success, error) in
// Samples added
}
![Page 121: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/121.jpg)
DemoSpeedySloth: Ending and Saving
Dash BrittainiOS Software Engineer
![Page 122: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/122.jpg)
Workouts in iOS 10
Jorge MoriñigoiOS Software Engineer
![Page 123: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/123.jpg)
Workouts in iOS 10
![Page 124: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/124.jpg)
Workouts in iOS 10
Workout apps have parent iPhone application
![Page 125: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/125.jpg)
Workouts in iOS 10
Workout apps have parent iPhone applicationWatchConnectivity for messaging when Apple Watch app is running
![Page 126: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/126.jpg)
Workouts in iOS 10
Workout apps have parent iPhone applicationWatchConnectivity for messaging when Apple Watch app is runningBackground running
![Page 127: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/127.jpg)
Workouts in iOS 10
Workout apps have parent iPhone applicationWatchConnectivity for messaging when Apple Watch app is runningBackground runningStart a workout from iPhone
![Page 128: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/128.jpg)
Workouts in iOS 10
Workout apps have parent iPhone applicationWatchConnectivity for messaging when Apple Watch app is runningBackground runningStart a workout from iPhoneNo user intervention on Apple Watch
![Page 129: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/129.jpg)
Workouts in iOS 10
HKWorkoutConfiguration
iPhone App
![Page 130: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/130.jpg)
Workouts in iOS 10
HKWorkoutConfiguration
iPhone App Apple Watch App
![Page 131: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/131.jpg)
Workouts in iOS 10
HKWorkoutConfigurationStart
HKWorkoutSession
iPhone App Apple Watch App
![Page 132: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/132.jpg)
Workouts in iOS 10
HKWorkoutConfigurationStart
HKWorkoutSession
iPhone App Apple Watch App
<key>UIBackgroundModes</key>
<array>
<string>workout-processing</string>
</array>
![Page 133: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/133.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Starting Workout from iPhone
![Page 134: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/134.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Starting Workout from iPhone
![Page 135: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/135.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Starting Workout from iPhone
![Page 136: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/136.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Starting Workout from iPhone
![Page 137: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/137.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Apple Watch App
// Starting Workout from iPhone
// iPhone App
![Page 138: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/138.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
// iPhone App
![Page 139: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/139.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
}
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
// iPhone App
![Page 140: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/140.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
}
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
// iPhone App
![Page 141: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/141.jpg)
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
}
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
// iPhone App
![Page 142: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/142.jpg)
healthStore.startWatchApp(with: workoutConfiguration) { (success, error) in
...
}
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
// iPhone App
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
}
![Page 143: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/143.jpg)
healthStore.startWatchApp(with: workoutConfiguration) { (success, error) in
...
}
var workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
// Starting Workout from iPhone
// iPhone App
if wcSession.activationState == .activated && wcSession.isWatchAppInstalled {
}
![Page 144: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/144.jpg)
// Starting Workout from iPhone
![Page 145: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/145.jpg)
// Starting Workout from iPhone
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
// Apple Watch App
![Page 146: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/146.jpg)
// Starting Workout from iPhone
// Apple Watch App
func handle(_ workoutConfiguration: HKWorkoutConfiguration) {
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
}
![Page 147: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/147.jpg)
// Starting Workout from iPhone
class ExtensionDelegate: WKExtensionDelegate {
}
func handle(_ workoutConfiguration: HKWorkoutConfiguration) {
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
}
// Apple Watch App
![Page 148: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/148.jpg)
// Starting Workout from iPhone
class ExtensionDelegate: WKExtensionDelegate {
}
func handle(_ workoutConfiguration: HKWorkoutConfiguration) {
let workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
workoutSession.delegate = self
healthStore.start(workoutSession)
}
// Apple Watch App
![Page 149: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/149.jpg)
DemoSpeedySloth: iPhone App
Jorge MoriñigoiOS Software Engineer
![Page 150: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/150.jpg)
Best Practices
![Page 151: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/151.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable
![Page 152: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/152.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable• Keep session running when losing connectivity
![Page 153: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/153.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable• Keep session running when losing connectivity• Use HealthKit distance when GPS is unavailable
![Page 154: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/154.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable• Keep session running when losing connectivity• Use HealthKit distance when GPS is unavailable
User should be able to begin workout on Apple Watch or iPhone
![Page 155: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/155.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable• Keep session running when losing connectivity• Use HealthKit distance when GPS is unavailable
User should be able to begin workout on Apple Watch or iPhoneDisplay workouts from other sources
![Page 156: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/156.jpg)
Best Practices
Ensure Apple Watch app is functional when iPhone is unreachable• Keep session running when losing connectivity• Use HealthKit distance when GPS is unavailable
User should be able to begin workout on Apple Watch or iPhoneDisplay workouts from other sourcesDon’t display deleted workouts
![Page 157: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/157.jpg)
Summary
![Page 158: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/158.jpg)
Summary
Background running
![Page 159: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/159.jpg)
Summary
Background runningContribute to Activity rings
![Page 160: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/160.jpg)
Summary
Background runningContribute to Activity ringsStart workout from Apple Watch or iPhone
![Page 161: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/161.jpg)
More Information
https://developer.apple.com/wwdc16/235
![Page 162: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/162.jpg)
Related Sessions
Getting the Most out of HealthKit Wednesday
Health and Fitness with Core Motion Thursday
Introducing HealthKit WWDC 2014
Designing Accessories for iOS and OS X WWDC 2014
What’s New in HealthKit WWDC 2015
![Page 163: Building Great Workout Apps](https://reader031.fdocuments.net/reader031/viewer/2022012304/58a2c8921a28abd8728c147f/html5/thumbnails/163.jpg)