118
© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. #WWDC15 Best Practices for Progress Reporting Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232

Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

#WWDC15

Best Practices for Progress Reporting

Vince Spader Cocoa Frameworks Engineer

App Frameworks

Session 232

Page 2: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Agenda

IntroductionCompositionCancellation, pausing, and resumingUser interfaceBest practices

Page 3: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Page 4: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

NSProgress represents the completion of some work

Page 5: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Page 6: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Installing…Installing…

Page 7: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Page 8: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Page 9: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Makes it easy to report progress in your app across various components

Page 10: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Makes it easy to report progress in your app across various componentsCocoa APIs are reporting their progress via NSProgress• NSBundleResourceRequest• UIDocument• NSData

Page 11: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

Makes it easy to report progress in your app across various componentsCocoa APIs are reporting their progress via NSProgress• NSBundleResourceRequest• UIDocument• NSData

Helps with localization

Page 12: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Introduction

var totalUnitCount: Int64 var completedUnitCount: Int64 var fractionCompleted: Double { get }

Page 13: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Units

Page 14: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Units

BytesFilesPhotosPercentage pointsFraction of workAnything

Page 15: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Units

var indeterminate: Bool { get }

Returns true if totalUnitCount < 0 or completedUnitCount < 0

Page 16: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Localization

var localizedDescription: String! var localizedAdditionalDescription: String!

Page 17: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationlocalizedDescription, localizedAdditionalDescription

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240

Page 18: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Localizationkind

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.kind = NSProgressKindFile

Page 19: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationuserInfo

var userInfo: [NSObject : AnyObject] { get } func setUserInfoObject(AnyObject?, forKey: String)

Page 20: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationuserInfo

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.setUserInfoObject(97, forKey: NSProgressEstimatedTimeRemainingKey)

Page 21: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationNSProgressKindFile

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.kind = NSProgressKindFile progress.setUserInfoObject(NSProgressFileOperationKindDownloading, forKey: NSProgressFileOperationKindKey)

Page 22: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationNSProgressKindFile

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.kind = NSProgressKindFile progress.setUserInfoObject(NSProgressFileOperationKindDownloading, forKey: NSProgressFileOperationKindKey) progress.setUserInfoObject(url, forKey: NSProgressFileURLKey)

Page 23: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationNSProgressKindFile

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.kind = NSProgressKindFile progress.setUserInfoObject(NSProgressFileOperationKindDownloading, forKey: NSProgressFileOperationKindKey) progress.setUserInfoObject(7, forKey: NSProgressFileCompletedCountKey) progress.setUserInfoObject(9, forKey: NSProgressFileTotalCountKey)

Page 24: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

LocalizationNSProgressKindFile

let progress = NSProgress() progress.totalUnitCount = 5_312_764 progress.completedUnitCount = 419_240 progress.kind = NSProgressKindFile progress.setUserInfoObject(NSProgressFileOperationKindDownloading, forKey: NSProgressFileOperationKindKey) progress.setUserInfoObject(50443, forKey: NSProgressThroughputKey)

Page 25: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

ResponsibilitiesFor creators

If you create a progress, you are responsible for updating ittotalUnitCount kind userInfo completedUnitCount

Page 26: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

ResponsibilitiesFor clients

If you receive a progress, do not update ittotalUnitCount { get } completedUnitCount { get } fractionCompleted { get } localizedDescription { get } localizedAdditionalDescription { get }

Page 27: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

NSProgressReporting

protocol NSProgressReporting : NSObjectProtocol { var progress: NSProgress { get } }

Page 28: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

NSProgressReporting

protocol NSProgressReporting : NSObjectProtocol { var progress: NSProgress { get } }

Page 29: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

DemoIntroduction

Page 30: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Page 31: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Page 32: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Composition

Page 33: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Download

Composition

Page 34: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Download Verify

Composition

Page 35: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Download Verify Decompress

Composition

Page 36: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Download Verify Decompress

Composition

But, the user only sees one progress bar

Page 37: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

What you’re tracking might not be a single operation’s progress

Download Verify Decompress

Composition

But, the user only sees one progress bar

Page 38: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Download Verify Decompress

Composition

Page 39: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Overall

Download Verify Decompress

Composition

Page 40: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Overall

Download Verify Decompress

Composition

Page 41: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Portions of a parent’s totalUnitCount can be assigned to a child progress object, referred to as pendingUnitCount• This is in terms of the parent’s units, not the child’s• The parent’s pendingUnitCount is assigned to the child

Page 42: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

When a child finishes, the parent’s completedUnitCount is incremented by the pendingUnitCount • Do not update the completedUnitCount manually• Assign everything to children

Page 43: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Page 44: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import

Composition

Page 45: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Page 46: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Page 47: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Photo 1 Photo 2

1 of 2 photos 1 of 2 photos

Page 48: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Photo 12 steps

Photo 22 steps

1 of 2 photos 1 of 2 photos

Page 49: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Photo 12 steps

1 of 2 photos 1 of 2 photos

Photo 22 steps

Page 50: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Photo 12 steps

Download Filter Download Filter

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

1 of 2 photos 1 of 2 photos

Photo 22 steps

Page 51: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import2 photos

Composition

Photo 12 steps

Download512 kilobytes

Filter7 stages

Download34 megabytes

Filter4 stages

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

1 of 2 photos 1 of 2 photos

Photo 22 steps

Page 52: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import0 of 2 photos

0%

Composition

Photo 10 of 2 steps

0%

Download0 of 512 kilobytes

0%

Filter0 of 7 stages

0%

Download0 of 34 megabytes

0%

Filter0 of 4 stages

0%

1 of 2 photos 1 of 2 photos

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

Photo 20 of 2 steps

0%

Page 53: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Import0 of 2 photos

25%

Composition

Download512 of 512 kilobytes

100%

Filter0 of 7 stages

0%

Download0 of 34 megabytes

0%

Filter0 of 4 stages

0%

1 of 2 photos 1 of 2 photos

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

Photo 11 of 2 steps

50%

Photo 20 of 2 steps

0%

Page 54: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Filter7 of 7 stages

100%

Download0 of 34 megabytes

0%

Filter0 of 4 stages

0%

1 of 2 photos 1 of 2 photos

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

Photo 12 of 2 steps

100%

Import1 of 2 photos

50%

Download512 of 512 kilobytes

100%

Photo 20 of 2 steps

0%

Page 55: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Download512 of 512 kilobytes

100%

Filter7 of 7 stages

100%

Download34 of 34 megabytes

100%

Filter0 of 4 stages

0%

1 of 2 photos 1 of 2 photos

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

Photo 12 of 2 steps

100%

Import1 of 2 photos

75%

Photo 21 of 2 steps

50%

Page 56: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Download512 of 512 kilobytes

100%

Filter7 of 7 stages

100%

Download34 of 34 megabytes

100%

Filter4 of 4 stages

100%

1 of 2 photos 1 of 2 photos

1 of 2 steps 1 of 2 steps 1 of 2 steps 1 of 2 steps

Photo 12 of 2 steps

100%

Import2 of 2 photos

100%

Photo 22 of 2 steps

100%

Page 57: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionWeighting

Photo0 of 2 steps

0%

Download0 of 512 kilobytes

0%

Filter0 of 7 stages

0%

1 of 2 steps 1 of 2 steps

Page 58: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Filter0 of 7 stages

0%

Composition

Download512 of 512 kilobytes

100%

1 of 2 steps 1 of 2 steps

Photo1 of 2 steps

50%

Weighting

Page 59: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Download512 of 512 kilobytes

100%

Filter7 of 7 stages

100%

1 of 2 steps 1 of 2 steps

Photo2 of 2 steps

100%

Weighting

Page 60: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Composition

Photo2 steps

Download Filter

1 of 2 steps 1 of 2 steps

Weighting

Page 61: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionWeighting

Photo

Download Filter

Page 62: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionWeighting

Photo

Download Filter

Page 63: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionWeighting

Photo10 “steps”

Download Filter

9 of 10 “steps” 1 of 10 “steps”

Page 64: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionWeighting

Photo0 of 10 “steps”

0%

Download0 of 512 kilobytes

0%

Filter0 of 7 stages

0%

9 of 10 “steps” 1 of 10 “steps”

Page 65: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Download512 of 512 kilobytes

100%

CompositionWeighting

Filter0 of 7 stages

0%

9 of 10 “steps” 1 of 10 “steps”

Photo9 of 10 “steps”

90%

Page 66: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Download512 of 512 kilobytes

100%

Filter7 of 7 stages

100%

CompositionWeighting

9 of 10 “steps” 1 of 10 “steps”

Photo10 of 10 “steps”

100%

Page 67: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionImplicit

Page 68: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()

CompositionImplicit

Page 69: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()

Photo

CompositionImplicit

Page 70: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2

Photo2 steps

CompositionImplicit

Page 71: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)

Photo2 steps

CompositionImplicit

Page 72: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)

Photo2 steps

CurrentProgress

CompositionImplicit

Page 73: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)

Photo

1 of 2 steps

2 steps

CurrentProgress

CompositionImplicit

Page 74: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)startDownload() // NSProgress(totalUnitCount:…)

Photo

1 of 2 steps

2 steps

CurrentProgress

CompositionImplicit

Page 75: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)startDownload() // NSProgress(totalUnitCount:…)

Download

Photo

1 of 2 steps

2 steps

CurrentProgress

CompositionImplicit

Page 76: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)startDownload() // NSProgress(totalUnitCount:…)photoProgress.resignCurrent()

Download

Photo

1 of 2 steps

2 steps

CurrentProgress

CompositionImplicit

Page 77: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let photoProgress = NSProgress()photoProgress.totalUnitCount = 2photoProgress.becomeCurrentWithPendingUnitCount(1)startDownload() // NSProgress(totalUnitCount:…)photoProgress.resignCurrent()

Download

Photo

1 of 2 steps

2 steps

CompositionImplicit

Page 78: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionImplicit

Page 79: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionImplicit

If you support implicit composition• Create with NSProgress(totalUnitCount:) immediately• Document it

Page 80: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionImplicit

If you support implicit composition• Create with NSProgress(totalUnitCount:) immediately• Document it

If no child is added• resignCurrent will mark the pendingUnitCount as finished• The completedUnitCount will be updated

Page 81: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionExplicit

Page 82: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progress

CompositionExplicit

Page 83: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progress

Filter

CompositionExplicit

Page 84: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progresslet photoProgress = …

Filter

CompositionExplicit

Page 85: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progresslet photoProgress = …

Photo

Download

1 of 2 steps

2 steps

Filter

CompositionExplicit

Page 86: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progresslet photoProgress = …photoProgress.addChild(filterProgress, withPendingUnitCount:1)

Photo

Download

1 of 2 steps

2 steps

Filter

CompositionExplicit

Page 87: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

let filterProgress = filter.progresslet photoProgress = …photoProgress.addChild(filterProgress, withPendingUnitCount:1)

Photo

Download

1 of 2 steps

2 steps

Filter

1 of 2 steps

CompositionExplicit

Page 88: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CompositionImplicit vs. explicit

Use implicit composition if• You have a method that can’t return the NSProgress• Releases older than OS X10.11 and iOS 9

Otherwise, use explicit composition

Page 89: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

DemoComposition

Page 90: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Cancellation, Pausing, and Resuming

Page 91: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CancellationCreators

var cancellable: Bool var cancellationHandler: (() -> Void)? var cancelled: Bool { get }

Page 92: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

CancellationClients

func cancel()

• Sets cancelled to true• Invokes the cancellationHandler• Cancellation flows down to children• It’s permanent

Page 93: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Pausing and ResumingCreators

var pausable: Bool var pausingHandler: (() -> Void)? var resumingHandler: (() -> Void)? var paused: Bool { get }

Page 94: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Pausing and ResumingClients

func pause() func resume()

• Sets paused to true/false• Invokes the pausingHandler/resumingHandler• Pausing/resuming flows down to children

Page 95: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

DemoCancellation, pausing, and resuming

Page 96: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User Interface

Page 97: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User Interface

NSProgress properties are key value observable• Add KVO observers to update your UI• Not necessarily called on main thread

Page 98: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User InterfaceExample

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

Page 99: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User InterfaceExample

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

Page 100: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User InterfaceExample

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

Page 101: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User InterfaceExample

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

override func observeValueForKeyPath(keyPath: …, object: …, …, context: …) { if context == &observationContext && keyPath == "fractionCompleted" { NSOperationQueue.mainQueue().addOperationWithBlock { let progress = (object as! NSProgress) progressView.progress = Float(progress.fractionCompleted) } } else { super.observeValueForKeyPath(…) } }

Page 102: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

User InterfaceExample

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

override func observeValueForKeyPath(keyPath: …, object: …, …, context: …) { if context == &observationContext && keyPath == "fractionCompleted" { NSOperationQueue.mainQueue().addOperationWithBlock { let progress = (object as! NSProgress) progressView.progress = Float(progress.fractionCompleted) } } else { super.observeValueForKeyPath(…) } }

Page 103: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

override func observeValueForKeyPath(keyPath: …, object: …, …, context: …) { if context == &observationContext && keyPath == "fractionCompleted" { NSOperationQueue.mainQueue().addOperationWithBlock { let progress = (object as! NSProgress) progressView.progress = Float(progress.fractionCompleted) } } else { super.observeValueForKeyPath(…) } }

User InterfaceExample

Page 104: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

override func observeValueForKeyPath(keyPath: …, object: …, …, context: …) { if context == &observationContext && keyPath == "fractionCompleted" { NSOperationQueue.mainQueue().addOperationWithBlock { let progress = (object as! NSProgress) progressView.progress = Float(progress.fractionCompleted) } } else { super.observeValueForKeyPath(…) } }

User InterfaceExample

Page 105: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Best Practices

Page 106: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Best Practices

Don’t use fractionCompleted to determine completion• It’s a float• Use completedUnitCount >= totalUnitCount instead

(unless indeterminate or zero)

Page 107: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Best Practices

NSProgress instances cannot be reusedMake a new instance and provide an additional mechanism so clients know

Page 108: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Performance

Don’t update completedUnitCount in a tight loopDon’t forget that final update to 100%

Page 109: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Page 110: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own units

Page 111: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitly

Page 112: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitlyThe pendingUnitCount is in the parent’s units

Page 113: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitlyThe pendingUnitCount is in the parent’s unitsFor each progress object, you are either a creator or a client

Page 114: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitlyThe pendingUnitCount is in the parent’s unitsFor each progress object, you are either a creator or a clientUse the kind and userInfo properties to let us give a good localizedDescription

Page 115: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitlyThe pendingUnitCount is in the parent’s unitsFor each progress object, you are either a creator or a clientUse the kind and userInfo properties to let us give a good localizedDescriptionNSProgress can be a conduit for cancellation, pausing, and resuming work

Page 116: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

Summary

Each NSProgress object has its own unitsYou can compose NSProgress objects, either implicitly or explicitlyThe pendingUnitCount is in the parent’s unitsFor each progress object, you are either a creator or a clientUse the kind and userInfo properties to let us give a good localizedDescriptionNSProgress can be a conduit for cancellation, pausing, and resuming work Properties are KVO observable

Page 117: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User

More Information

DocumentationNSProgress Class ReferenceProgress Indicator Programming TopicsiOS Human Interface GuidelinesOS X Human Interface Guidelines

Sample CodePhotoProgress

http://developer.apple.com/library/

Technical SupportApple Developer ForumsDeveloper Technical Support

General InquiriesPaul Marcos, App Frameworks [email protected]

Page 118: Best Practices for Progress Reporting · Vince Spader Cocoa Frameworks Engineer App Frameworks Session 232. Agenda Introduction Composition Cancellation, pausing, and resuming User