data flow through swiftui - devstreaming-cdn.apple.com · redistribution or public display not...
TRANSCRIPT
![Page 1: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/1.jpg)
#WWDC19
© 2019 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
Luca Bernardi, SwiftUI Engineer Raj Ramamurthy, SwiftUI Engineer
•Data Flow Through SwiftUI
![Page 2: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/2.jpg)
•Principles of Data Flow •Anatomy of an Update •Understanding Your Data
![Page 3: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/3.jpg)
•Principles of Data Flow •Anatomy of an Update •Understanding Your Data
![Page 4: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/4.jpg)
•Principles of Data Flow •Anatomy of an Update •Understanding Your Data
![Page 5: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/5.jpg)
What is data?
![Page 6: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/6.jpg)
Tools for Data Flow
Property
@Binding
BindableObject
@Environment
@State
![Page 7: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/7.jpg)
Data Access as a Dependency
PlayerView isPlaying: Bool
![Page 8: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/8.jpg)
Data Access as a Dependency
PlayerView isPlaying: Bool
![Page 9: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/9.jpg)
Data Access as a Dependency
PlayerView false
![Page 10: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/10.jpg)
Data Access as a Dependency
falsePlayerViewPlayerView
![Page 11: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/11.jpg)
Data Access as a Dependency
truePlayerView
![Page 12: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/12.jpg)
Source of Truth
![Page 13: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/13.jpg)
Source of Truth
accentColor: Color
isPlaying: Bool
store: MessageStore
post: PhotoPost
![Page 14: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/14.jpg)
Duplicated Source of Truth
View
ViewView
isPlaying: Bool isPlaying: Bool
![Page 15: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/15.jpg)
Duplicated Source of Truth
View
ViewView
isPlaying: Bool isPlaying: Bool
![Page 16: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/16.jpg)
Duplicated Source of Truth
View
ViewView
isPlaying: BoolisPlaying: Bool
![Page 17: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/17.jpg)
Single Source of Truth
View
ViewView
isPlaying: Bool
![Page 18: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/18.jpg)
Single Source of Truth
View
ViewView
isPlaying: Bool
![Page 19: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/19.jpg)
Single Source of Truth
View
ViewView
isPlaying: Bool
![Page 20: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/20.jpg)
![Page 21: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/21.jpg)
struct PlayerView : View { let episode: Episode
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray) } } }
![Page 22: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/22.jpg)
struct PlayerView : View { let episode: Episode
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray) } } }
![Page 23: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/23.jpg)
struct PlayerView : View { let episode: Episode
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray) } } }
![Page 24: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/24.jpg)
struct PlayerView : View { let episode: Episode
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray) } } }
![Page 25: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/25.jpg)
struct PlayerView : View { let episode: Episode var isPlaying: Bool
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 26: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/26.jpg)
struct PlayerView : View { let episode: Episode var isPlaying: Bool
var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 27: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/27.jpg)
struct PlayerView : View { let episode: Episode var isPlaying: Bool var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 28: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/28.jpg)
struct PlayerView : View { let episode: Episode var isPlaying: Bool var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 29: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/29.jpg)
struct PlayerView : View { let episode: Episode var isPlaying: Bool var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
Cannot use mutating member on immutable value: 'self' is immutable
![Page 30: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/30.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 31: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/31.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
false
![Page 32: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/32.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
false
![Page 33: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/33.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
true
![Page 34: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/34.jpg)
Wraps property access with additional behavior
What’s New in Swift WWDC 2019
Modern Swift API Design Thursday, 2:00
Property Wrapper
![Page 35: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/35.jpg)
@State Property Wrapper
@State private var isPlaying: Bool = false
PlayerView
SwiftUI
![Page 36: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/36.jpg)
@State Property Wrapper
@State private var isPlaying: Bool = false
PlayerView isPlaying = false
SwiftUI
![Page 37: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/37.jpg)
Anatomy of a View Update
PlayerView
ButtonTextText
SwiftUI isPlaying = false
![Page 38: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/38.jpg)
PlayerView
TextText
SwiftUI isPlaying = false
Anatomy of a View Update
Button
![Page 39: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/39.jpg)
PlayerView
TextText
SwiftUI isPlaying = false
Anatomy of a View Update
isPlaying = true
Button
![Page 40: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/40.jpg)
Anatomy of a View Update
PlayerView
SwiftUI
ButtonTextText
isPlaying = true
![Page 41: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/41.jpg)
Anatomy of a View Update
PlayerView
ButtonTextText
SwiftUI isPlaying = true
PlayerView
ButtonTextText
![Page 42: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/42.jpg)
Anatomy of a View Update
PlayerView
ButtonTextText
SwiftUI isPlaying = true
![Page 43: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/43.jpg)
Every @State is a source of truth.
![Page 44: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/44.jpg)
Views are a function of state, not of a sequence of events.
![Page 45: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/45.jpg)
!
![Page 46: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/46.jpg)
!
SwiftUI
![Page 47: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/47.jpg)
!User Interaction
SwiftUI
Action
![Page 48: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/48.jpg)
!User Interaction
SwiftUI
Action
![Page 49: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/49.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
![Page 50: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/50.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
![Page 51: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/51.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
View
Updates
![Page 52: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/52.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
View
Updates
![Page 53: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/53.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
View
Updates
Render
![Page 54: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/54.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 55: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/55.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 56: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/56.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 57: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/57.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
![Page 58: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/58.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton() } } }
![Page 59: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/59.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton() } } }
![Page 60: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/60.jpg)
struct PlayButton : View { @State private var isPlaying: Bool = false
var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 61: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/61.jpg)
struct PlayButton : View { @State private var isPlaying: Bool = false
var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 62: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/62.jpg)
struct PlayButton : View { @State private var isPlaying: Bool = false
var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 63: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/63.jpg)
@Binding Property Wrapper
Read and write without ownership
Derivable from @State
@Binding var isPlaying: Bool
![Page 64: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/64.jpg)
struct PlayButton : View { @Binding var isPlaying: Bool var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 65: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/65.jpg)
struct PlayButton : View { @Binding var isPlaying: Bool var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 66: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/66.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton(isPlaying: $isPlaying) } } }
![Page 67: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/67.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton(isPlaying: $isPlaying) } } }
![Page 68: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/68.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton(isPlaying: $isPlaying) } } }
![Page 69: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/69.jpg)
PlayerViewController
![Page 70: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/70.jpg)
PlayerView
PlayerViewController isPlaying
PlayButton
isPlaying
![Page 71: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/71.jpg)
PlayerView
PlayerViewController isPlaying
PlayButton
isPlaying
![Page 72: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/72.jpg)
PlayerView
PlayerViewController
isPlayingisPlaying
![Page 73: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/73.jpg)
PlayerView
PlayerViewController
isPlaying
PlayButton
isPlaying
![Page 74: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/74.jpg)
PlayerView
isPlaying
PlayButton
isPlaying
![Page 75: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/75.jpg)
API
![Page 76: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/76.jpg)
public struct Toggle<Label> : View { public init( isOn: Binding<Bool>, label: () -> Label ) }
public struct TextField : View { init( _ text: Binding<String> ) }
public struct Slider : View { public init<V : BinaryFloatingPoint>( value: Binding<V> ) }
API
![Page 77: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/77.jpg)
Views are for Data
Layout Visual Effects Navigation
Gestures Drawing Animations
![Page 78: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/78.jpg)
// Animated Changes
struct PlayButton : View { @Binding var isPlaying: Bool var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 79: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/79.jpg)
// Animated Changes
struct PlayButton : View { @Binding var isPlaying: Bool var body: some View { Button(action: { withAnimation { self.isPlaying.toggle() } }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 80: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/80.jpg)
// Animated Changes
struct PlayButton : View { @Binding var isPlaying: Bool var body: some View { Button(action: { withAnimation { self.isPlaying.toggle() } }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
![Page 81: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/81.jpg)
Raj Ramamurthy, SwiftUI Engineer
•Working With External Data
![Page 82: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/82.jpg)
Tools for Data Flow
@Binding
BindableObject
@Environment
@State
Property
![Page 83: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/83.jpg)
!
SwiftUI
![Page 84: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/84.jpg)
!User Interaction
SwiftUI
Action
State
Mutation
View
Updates
Render
![Page 85: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/85.jpg)
User Interaction
SwiftUI
Action
State
Mutation
View
Updates
Render
!🔔⏰
![Page 86: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/86.jpg)
User Interaction
SwiftUI
Action
State
Mutation
View
Updates
Render
!🔔⏰
Publisher
![Page 87: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/87.jpg)
Combine Publisher
Single abstraction
Main thread: use .receive(on:)
Introducing Combine and Advances in Foundation Thursday, 10:00
Combine in Practice Thursday, 2:00
![Page 88: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/88.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = true @State private var currentTime: TimeInterval = 0.0
var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton(isPlaying: $isPlaying)
Text("\(currentTime, formatter: currentTimeFormatter)") } } }
![Page 89: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/89.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = true @State private var currentTime: TimeInterval = 0.0
var body: some View { VStack { Text(episode.title).foregroundColor(isPlaying ? .white : .gray) Text(episode.showTitle).font(.caption).foregroundColor(.gray)
PlayButton(isPlaying: $isPlaying)
Text("\(currentTime, formatter: currentTimeFormatter)") } } }
![Page 90: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/90.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = true @State private var currentTime: TimeInterval = 0.0
var body: some View { VStack { // … Text("\(playhead, formatter: currentTimeFormatter)") } .onReceive(PodcastPlayer.currentTimePublisher) { newCurrentTime in self.currentTime = newCurrentTime } } }
![Page 91: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/91.jpg)
struct PlayerView : View { let episode: Episode @State private var isPlaying: Bool = true @State private var currentTime: TimeInterval = 0.0
var body: some View { VStack { // … Text("\(playhead, formatter: currentTimeFormatter)") } .onReceive(PodcastPlayer.currentTimePublisher) { newCurrentTime in self.currentTime = newCurrentTime } } }
![Page 92: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/92.jpg)
BindableObject Protocol
External
Reference type
Great for the model you already have
![Page 93: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/93.jpg)
class PodcastPlayerStore { var currentTime: TimeInterval var isPlaying: Bool var currentEpisode: Episode
func advance() { ... } func skipForward() { ... } func skipBackward() { ... } }
![Page 94: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/94.jpg)
class PodcastPlayerStore : BindableObject {
var didChange = PassthroughSubject<Void, Never>() // …
func advance() { currentEpisode = nextEpisode currentTime = 0.0 // Notify subscribers that the player changed didChange.send() } }
![Page 95: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/95.jpg)
class PodcastPlayerStore : BindableObject {
var didChange = PassthroughSubject<Void, Never>() // …
func advance() { currentEpisode = nextEpisode currentTime = 0.0 // Notify subscribers that the player changed didChange.send() } }
![Page 96: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/96.jpg)
Creating Dependencies on BindableObject
ViewModel
![Page 97: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/97.jpg)
Creating Dependencies on BindableObject
ViewModel
@ObjectBinding
![Page 98: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/98.jpg)
Creating Dependencies on BindableObject
ViewModel
@ObjectBinding
struct MyView :aView {a @ObjectBinding var model: MyModelObject ... }a
MyView(model: modelInstance)
![Page 99: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/99.jpg)
Creating Dependencies on BindableObject
ViewModel
@ObjectBinding
struct MyView :aView {a @ObjectBinding var model: MyModelObject ... }a
MyView(model: modelInstance)
![Page 100: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/100.jpg)
Creating Dependencies on BindableObject
View
@ObjectBinding
Model
struct MyView :aView {a @ObjectBinding var model: MyModelObject ... }a
MyView(model: modelInstance)
![Page 101: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/101.jpg)
Creating Dependencies on BindableObject
View
@ObjectBinding
Model
struct MyView :aView {a @ObjectBinding var model: MyModelObject ... }a
MyView(model: modelInstance)
![Page 102: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/102.jpg)
Creating Dependencies on BindableObject
View
@ObjectBinding
Model
Pass directly with @ObjectBinding
Automatic dependency tracking
struct MyView :aView {a @ObjectBinding var model: MyModelObject ... }a
MyView(model: modelInstance)
![Page 103: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/103.jpg)
Creating Dependencies Indirectly
View
View
View
Model
![Page 104: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/104.jpg)
Creating Dependencies Indirectly
View
View
View
Environment
Environment
Environment
Model
![Page 105: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/105.jpg)
Creating Dependencies Indirectly
Environment
Environment
Environment
.environmentObject()
Model
View
View
View
![Page 106: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/106.jpg)
Creating Dependencies Indirectly
Environment
Environment
Environment
@EnvironmentObject
.environmentObject()
Model
View
View
View
![Page 107: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/107.jpg)
Creating Dependencies Indirectly
Environment
Environment
Environment
.environmentObject()
Model
@EnvironmentObject
View
View
View@EnvironmentObject
![Page 108: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/108.jpg)
Creating Dependencies Indirectly
Environment
Environment
Environment
.environmentObject()
Model
@EnvironmentObject
View
View
View@EnvironmentObject
![Page 109: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/109.jpg)
struct PlayerView : View { @EnvironmentObject var player: PodcastPlayerStore var body: some View { VStack { Text(player.currentEpisode.title) .foregroundColor(isPlaying ? .white : .gray) Text(player.currentEpisode.showTitle) .font(.caption).foregroundColor(.gray) PlayButton(isPlaying: $player.isPlaying) Text("\(player.currentTime, formatter: playheadTimeFormatter)") } } }
![Page 110: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/110.jpg)
struct PlayerView : View { @EnvironmentObject var player: PodcastPlayerStore var body: some View { VStack { Text(player.currentEpisode.title) .foregroundColor(isPlaying ? .white : .gray) Text(player.currentEpisode.showTitle) .font(.caption).foregroundColor(.gray) PlayButton(isPlaying: $player.isPlaying) Text("\(player.currentTime, formatter: playheadTimeFormatter)") } } }
![Page 111: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/111.jpg)
@ObjectBinding
View View View View View View
Model
![Page 112: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/112.jpg)
@ObjectBinding
View View View View View View
Model
![Page 113: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/113.jpg)
@EnvironmentObject
View View View View View View
Model Environment
![Page 114: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/114.jpg)
@EnvironmentObject
View View View View View View
Model Environment
![Page 115: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/115.jpg)
Environment
•Data applicable to an entire hierarchy •Convenience for indirection •Accent color, right-to-left, and more
![Page 116: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/116.jpg)
Sources of Truth
@State BindableObject
View-local Value
Framework Managed
External Reference
Developer Managed
![Page 117: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/117.jpg)
Building Reusable Components
Read-only: Swift property, Environment
Read-write: @Binding
Prefer immutable access
![Page 118: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/118.jpg)
@Binding
First class reference to data
Great for reusability
Use $ to derive from source
@State @ObjectBinding
@Binding
@Binding
![Page 119: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/119.jpg)
Using State Effectively
Limit use if possible
Use derived Binding or value
Prefer BindableObject for persistence
Example: Button highlighting
![Page 120: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/120.jpg)
Next Steps
Minimize sources of truth
Understand your data
Build a great app!
![Page 121: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/121.jpg)
More Informationdeveloper.apple.com/wwdc19/226
SwiftUI Essentials WWDC 2019
Integrating SwiftUI Thursday, 3:00
Building Custom Views with SwiftUI Friday, 9:00
![Page 122: Data Flow Through SwiftUI - devstreaming-cdn.apple.com · Redistribution or public display not permitted without written permission from Apple. Luca Bernardi, SwiftUI Engineer Raj](https://reader030.vdocuments.us/reader030/viewer/2022011910/5f77cc4037e81316d866c0b0/html5/thumbnails/122.jpg)