Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at...

201
© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer Tools Session 411 #WWDC15

Transcript of Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at...

Page 1: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

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

Swift in PracticeFinding more issues at compile-time

Ted Kremenek Swift Team ManagerAlex Migicovsky Sample Code Engineer

Developer Tools

Session 411

#WWDC15

Page 2: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

This Talk

Page 3: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

This Talk

Take advantage of new APIs while deploying to older OS releases

Page 4: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

This Talk

Take advantage of new APIs while deploying to older OS releasesEnforce expected application behavior using enums and protocols

Page 5: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Taking Advantage of New APIs

Page 6: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs

Each OS release comes up with new APIs for appsBrings new functionality that enables richer experiences for users

Page 7: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs

Each OS release comes up with new APIs for appsBrings new functionality that enables richer experiences for users

Page 8: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Problem: Users on Different OS Releases

Page 9: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Problem: Users on Different OS Releases

Should you change your app to require the latest OS?

Page 10: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Problem: Users on Different OS Releases

Should you change your app to require the latest OS?

Should you hold back on adopting new features?

Page 11: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Problem: Users on Different OS Releases

Should you change your app to require the latest OS?

Should you hold back on adopting new features?

Adopt new features and support the older OS releases

Page 12: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Reality

Page 13: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

RealityIt is possible to do this today...

Page 14: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer
Page 15: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

...but now it is pain-free in Swift 2

Page 16: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Base SDK and Deployment Target

Page 17: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Always use the Latest SDK to access complete set of APIs...

Base SDK and Deployment Target

Page 18: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Always use the Latest SDK to access complete set of APIs...

Base SDK and Deployment Target

... use Deployment Target to set an application’s minimum supported OS release

Page 19: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

Page 20: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

9

8.4

...

8.0

7.1

7.0

Page 21: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

9

8.4

...

8.0

7.1

7.0

Base SDK

Page 22: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

9

8.4

...

8.0

7.1

7.0

Base SDK

Page 23: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

9

8.4

...

8.0

7.1

7.0

Base SDK Deployment Target

Page 24: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Example: Supporting Multiple iOS Releases

9

8.4

...

8.0

7.1

7.0

Base SDK

Deployment Target

Page 25: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs While Deploying BackExisting very painful method

Page 26: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs While Deploying BackExisting very painful method

Previously you needed separate considerations for adopting each of the following:• Frameworks• Classes• Methods• Functions• Enums

Page 27: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Mark Frameworks as Optional

RequiredOptional

Page 28: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Mark Frameworks as Optional

RequiredOptional

Page 29: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

if ([NSDataAsset class]) {      NSDataAsset *asset = [[NSDataAsset alloc] initWithName:@"Dragon"]; }

Page 30: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

if ([NSDataAsset class]) {      NSDataAsset *asset = [[NSDataAsset alloc] initWithName:@"Dragon"]; }

Class previously may have been internal API

Page 31: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

Class previously may have been internal API

Page 32: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

if ([NSDataAsset class]) {      NSDataAsset *asset = [[NSDataAsset alloc] initWithName:@"Dragon"]; }

Page 33: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

if ([NSData class]) {      NSDataAsset *asset = [[NSDataAsset alloc] initWithName:@"Dragon"]; }

Page 34: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Class Is Available

if ([NSData class]) {      NSDataAsset *asset = [[NSDataAsset alloc] initWithName:@"Dragon"]; }

Easy to make mistakes

Page 35: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Method Is Available

if ([view respondsToSelector:@selector(setSemanticContentAttribute:)]) { view.semanticContentAttribute = UISemanticContentAttributePlayback; }

Page 36: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Method Is Available

if ([view respondsToSelector:@selector(setSemanticContentAttribute:)]) { view.semanticContentAttribute = UISemanticContentAttributePlayback; }

Different syntax from classes

Easy to make mistakes

Page 37: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Manually Check if a Function Is Available

if (&CGPathCreateWithRoundedRect) { path = CGPathCreateWithRoundedRect(rect, cornerWidth, cornerHeight, transform); ... }

Yet another syntax!

Easy to make mistakes

Page 38: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enums?You are stuck with a manual OS version check

typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {       UIModalPresentationFullScreen = 0,       UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),       UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1 };

Page 39: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enums?You are stuck with a manual OS version check

typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {       UIModalPresentationFullScreen = 0,       UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),       UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),       UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),       UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1 };

You are stuck with a manual OS version checkGood luck getting that right

Page 40: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer
Page 41: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer
Page 42: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Observations

Deploying to earlier OS is technically possibleIt is easy to get wrongDifferent syntax for each availability checkFailure occurs on earlier OS releases, which are less tested in practice

Page 43: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs while Deploying BackThe new way

Page 44: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs while Deploying BackThe new way

Focus on using new APIs to build features

Page 45: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Adopting New APIs while Deploying BackThe new way

Focus on using new APIs to build featuresCompiler emits error if API is unsafely used• Unified syntax for conditionally using all API kinds• No special handling of optional frameworks needed

Page 46: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

Page 47: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

9.0

8.0

7.0

@available(iOS 8.0, *) func requestWhenInUseAuthorization()

@available(iOS 2.0, *) class CLLocationManager

API is always available

Page 48: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

9.0

8.0

7.0

@available(iOS 8.0, *) func requestWhenInUseAuthorization()

@available(iOS 2.0, *) class CLLocationManager

Page 49: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

9.0

8.0

7.0

@available(iOS 8.0, *) func requestWhenInUseAuthorization()

@available(iOS 2.0, *) class CLLocationManager

API is always available

Page 50: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

9.0

8.0

7.0

@available(iOS 8.0, *) func requestWhenInUseAuthorization()

@available(iOS 2.0, *) class CLLocationManager

Page 51: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

9.0

8.0

7.0

@available(iOS 8.0, *) func requestWhenInUseAuthorization()

@available(iOS 2.0, *) class CLLocationManager

API is used when it may not be available!

Page 52: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

Compile-Time API Availability Checking

Page 53: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

Compile-Time API Availability Checking

error: ‘requestWhenInUseAuthorization’ is only available on iOS 8.0 or newer

Page 54: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization()

Compile-Time API Availability Checking

note: guard with version check?

error: ‘requestWhenInUseAuthorization’ is only available on iOS 8.0 or newer

Page 55: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() if #available(iOS 8.0, *) { locationManager.requestWhenInUseAuthorization() }

Page 56: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() if #available(iOS 8.0, *) { locationManager.requestWhenInUseAuthorization() }

Compiler generates runtime check for host version

Page 57: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Compile-Time API Availability Checking

let locationManager = CLLocationManager() if #available(iOS 8.0, *) { locationManager.requestWhenInUseAuthorization() }

Compiler generates runtime check for host versionCompiler infers the minimum OS version needed from the APIs used

Page 58: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Why Check Based on OS Version?

Page 59: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Why Check Based on OS Version?

Features are defined by a collection of APIs• Checking for one API does not imply a collection of APIs are available• Features are tied to OS versions• Users are tied to OS versions

Page 60: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Why Check Based on OS Version?

Features are defined by a collection of APIs• Checking for one API does not imply a collection of APIs are available• Features are tied to OS versions• Users are tied to OS versions

Compiler-enforced• Availability checks are reliable• Unified syntax for availability checks

Page 61: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Multiple Platforms

if #available(iOS 9.0, *) { let asset = NSDataAsset(name: "Dragon") ... }

Page 62: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Multiple Platforms

if #available(iOS 9.0, OSX 10.11, *) { let asset = NSDataAsset(name: "Dragon") ... }

Page 63: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Multiple Platforms

if #available(iOS 9.0, OSX 10.11, *) { let asset = NSDataAsset(name: "Dragon") ...

The * indicates “require minimum deployment target for other platforms”

Writing * is mandatory to call out control-flow

}

Page 64: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Expressing Conditional Logic

if #available(iOS 9.0, OSX 10.11, *) { let asset = NSDataAsset(name: "Dragon") ... }

Page 65: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Expressing Conditional Logic

if #available(iOS 9.0, OSX 10.11, *) { let asset = NSDataAsset(name: "Dragon") ... }

Could be a lot of code within the if block, but none afterwards

Page 66: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Expressing Conditional Logic

guard #available(iOS 9.0, OSX 10.11, *) else { return } let asset = NSDataAsset(name: "Dragon") ...

Page 67: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Expressing Conditional Logic

guard #available(iOS 9.0, OSX 10.11, *) else { return } let asset = NSDataAsset(name: "Dragon") ...

Use a guard statement to bail out early (when applicable)Useful for when the code exclusively focuses on using new APIs

Page 68: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code

Page 69: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

Page 70: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() ... }

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

Page 71: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() ... }

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

iOS7API() ...

Page 72: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() ... }

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

iOS7API() ...

Page 73: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

func myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. }

Page 74: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

func myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. }

Page 75: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

func myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. if #available(iOS 8.0, *) { iOS8API() ... } }

Page 76: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Codefunc myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. if #available(iOS 8.0, *) { iOS8API() ... } }

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

Page 77: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Codefunc myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. if #available(iOS 8.0, *) { iOS8API() ... } }

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

@available(iOS 8.0, *)

Page 78: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Codefunc myFunctionThatUsesiOS8() { // Use iOS 7 (or earlier) APIs. if #available(iOS 8.0, *) { iOS8API() ... } }

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

@available(iOS 8.0, *)

Page 79: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Codefunc myFunctionThatUsesiOS8() { iOS8API() ... }

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

@available(iOS 8.0, *)

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

Page 80: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

func otherFunctionThatUsesiOS8() { iOS8API() ... }

Factoring Your Codefunc myFunctionThatUsesiOS8() { iOS8API() ... otherFunctionThatUsesiOS8() }

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

@available(iOS 8.0, *)

@available(iOS 8.0, *)

Page 81: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

func otherFunctionThatUsesiOS8() { iOS8API() ... if #available(iOS 9.0, *) { // Use iOS 9 APIs. myFunctionThatUsesiOS9() } }

func myFunctionThatUsesiOS9() { iOS9API() }

@available(iOS 9.0, *)

@available(iOS 8.0, *)

Factoring Your Codefunc myFunctionThatUsesiOS8() { iOS8API() ... otherFunctionThatUsesiOS8() }

// Deployment target is iOS 7. // Use iOS 7 (or earlier) APIs.

iOS7API() ...

if #available(iOS 9.0, *) { // Use iOS 9 (or earlier) APIs. iOS8API() iOS9API() }

if #available(iOS 8.0, *) { // Use iOS 8 (or earlier) APIs. iOS8API() myFunctionThatUsesiOS8() }

iOS7API() ...

@available(iOS 8.0, *)

Page 82: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code@available on methods

class MyClass { @available(iOS 8.0, *) func myMethodThatUsesiOS8() { ... }

func otherMethod() { ... } }

Page 83: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code@available on methods

class MyClass { @available(iOS 8.0, *) func myMethodThatUsesiOS8() { ... }

func otherMethod() { ... } }

Page 84: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code@available on methods

let myClass = MyClass() myClass.otherMethod()

if #available(iOS 8.0, *) { myClass.myMethodThatUsesiOS8() ... }

class MyClass { @available(iOS 8.0, *) func myMethodThatUsesiOS8() { ... }

func otherMethod() { ... } }

Page 85: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code@available on entire classes

class MyClass { @available(iOS 8.0, *) func myMethodThatUsesiOS8() {

func otherMethod() { ... }

}

}

...

Page 86: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Factoring Your Code@available on entire classes

@available(iOS 8.0, *) class MyClass { func myMethodThatUsesiOS8() {

func otherMethod() { ... }

}

}

...

Page 87: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

if #available(iOS 8.0, *) { let myClass = MyClass() myClass.otherMethod() myClass.myMethodThatUsesiOS8() }

Factoring Your Code@available on entire classes

@available(iOS 8.0, *) class MyClass { func myMethodThatUsesiOS8() { ... }

func otherMethod() { ... } }

Page 88: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

@available and Subclassing

Page 89: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

@available and Subclassingclass CustomBlurView : UIView { ... }

Page 90: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

@available and Subclassingclass CustomBlurView : UIView { ... }

func makeBlurView() -> UIView { if #available(iOS 8.0, *) { // Use newer UIKit view when available. return UIVisualEffectView(...) } return CustomBlurView(...) }

Page 91: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

@available and Subclassingclass CustomBlurView : UIView { ... }

func makeBlurView() -> UIView { if #available(iOS 8.0, *) { // Use newer UIKit view when available. return UIVisualEffectView(...) } return CustomBlurView(...) }

let blurView = makeBlurView()

Page 92: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

@available and Subclassingclass CustomBlurView : UIView { ... }

func makeBlurView() -> UIView { if #available(iOS 8.0, *) { // Use newer UIKit view when available. return UIVisualEffectView(...) } return CustomBlurView(...) }

let blurView = makeBlurView()

Page 93: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

API Availability Checking

Swift’s Availability checking catches unsafe uses of newer APIs at compile-timeUnified syntax for availability checkingFactor your apps logic around available APIs

Page 94: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enforcing Application Constraints

Alex Migicovsky Swift and Cocoa Lucid Dreamer

Page 95: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enforcing Application Constraints

Alex Migicovsky Swift and Cocoa Lucid Dreamer

zzz

Page 96: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer
Page 97: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

Page 98: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

Page 99: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

Page 100: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(named: "Isabella")!

let williamImage = UIImage(named: "William")!

let oliviaImage = UIImage(named: "Olivia")!

Page 101: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(named: "Isabella")!

let williamImage = UIImage(named: "William")!

let oliviaImage = UIImage(named: "Olivia")!

Page 102: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(named: "Isabella")!

let williamImage = UIImage(named: "William")!

let oliviaImage = UIImage(named: "Olivia")!

Page 103: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

"William"

"Olivia"

"Isabella"

Page 104: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

"William"

"Olivia"

"Isabella"

"Olivia""Olivia"

"Oivia"

"Olivia"

"Olivia"

"Olivia"

"Olivia"

"Olivia"

"Oliia"

"Olivia"

"Olivia"

"Isabella"

"Isabella"

"Isabella"

"Isabella"

"Isabella" "Isabela"

"Isabella"

"Isabella"

"Isabella""William"

"Willim"

"William"

"William""William"

"William""William"

"William"

Page 105: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

"William"

"Olivia"

"Isabella"

"Olivia""Olivia"

"Oivia"

"Olivia"

"Olivia"

"Olivia"

"Olivia"

"Olivia"

"Oliia"

"Olivia"

"Olivia"

"Isabella"

"Isabella"

"Isabella"

"Isabella"

"Isabella" "Isabela"

"Isabella"

"Isabella"

"Isabella""William"

"Willim"

"William"

"William""William"

"William""William"

"William"

Page 106: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

String Constants

let IsabellaUnicornImageName = "Isabella"

let isabellaImage = UIImage(named: IsabellaUnicornImageName)!

Page 107: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

String Constants

let IsabellaUnicornImageName = "Isabella"

let isabellaImage = UIImage(named: IsabellaUnicornImageName)!

Page 108: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

String Constants

let IsabellaUnicornImageName = "Isabella"

let isabellaImage = UIImage(named: IsabellaUnicornImageName)!

Page 109: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

String Constants

let IsabellaUnicornImageName = "Isabella"

let isabellaImage = UIImage(named: IsabellaUnicornImageName)!

let isabellaImage = UIImage(named: NSUbiquityIdentityDidChangeNotification)!

Page 110: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

String Constants

let IsabellaUnicornImageName = "Isabella"

let isabellaImage = UIImage(named: IsabellaUnicornImageName)!

let isabellaImage = UIImage(named: NSUbiquityIdentityDidChangeNotification)!

fatal error: unexpectedly found nil while unwrapping an Optional value

Page 111: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strings as Distinct Types

Stringly typed

Page 112: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strings as Distinct Types

typedStringly

Page 113: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strongly

Strings as Distinct Types

typed

Page 114: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strings as Distinct Types

Strongly typed

Page 115: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strings as Distinct Types

Strongly typedWanted:• Mapping between strings and a new type• UIImage non-failable init

Page 116: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Strings as Distinct Types

Strongly typedWanted:• Mapping between strings and a new type• UIImage non-failable init

Solution: application specific enums

Page 117: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(assetIdentifier: .Isabella)

let williamImage = UIImage(assetIdentifier: .William)

let oliviaImage = UIImage(assetIdentifier: .Olivia)

Page 118: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

extension UIImage {

enum AssetIdentifier: String {

}

}

Asset Catalog Identifiers

Page 119: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

extension UIImage {

enum AssetIdentifier: String {

case Isabella = "Isabella"

}

}

Page 120: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

extension UIImage {

enum AssetIdentifier: String {

case Isabella = "Isabella"

case William = "William"

case Olivia = "Olivia"

}

}

Page 121: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

extension UIImage {

enum AssetIdentifier: String {

case Isabella = "Isabella"

case William = "William"

case Olivia = "William"

}

}

Page 122: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

extension UIImage {

enum AssetIdentifier: String {

case Isabella = "Isabella"

case William = "William"

case Olivia = "William"

}

} error: raw value for enum case is not unique

Page 123: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

extension UIImage {

...

convenience init!(assetIdentifier: AssetIdentifier) {

self.init(named: assetIdentifier.rawValue)

}

}

Page 124: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(assetIdentifier: .Isabella)

let williamImage = UIImage(assetIdentifier: .William)

let oliviaImage = UIImage(assetIdentifier: .Olivia)

Page 125: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(assetIdentifier: .Isabella)

let williamImage = UIImage(assetIdentifier: .William)

let oliviaImage = UIImage(assetIdentifier: .Oliia)

Page 126: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(assetIdentifier: .Isabella)

let williamImage = UIImage(assetIdentifier: .William)

let oliviaImage = UIImage(assetIdentifier: .Oliia)

error: 'UIImage.AssetIdentifier.Type' does not have a member named 'Oliia'

Page 127: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Asset Catalog Identifiers

let isabellaImage = UIImage(assetIdentifier: .Isabella)

let williamImage = UIImage(assetIdentifier: .William)

let oliviaImage = UIImage(assetIdentifier: .Olivia)

Page 128: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

AssetIdentifier Enum Benefits

Centrally located constants

Page 129: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

AssetIdentifier Enum Benefits

Centrally located constantsDoesn’t pollute global namespace

Page 130: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

AssetIdentifier Enum Benefits

Centrally located constantsDoesn’t pollute global namespaceMust use one of the enum cases

Page 131: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

AssetIdentifier Enum Benefits

Centrally located constantsDoesn’t pollute global namespaceMust use one of the enum casesImage initializers are not failable

Page 132: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enums

Think about how you can use enums for compile time safety

Page 133: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Enums

Think about how you can use enums for compile time safetyEnums can be backed by more than just String (Int, Selector, Character, Double, etc.)

Page 134: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

Page 135: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowser Storyboard

Page 136: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowser Storyboard

UnicornBrowserViewController

ImportUnicornViewController CreateUnicornViewController

"ShowCreateNewUnicorn""ShowImportUnicorn"

Page 137: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

}

Page 138: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

switch segue.identifier {

case "ShowImportUnicorn"?: // Config...

case "ShowCreateNewUnicorn"?: // Config...

}

}

Segue Identifiers

Page 139: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

switch segue.identifier {

case "ShowImportUnicorn"?: // Config...

case "ShowCreateNewUnicorn"?: // Config...

}

}

Segue Identifiers

error: switch must be exhaustive, consider adding a default case

Page 140: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

switch segue.identifier {

case "ShowImportUnicorn"?: // Config...

case "ShowCreateNewUnicorn"?: // Config...

default: fatalError("Invalid segue identifier \(segue.identifier).")

}

}

Page 141: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

enum SegueIdentifier: String {

case ShowImportUnicorn = "ShowImportUnicorn"

case ShowCreateNewUnicorn = "ShowCreateNewUnicorn"

}

}

Page 142: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

}

Page 143: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

}

Page 144: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

}

Page 145: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

}

Page 146: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

switch segueIdentifier {

}

}

Page 147: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

switch segueIdentifier {

case .ShowImportUnicorn: // Config...

case .ShowCreateNewUnicorn: // Config...

}

}

Page 148: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

enum SegueIdentifier: String {

...

case ShowEditUnicorn = "ShowEditUnicorn"

}

Page 149: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

switch segueIdentifier {

case .ShowImportUnicorn: // Config...

case .ShowCreateNewUnicorn: // Config...

}

}

Page 150: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

switch segueIdentifier {

case .ShowImportUnicorn: // Config...

case .ShowCreateNewUnicorn: // Config...

}

}error: switch must be exhaustive, consider adding a default case

Page 151: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

Segues usually invoked by UIKitMay need to invoke with API

Page 152: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

Segues usually invoked by UIKitMay need to invoke with API

Page 153: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

func handleAction(sender: AnyObject?) {

performSegueWithIdentifier("ShowImportUnicorn", sender: sender)

}

}

Page 154: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

func handleAction(sender: AnyObject?) {

performSegueWithIdentifier(.ShowImportUnicorn, sender: sender)

}

}

Page 155: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

func performSegueWithIdentifier(segueIdentifier: SegueIdentifier,

sender: AnyObject?) {

}

}

Page 156: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

func performSegueWithIdentifier(segueIdentifier: SegueIdentifier,

sender: AnyObject?) {

performSegueWithIdentifier(segueIdentifier.rawValue, sender: sender)

}

}

Page 157: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

func handleAction(sender: AnyObject?) {

performSegueWithIdentifier(.ShowImportUnicorn, sender: sender)

}

}

Page 158: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

Page 159: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

UnicornBrowserViewController

UIViewController

Page 160: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

Mapping

Page 161: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

Mapping

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)Implementation

Page 162: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 163: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

Page 164: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

Page 165: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

Page 166: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 167: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 168: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController

UIViewController

enum SegueIdentifier case ShowImportUnicorn case ShowCreateNewUnicorn

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 169: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 170: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

Page 171: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

UnicornBrowserViewController Structure

performSegueWithIdentifier(_:sender:)

prepareForSegue(_:sender:)

UnicornBrowserViewController UnicornMetadataViewController

ImportUnicornViewController

Page 172: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

protocol SegueHandlerType {

}

Segue Identifiers

Page 173: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

protocol SegueHandlerType {

typealias SegueIdentifier

}

Page 174: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

protocol SegueHandlerType {

typealias SegueIdentifier: RawRepresentable

}

Page 175: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

extension SegueHandlerType

Page 176: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

extension SegueHandlerType where

Page 177: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

extension SegueHandlerType where

Self: UIViewController,

Page 178: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

extension SegueHandlerType where

Self: UIViewController,

SegueIdentifier.RawValue == String {

}

Page 179: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

extension SegueHandlerType where

Self: UIViewController,

SegueIdentifier.RawValue == String {

func performSegueWithIdentifier(segueIdentifier: SegueIdentifier,

sender: AnyObject?) {

performSegueWithIdentifier(segueIdentifier.rawValue, sender: sender)

}

}

Segue Identifiers

Page 180: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController {

enum SegueIdentifier: String {

...

}

}

Page 181: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController, SegueHandlerType {

enum SegueIdentifier: String {

...

}

}

Page 182: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController, SegueHandlerType {

enum SegueIdentifier: String {

...

}

}

Page 183: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

class UnicornBrowserViewController: UIViewController, SegueHandlerType {

...

func handleAction(sender: AnyObject?) {

performSegueWithIdentifier(.ShowImportUnicorn, sender: sender)

}

}

Page 184: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// SegueHandlerType.swift

func segueIdentifierForSegue(segue: UIStoryboardSegue) -> SegueIdentifier {

}

Page 185: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// SegueHandlerType.swift

func segueIdentifierForSegue(segue: UIStoryboardSegue) -> SegueIdentifier {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

}

Page 186: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// SegueHandlerType.swift

func segueIdentifierForSegue(segue: UIStoryboardSegue) -> SegueIdentifier {

guard let identifier = segue.identifier,

segueIdentifier = SegueIdentifier(rawValue: identifier)

else { fatalError("Invalid segue identifier \(segue.identifier).") }

return segueIdentifier

}

Page 187: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

}

Page 188: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

switch segueIdentifierForSegue(segue) {

}

}

Page 189: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Segue Identifiers

// UnicornBrowserViewController.swift

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

switch segueIdentifierForSegue(segue) {

case .ShowImportUnicorn: // Config...

case .ShowCreateNewUnicorn: // Config...

}

}

Page 190: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SegueHandlerType Protocol Benefits

Compiler errors when adding new segues if the new case isn’t handled

Page 191: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SegueHandlerType Protocol Benefits

Compiler errors when adding new segues if the new case isn’t handledReusable

Page 192: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SegueHandlerType Protocol Benefits

Compiler errors when adding new segues if the new case isn’t handledReusableConvenient syntax

Page 193: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Protocols

Tighten app constraints using protocols with associated types

Page 194: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Protocols

Tighten app constraints using protocols with associated typesShare implementation through a constrained protocol extension

Page 195: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SummaryThe compiler is here to help

Page 196: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SummaryThe compiler is here to help

Safely take advantage of new APIs

Page 197: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

SummaryThe compiler is here to help

Safely take advantage of new APIsLeverage strong typing to enforce application behavior

Page 198: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Related Session

Protocol-Oriented Programming in Swift Mission Wednesday 2:30PM

Page 199: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

Listerhttp://developer.apple.com/library/prerelease/ios/samplecode/Lister

DemoBotshttp://developer.apple.com/library/prerelease/ios/samplecode/DemoBots

Want to Have Lucid Dreams About Swift and Cocoa?

Page 200: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer

More Information

Swift Language Documentationhttp://developer.apple.com/swift

Apple Developer Forumshttp://developer.apple.com/forums

Stefan LesserDeveloper Tools [email protected]

Page 201: Swift in Practice - devstreaming-cdn.apple.com · Swift in Practice Finding more issues at compile-time Ted Kremenek Swift Team Manager Alex Migicovsky Sample Code Engineer Developer