•what’s new in foundation - apple developer · faster calendrical calculations with lower peak...

300
#WWDC17 © 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. Tony Parker, Foundation Michael LeHew, Foundation Itai Ferber, Foundation What’s New in Foundation Session 212 App Frameworks

Upload: others

Post on 23-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

#WWDC17

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

Tony Parker, Foundation Michael LeHew, Foundation Itai Ferber, Foundation

•What’s New in Foundation • Session 212

App Frameworks

Page 2: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•New API Highlights •Key Paths and Key Value Observation •Encoding and Decoding

Page 3: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•New API Highlights •Key Paths and Key Value Observation •Encoding and Decoding

Page 4: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•New API Highlights •Key Paths and Key Value Observation •Encoding and Decoding

Page 5: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•New API Highlights •Key Paths and Key Value Observation •Encoding and Decoding

Page 6: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•New API Highlights

Page 7: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Page 8: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Improved available storage space API

Page 9: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Improved available storage space API

Improved NSString ↔ Swift String range conversion

Page 10: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Improved available storage space API

Improved NSString ↔ Swift String range conversion

Discrete NSProgress support in NSXPCConnection

Page 11: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Improved available storage space API

Improved NSString ↔ Swift String range conversion

Discrete NSProgress support in NSXPCConnection

Thermal notifications on iOS

Page 12: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

New Foundation Features

File provider communication

Improved available storage space API

Improved NSString ↔ Swift String range conversion

Discrete NSProgress support in NSXPCConnection

Thermal notifications on iOS

What’s New in Cocoa Grand Ballroom B Wednesday 9:00AM

Page 13: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Foundation Performance Improvements

Copy-on-write NSArray, NSDictionary, NSSet

Page 14: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Foundation Performance Improvements

Copy-on-write NSArray, NSDictionary, NSSet

Data inlining

Page 15: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Foundation Performance Improvements

Copy-on-write NSArray, NSDictionary, NSSet

Data inlining

Faster calendrical calculations with lower peak memory

Page 16: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Foundation Performance Improvements

Copy-on-write NSArray, NSDictionary, NSSet

Data inlining

Faster calendrical calculations with lower peak memory

Faster bridging of NSNumber to and from Swift

Page 17: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Foundation Performance Improvements

Copy-on-write NSArray, NSDictionary, NSSet

Data inlining

Faster calendrical calculations with lower peak memory

Faster bridging of NSNumber to and from Swift

Efficient Interactions with Frameworks Hall 2 Friday 1:50PM

Page 18: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Michael LeHew, Foundation

•Key Paths and Key Value Observing

Page 19: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Key Paths are important

Page 20: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

Page 21: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

var ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 22: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

var ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 23: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

var ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 24: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

var ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 25: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

let ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 26: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

let ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 27: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

let ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

// String

Page 28: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

let ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

Page 29: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Swift 3 String Key Paths

@objcMembers class Kid : NSObject { dynamic var nickname: String = "" dynamic var age: Double = 0.0 dynamic var bestFriend: Kid? = nil dynamic var friends: [Kid] = [] }

let ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath) ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

// valueForKeyPath(_: String) -> Any // setValue(_, forKeyPath: String) -> Any

Page 30: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Key Paths

Page 31: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal

Key Paths

Page 32: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal•Statically type-safe

Key Paths

Page 33: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal•Statically type-safe•Fast

Key Paths

Page 34: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal•Statically type-safe•Fast•Applicable to all values

Key Paths

Page 35: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal•Statically type-safe•Fast•Applicable to all values•Works on all platforms•

Key Paths

Page 36: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal •Statically type-safe •Fast •Applicable to all values •Works on all platforms

Key Paths

Page 37: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

•Property traversal •Statically type-safe •Fast •Applicable to all values •Works on all platforms

Key Paths

•SE-0161 Smart Key Paths

Page 38: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

.nicknameKid\

NEWNEW

Page 39: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Backslash

.nicknameKid\

NEWNEW

Page 40: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Base Type

Backslash

.nicknameKid\

NEWNEW

Page 41: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Dot

Base Type

Backslash

.nicknameKid\

NEWNEW

Page 42: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Property Name

Dot

Base Type

Backslash

.nicknameKid\

NEWNEW

Page 43: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Property Name

DotBackslash

.nicknameKid\

NEWNEW

Base Type

Page 44: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Property Name

DotBackslash

.nickname\

NEWNEW

Page 45: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Property Name

Property Name

Base Type

\Kid.nickname.characters

NEW

Page 46: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Property Name

Property Name

Base Type

\Kid.bestFriend?.nickname

Coming Soon

NEW

Page 47: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

SubscriptProperty Name

Base Type

\Kid.friends[0]

Coming Soon

NEW

Page 48: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

SubscriptBase Type

.[.startIndex]Data\

Coming Soon

NEW

Page 49: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

.[.startIndex]\

Coming Soon

NEW

Page 50: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Types Properties / Subscripts

Uniform Syntax

Page 51: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct class

@objc class

Types Properties / Subscripts

Uniform Syntax

Page 52: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct class

@objc class

let/var get/set

Stored or computed

Types Properties / Subscripts

Uniform Syntax

Page 53: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.age

Page 54: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.agelet age = ben[keyPath: ]

Page 55: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let age = ben[keyPath: \Kid.age]

Page 56: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let age = ben[keyPath: \Kid.age]

Page 57: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let age = ben[keyPath: \Kid.age]

Page 58: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let age = ben[keyPath: \Kid.age]

Page 59: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let age = ben[keyPath: \Kid.age]

Page 60: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

ben[keyPath: \Kid.nickname] = "Ben"

let age = ben[keyPath: \Kid.age]

Page 61: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

Page 62: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

Page 63: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

.celebrant]BirthdayParty

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

let birthdayKid = bensParty[keyPath: \

Page 64: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

.theme] = "Pirate"BirthdayParty

.celebrant]BirthdayParty

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

let birthdayKid = bensParty[keyPath: \

bensParty[keyPath: \

Page 65: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

"Pirate"

.celebrant]

.theme] =

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

let birthdayKid = bensParty[keyPath: \

bensParty[keyPath: \

Page 66: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

"Pirate"

.celebrant]

.theme] =

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

let birthdayKid = bensParty[keyPath: \

bensParty[keyPath: \

Page 67: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

"Ninja"

.celebrant]

.theme] =

// Using Swift 4 KeyPaths

struct BirthdayParty { let celebrant: Kid var theme: String var attending: [Kid] }

let bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])

let birthdayKid = bensParty[keyPath: \

bensParty[keyPath: \

Page 68: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.nickname

Page 69: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.nicknamelet nicknameKeyPath =

Page 70: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath<Kid, String>

\Kid.nicknamelet nicknameKeyPath =

Page 71: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath<Kid, String>Base Type

\Kid.nicknamelet nicknameKeyPath =

Page 72: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath<Kid, String>Property

TypeBase Type

\Kid.nicknamelet nicknameKeyPath =

Page 73: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

Page 74: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath<BirthdayParty, Double>

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

Page 75: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

let birthdayBoysAge = bensParty[keyPath: birthdayKidsAgeKeyPath]

Page 76: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

let birthdayBoysAge = bensParty[keyPath: birthdayKidsAgeKeyPath]

Page 77: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

let birthdayBoysAge = bensParty[keyPath: birthdayKidsAgeKeyPath]

let mia = Kid(nickname: "Mia", age: 4.5) let miasParty = BirthdayParty(celebrant: mia, theme: "Space", attending: []))

Page 78: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths and Properties

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age

let birthdayBoysAge = bensParty[keyPath: birthdayKidsAgeKeyPath]

let mia = Kid(nickname: "Mia", age: 4.5) let miasParty = BirthdayParty(celebrant: mia, theme: "Space", attending: [])

let birthdayGirlsAge = miasParty[keyPath: birthdayKidsAgeKeyPath]

Page 79: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

Page 80: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double {

}

Page 81: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double {

}

Page 82: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double {

}

Page 83: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double { let kidsAgeKeyPath = participantPath.appending(\.age)

}

Page 84: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath<BirthdayParty, Double>

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double { let kidsAgeKeyPath = participantPath.appending(\.age)

}

Page 85: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double { let kidsAgeKeyPath = participantPath.appending(\.age) return party[keyPath: kidsAgeKeyPath] }

Page 86: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double { let kidsAgeKeyPath = participantPath.appending(\.age) return party[keyPath: kidsAgeKeyPath] }

let birthdayBoysAge = partyPersonsAge(bensParty, \.celebrant)

Page 87: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Appending Key Paths

func partyPersonsAge(party: BirthdayParty, participantPath: KeyPath<BirthdayParty, Kid>) -> Double { let kidsAgeKeyPath = participantPath.appending(\.age) return party[keyPath: kidsAgeKeyPath] }

let birthdayBoysAge = partyPersonsAge(bensParty, \.celebrant)

// Coming Soon let firstAttendeesAge = partyPersonsAge(bensParty, \.attendees[0])

Page 88: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

)\Kid.age(.appending\BirthdayParty.celebrant

The .appending Rule

Page 89: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.age.appending

\BirthdayParty.celebrant

The .appending Rule

Page 90: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\BirthdayParty.celebrant.age

\Kid.age.appending

\BirthdayParty.celebrant

The .appending Rule

Page 91: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,

KeyPath<Kid, Double>

KeyPath<BirthdayParty, Kid>

\BirthdayParty.celebrant.age

\Kid.age.appending

\BirthdayParty.celebrant

The .appending Rule

Page 92: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,

KeyPath<Kid, Double>

KeyPath<BirthdayParty, Kid>

The .appending Rule

Page 93: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,

KeyPath<Kid, Double>

KeyPath<BirthdayParty, Kid>

The .appending Rule

Page 94: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,

KeyPath<Kid, Double>

KeyPath<BirthdayParty, Kid>

The .appending Rule

Page 95: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,

The .appending Rule

Page 96: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,Base Type

The .appending Rule

Page 97: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Double>KeyPath<BirthdayParty,Base Type

Property Type

The .appending Rule

Page 98: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

Page 99: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

Page 100: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

String

Page 101: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

String [Kid]

Page 102: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Kid

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

String [Kid]

Page 103: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

[PartialKeyPath<BirthdayParty>]

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

Page 104: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

for (title, partyPath) in zip(titles, partyPaths) { let partyValue = miasParty[keyPath: partyPath] print("\(title)\n\(partyValue)\n") }

Page 105: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

for (title, partyPath) in zip(titles, partyPaths) { let partyValue = miasParty[keyPath: partyPath] print("\(title)\n\(partyValue)\n") }

Page 106: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

for (title, partyPath) in zip(titles, partyPaths) { let partyValue = miasParty[keyPath: partyPath] print("\(title)\n\(partyValue)\n") }

Page 107: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

for (title, partyPath) in zip(titles, partyPaths) { let partyValue = miasParty[keyPath: partyPath] print("\(title)\n\(partyValue)\n") }

Page 108: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Theme Space

Attending ["Ben"]

Birthday Kid Mia

// Type Erased Key Paths

let titles = ["Theme", "Attending", "Birthday Kid"] let partyPaths = [\BirthdayParty.theme, \BirthdayParty.attending, \BirthdayParty.celebrant]

for (title, partyPath) in zip(titles, partyPaths) { let partyValue = miasParty[keyPath: partyPath] print("\(title)\n\(partyValue)\n") }

Page 109: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty {

}

Page 110: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) {

} }

Page 111: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) {

} }

Page 112: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 113: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 114: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 115: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

error: Cannot assign to immutable expression of type 'Double'

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 116: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 117: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 118: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

Page 119: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 120: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 121: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 122: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 123: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 124: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 125: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 126: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 127: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { mutating func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 128: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { mutating func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 129: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { mutating func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 130: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct BirthdayParty { let celebrant: Kid }

// Mutating Key Paths

extension BirthdayParty { mutating func blowCandles(ageKeyPath: WritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 131: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: ReferenceWritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age) struct BirthdayParty { let celebrant: Kid }

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 132: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Mutating Key Paths

extension BirthdayParty { func blowCandles(ageKeyPath: ReferenceWritableKeyPath<BirthdayParty, Double>) { let age = self[keyPath: ageKeyPath] self[keyPath: ageKeyPath] = floor(age) + 1.0 } }

bensParty.blowCandles(ageKeyPath: \.celebrant.age)

assert(6.0 == ben.age)

struct BirthdayParty { let celebrant: Kid }

@objcMembers class Kid : NSObject { dynamic var age: Double }

Page 133: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Write directly into value-type base (inout/mutating)WritableKeyPath

Page 134: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Write into a reference-type baseReferenceWritableKeyPath

Write directly into value-type base (inout/mutating)WritableKeyPath

Page 135: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

WritableKeyPath<Base, Property>

ReferenceWritableKeyPath<Base, Property>

PartialKeyPath

KeyPath<Base, Property>

<Base>

Page 136: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

WritableKeyPath<Base, Property>

ReferenceWritableKeyPath<Base, Property>

PartialKeyPath

KeyPath<Base, Property>

<Base>

AnyKeyPath

Page 137: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Read-Only Properties

Page 138: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath

Read-Only Properties

Page 139: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Read-Write Properties

Page 140: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Read-Write Properties Mutable value type base

Page 141: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

WritableKeyPath

Read-Write Properties Mutable value type base

Page 142: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Read-Write Properties Immutable value type base

Page 143: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

KeyPath

Read-Write Properties Immutable value type base

Page 144: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Read-Write Properties Reference type base

Page 145: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

ReferenceWritableKeyPath

Read-Write Properties Reference type base

Page 146: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

Page 147: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

Page 148: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

Page 149: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

Page 150: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\BirthdayParty.attendees[0]

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

Page 151: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

index = 1 let sameAge = partyPersonsAge(party, whichKidKeyPath)

Page 152: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

index = 1 let sameAge = partyPersonsAge(party, whichKidKeyPath)

Page 153: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\BirthdayParty.attendees[0]

// Key Paths Capture By Value // Coming Soon

var index = 0 let whichKidKeyPath = \BirthdayParty.attendees[index] let firstAttendeesAge = partyPersonsAge(party, whichKidKeyPath)

index = 1 let sameAge = partyPersonsAge(party, whichKidKeyPath)

Page 154: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Key Paths

Page 155: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Key Value Observing

Page 156: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let observation = mia.observe(\.age) {

Page 157: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

} ...let observation = mia.observe(\.age) {

NEW

Page 158: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Observe using key path

} ...let observation = mia.observe(\.age) {

NEW

Page 159: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Observation

Observe using key path

} ...let observation = mia.observe(\.age) {

NEW

Page 160: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Reaction ClosureObservation

Observe using key path

} ...let observation = mia.observe(\.age) {

NEW

Page 161: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let observation = mia.observe(\.age) {

}

observed, change in

NEW

Page 162: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let observation = mia.observe(\.age) {

}

observed, change in

Kid

NEW

Page 163: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let observation = mia.observe(\.age) {

}

observed, change in

Kid

NSKeyValueObservedChange<Double>

NEW

Page 164: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid

init(kid: Kid) { representedKid = kid

} }

Page 165: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid var ageObservation: NSKeyValueObservation init(kid: Kid) { representedKid = kid

} }

Page 166: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid var ageObservation: NSKeyValueObservation init(kid: Kid) { representedKid = kid ageObservation = observe(\.representedKid.age) { observed, change in

} } }

Page 167: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid var ageObservation: NSKeyValueObservation init(kid: Kid) { representedKid = kid ageObservation = observe(\.representedKid.age) { observed, change in if observed.kid.age > 5 { print("Happy birthday \(observed.kid.nickname)! Time for kindergarten!") } } } }

Page 168: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid var ageObservation: NSKeyValueObservation init(kid: Kid) { representedKid = kid ageObservation = observe(\.representedKid.age) { observed, change in if observed.kid.age > 5 { print("Happy birthday \(observed.kid.nickname)! Time for kindergarten!") } } } } let controller = KindergartenController(kid: mia) miasParty.blowCandles(\.celebrant.age)

Page 169: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Happy birthday Mia! Time for kindergarten!

// Cocoa Adoption of Key Paths: KVO

@objcMembers class KindergartenController : NSObject { dynamic var representedKid: Kid var ageObservation: NSKeyValueObservation init(kid: Kid) { representedKid = kid ageObservation = observe(\.representedKid.age) { observed, change in if observed.kid.age > 5 { print("Happy birthday \(observed.kid.nickname)! Time for kindergarten!") } } } } let controller = KindergartenController(kid: mia) miasParty.blowCandles(\.celebrant.age)

Page 170: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

#keyPath(Kid.nickname)

Page 171: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.nickname

#keyPath(Kid.nickname)

Page 172: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

\Kid.nickname

Page 173: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Tony Parker, Foundation

•Encoding and Decoding

Page 174: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding and Decoding

Conversion between Swift data structures and archived formats

Page 175: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding and Decoding

Conversion between Swift data structures and archived formats

Swift and archived formats have strong typing mismatch

Page 176: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding and Decoding

Conversion between Swift data structures and archived formats

Swift and archived formats have strong typing mismatch

Solution is close integration with Swift

Page 177: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

Page 178: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

struct Author

let name: String

let email: String

let date: Date

}

{

Page 179: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

struct Author

let name: String

let email: String

let date: Date

}

{ : Codable

Page 180: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }

""".data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

Page 181: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

Page 182: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

Page 183: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

decoder.dateDecodingStrategy = .iso8601

Page 184: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

decoder.dateDecodingStrategy = .iso8601

Page 185: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

decoder.dateDecodingStrategy = .iso8601

let author = try decoder.decode(Author.self, from: jsonData)

Page 186: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

let jsonData = """

{ "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" } """.data(using: .utf8)!

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let decoder = JSONDecoder()

decoder.dateDecodingStrategy = .iso8601

let author = try decoder.decode(Author.self, from: jsonData)

Page 187: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

Page 188: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

Page 189: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

Page 190: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

{

"name": "Monalisa Octocat",

"email": "[email protected]",

"date": "2011-04-14T16:00:49Z"

}

Page 191: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Author : Codable {

let name: String

let email: String

let date: Date

}

Page 192: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Author : Codable {

let name: String

let email: String

let date: Date

}

Page 193: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Commit : Codable {

let url: URL

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let author: Author

let message: String

let comment_count: Int

}

Page 194: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Commit : Codable {

let url: URL

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let author: Author

let message: String

let comment_count: Int

}

let commit = try decoder.decode(Commit.self, from: jsonData)

Page 195: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Commit : Codable {

let url: URL

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let author: Author

let message: String

let comment_count: Int

}

let commit = try decoder.decode(Commit.self, from: jsonData)

Page 196: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Commit : Codable {

let url: URL

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let author: Author

let message: String

let comment_count: Int

}

let commit = try decoder.decode(Commit.self, from: jsonData)

let commitDate = commit.author.date

Page 197: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

{ "url": "https://api.github.com/.../6dcb09", "author": { "name": "Monalisa Octocat", "email": "[email protected]", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "comment_count": 0, }

struct Commit : Codable {

let url: URL

struct Author : Codable {

let name: String

let email: String

let date: Date

}

let author: Author

let message: String

let comment_count: Int

}

let commit = try decoder.decode(Commit.self, from: jsonData)

let commitDate = commit.author.date

Page 198: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Protocols

Codabletypealias Codable = Encodable & Decodable

Page 199: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Protocols

Codabletypealias Codable = Encodable & Decodable

public protocol Encodable {

func encode(to encoder: Encoder) throws

}

Encodable

Page 200: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Protocols

Codabletypealias Codable = Encodable & Decodable

public protocol Encodable {

func encode(to encoder: Encoder) throws

}

public protocol Decodable {

init(from decoder: Decoder) throws

}

Encodable

Decodable

Page 201: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Protocols

Use Swift protocol extension behavior

Page 202: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Protocols

Use Swift protocol extension behavior

Write your own implementation to customize

Page 203: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

Page 204: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

// Encodable public func encode(to encoder: Encoder) throws { /* … */ }

// Decodable init(from decoder: Decoder) throws { /* … */ }

Compiler Generated

Page 205: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

Page 206: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

Page 207: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

Page 208: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

private enum CodingKeys : String, CodingKey { case url case message case author case comment_count }

Page 209: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

private enum CodingKeys : String, CodingKey { case url case message case author case comment_count }

Compiler Generated

Page 210: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

private enum CodingKeys : String, CodingKey { case url case message case author case comment_count }

Customized

Page 211: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

private enum CodingKeys : String, CodingKey { case url case message case author case comment_count }

Page 212: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let comment_count: Int

private enum CodingKeys : String, CodingKey { case url case message case author case comment_count }

Page 213: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int

private enum CodingKeys : String, CodingKey { case url case message case author case commentCount = "comment_count" }

Page 214: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int

private enum CodingKeys : String, CodingKey { case url case message case author case commentCount = "comment_count" } }

Page 215: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Itai Ferber, Foundation

•Demo •Encoding and Decoding

Page 216: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Tony Parker, Foundation

•Encoding and Decoding

Page 217: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Codable Philosophy

•Error handling built-in •Encapsulate encoding details •Abstract format from types

Page 218: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Codable Philosophy

•Error handling built-in •Encapsulate encoding details •Abstract format from types

Page 219: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Error Handling

Unexpected input is not if, but when

Page 220: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Error Handling

Unexpected input is not if, but when

No fatal errors from untrusted data—only for developer mistakes

Page 221: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Error Handling

Unexpected input is not if, but when

No fatal errors from untrusted data—only for developer mistakes

Errors possible on decode and encode

Page 222: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coder Errors

Encoding • Invalid value

Page 223: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coder Errors

Encoding • Invalid value

Decoding • Type mismatch • Missing key • Missing value • Data corrupt

Page 224: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Beyond Basic Error Handling

Page 225: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Bytes

Beyond Basic Error Handling

Page 226: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Structured bytes

Bytes

Beyond Basic Error Handling

Page 227: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Typed data

Structured bytes

Bytes

Beyond Basic Error Handling

Page 228: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Domain-specific validation

Typed data

Structured bytes

Bytes

Beyond Basic Error Handling

Page 229: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Graph-level validation

Domain-specific validation

Typed data

Structured bytes

Bytes

Beyond Basic Error Handling

Page 230: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ }

Page 231: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url) message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

Page 232: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url) message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

Page 233: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url) message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

Page 234: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url) message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

Page 235: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url)

message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

Page 236: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) url = try container.decode(URL.self, forKey: .url)

message = try container.decode(String.self, forKey: .message)

author = try container.decode(Author.self, forKey: .author)

commentCount = try container.decode(Int.self, forKey: .commentCount)

} }

guard url.scheme == "https" else {

throw DecodingError.dataCorrupted(DecodingError.Context(

codingPath: container.codingPath + [CodingKeys.url],

debugDescription: "URLs require https")) }

Page 237: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Codable Philosophy

•Error handling built-in •Encapsulate encoding details •Abstract format from types

Page 238: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encapsulate Encoding Details

Keys and values are private

Containers provide storage for values

Page 239: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Keyed Containers

Page 240: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Keyed Containers

ValueKey :

ValueKey :

ValueKey :

{ }

Page 241: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys Strongly-typed replacement for String keys

public protocol CodingKey {

var stringValue: String { get }

var intValue: Int? { get }

init?(stringValue: String)

init?(intValue: Int)

}

Page 242: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

Page 243: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

private enum CodingKeys : String, CodingKey { case url case author case comment_count }

Page 244: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

private enum CodingKeys : String, CodingKey { case url case author case comment_count }

Case Name stringValue intValue?

url url nil

author author nil

comment_count comment_count nil

Page 245: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

private enum CodingKeys : String, CodingKey { case url case author case commentCount = "comment_count" }

Case Name stringValue intValue?

url url nil

author author nil

commentCount comment_count nil

Page 246: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

private enum CodingKeys : Int, CodingKey { case url = 42 case author = 100 case comment_count }

Case Name stringValue intValue?

url url 42

author author 100

comment_count comment_count 101

Page 247: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Coding Keys

private enum CodingKeys : Int, CodingKey { case url = 42 case author = 100 case comment_count }

Case Name stringValue intValue?

url url 42

author author 100

comment_count comment_count 101

Page 248: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Unkeyed Containers

Page 249: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Unkeyed Containers

[ ]Value , Value , Value,Value

Page 250: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Single Value Containers

Page 251: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Single Value Containers

Value

Page 252: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { /* … */ }

Page 253: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { /* … */ } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(url, forKey: .url) try container.encode(message, forKey: .message) try container.encode(author, forKey: .author) try container.encode(commentCount, forKey: .commentCount) } }

Page 254: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { /* … */ } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(url, forKey: .url) try container.encode(message, forKey: .message) try container.encode(author, forKey: .author) try container.encode(commentCount, forKey: .commentCount) } }

Page 255: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { /* … */ } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(url, forKey: .url) try container.encode(message, forKey: .message) try container.encode(author, forKey: .author) try container.encode(commentCount, forKey: .commentCount) } }

Page 256: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Commit : Codable { struct Author : Codable { /* … */ } let url: URL let message: String let author: Author let commentCount: Int private enum CodingKeys : String, CodingKey { /* … */ } public init(from decoder: Decoder) throws { /* … */ } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(url, forKey: .url) try container.encode(message, forKey: .message) try container.encode(author, forKey: .author) try container.encode(commentCount, forKey: .commentCount) } }

Page 257: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

Page 258: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

Page 259: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

public func encode(to encoder: Encoder) throws {

var container = encoder.unkeyedContainer()

try container.encode(x)

try container.encode(y) }

}

Page 260: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

public func encode(to encoder: Encoder) throws {

var container = encoder.unkeyedContainer()

try container.encode(x)

try container.encode(y) }

}

Page 261: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

public func encode(to encoder: Encoder) throws {

var container = encoder.unkeyedContainer()

try container.encode(x)

try container.encode(y) }

}

// [ 1.5, 3.9 ]

Page 262: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

struct Point2D : Encodable {

var x: Double

var y: Double

public func encode(to encoder: Encoder) throws {

var container = encoder.unkeyedContainer()

try container.encode(x)

try container.encode(y) }

}

// [ 1.5, 3.9 ]

Page 263: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Nested Containers

Lightweight encapsulation of additional values

ValueKey

ValueKey :

ValueKey :

{ }:

Page 264: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Nested Containers

Lightweight encapsulation of additional values

ValueKey

ValueKey :

ValueKey :

{ }:

Page 265: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Nested Containers

Lightweight encapsulation of additional values

ValueKey

Key :

ValueKey :

{ }:

Value , Value[ ], Value

Page 266: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding a Class Hierarchy

Use nested container for superclass data

Encapsulates keys and values from superclass

Page 267: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

}

Page 268: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

}

Page 269: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

} class Dog : Animal {

var bestFriend: Kid

private enum CodingKeys : String, CodingKey { case bestFriend }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

bestFriend = try container.decode(Kid.self, forKey: .bestFriend)

let superDecoder = try container.superDecoder()

try super.init(from: superDecoder)

}

}

Page 270: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

} class Dog : Animal {

var bestFriend: Kid

private enum CodingKeys : String, CodingKey { case bestFriend }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

bestFriend = try container.decode(Kid.self, forKey: .bestFriend)

let superDecoder = try container.superDecoder()

try super.init(from: superDecoder)

}

}

Page 271: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

} class Dog : Animal {

var bestFriend: Kid

private enum CodingKeys : String, CodingKey { case bestFriend }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

bestFriend = try container.decode(Kid.self, forKey: .bestFriend)

let superDecoder = try container.superDecoder()

try super.init(from: superDecoder)

}

}

Page 272: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

class Animal : Decodable {

var legCount: Int

private enum CodingKeys: String, CodingKey { case legCount }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

legCount = try container.decode(Int.self, forKey: .legCount)

}

} class Dog : Animal {

var bestFriend: Kid

private enum CodingKeys : String, CodingKey { case bestFriend }

required init(from decoder: Decoder) throws {

let container = try decoder.container(keyedBy: CodingKeys.self)

bestFriend = try container.decode(Kid.self, forKey: .bestFriend)

let superDecoder = try container.superDecoder()

try super.init(from: superDecoder)

}

}

Page 273: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Codable Philosophy

•Error handling built-in •Encapsulate encoding details •Abstract format from types

Page 274: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Abstract Format from Types

Reuse one implementation of Encodable and Decodable

Page 275: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Abstract Format from Types

Reuse one implementation of Encodable and Decodable

Allow new formats without library changes

Page 276: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Abstract Format from Types

Reuse one implementation of Encodable and Decodable

Allow new formats without library changes

Formats have different fundamental types and conventions

Page 277: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

Page 278: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Page 279: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

"2017-06-07T18:00:40Z"

Page 280: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

1496858440.0729699

Page 281: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

1496858440072.97

Page 282: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

"Wednesday, June 7, 2017 at 11:00 AM"

Page 283: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Data

"Wednesday, June 7, 2017 at 11:00 AM"

Page 284: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Data

"Wednesday, June 7, 2017 at 11:00 AM"

"AAIABAA="

Page 285: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Data

"Wednesday, June 7, 2017 at 11:00 AM"

[0,2,0,4,0]

Page 286: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Data

"Wednesday, June 7, 2017 at 11:00 AM"

"🐑🐶🐑🐶🐑"

Page 287: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Encoding Strategies

Encoder-specific customizations for certain types

JSON

Date

Data

Property Lists

"Wednesday, June 7, 2017 at 11:00 AM"

"🐑🐶🐑🐶🐑"

Page 288: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Codable Foundation Types

CGFloat AffineTransform Calendar CharacterSet Data Date DateComponents DateInterval Decimal

IndexPath IndexSet Locale Measurement NSRange PersonNameComponents TimeZone URL UUID

Page 289: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Page 290: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Page 291: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Encodable

Decodable

Page 292: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Encodable

Decodable

Encoder

Decoder

Page 293: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Encodable

Decodable

SingleValueEncodingContainer

UnkeyedEncodingContainer

KeyedEncodingContainer

KeyedDecodingContainer

UnkeyedDecodingContainer

SingleValueDecodingContainer

Encoder

Decoder

Page 294: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Encodable

Decodable

SingleValueEncodingContainer

UnkeyedEncodingContainer

KeyedEncodingContainer

KeyedDecodingContainer

UnkeyedDecodingContainer

SingleValueDecodingContainer

CodingKey

Encoder

Decoder

Page 295: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Your Type

Encodable

Decodable

SingleValueEncodingContainer

UnkeyedEncodingContainer

KeyedEncodingContainer

KeyedDecodingContainer

UnkeyedDecodingContainer

SingleValueDecodingContainer

CodingKey

JSONEncoder

PropertyListEncoder

PropertyListDecoder

JSONDecoder

Encoder

Decoder

Page 296: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Summary

New API and improved performance in Foundation

Strongly typed key paths for Swift

New Key-Value Observation API

New Codable protocols

Page 297: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

More Informationhttps://developer.apple.com/wwdc17/212

Page 298: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Related Sessions

What’s New in Cocoa Grand Ballroom B Wednesday 9:00AM

Cocoa Development Tips Grand Ballroom B Friday 9:00AM

Efficient Interactions with Frameworks Hall 2 Friday 1:50PM

Page 299: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with

Labs

Foundation Lab Technology Lab C Wed 1:00PM-2:10PM

Page 300: •What’s New in Foundation - Apple Developer · Faster calendrical calculations with lower peak memory Faster bridging of NSNumber to and from Swift Efficient Interactions with