SwiftUI #2

Data flow, State & Binding, ObservableObject

SwiftUI Architecture

SwiftUI Architecture

  • There are many
  • Reduced simply to Model-View
  • With a data Store to drive the view

State

  • Declare with @State var
  • Views are a function of state
  • Change the state (input) -> View will react accordingly

Binding

  • State is the source-of-truth
  • Binding is the "reference type" to the state

StateObject & ObservedObject

  • Equivalent to State & Binding
  • But for custom object types

Create your observable object

class Book: ObservableObject {
    @Published var title = "Great Expectations"
}

View observe the object

struct BookView: View {
    @ObservedObject var book: Book
    
    var body: some View {
        Text(book.title)
    }
}

Where is the source of truth?

struct MyApp: App {
    @StateObject private var book = Book()

    @SceneBuilder var body: some Scene {
        ...
        BookView(book: book)
        ...
    }
}

Passing via Environment

  • Another way to pass the Book to BookView
  • Environment is like a global scope, passing to any child views
  • No need to pass during view init BookView(book: book)

Passing via Environment

struct MyApp: App {
    @StateObject private var book = Book()

    @SceneBuilder var body: some Scene {
        BookView()
            .environmentObject(book)
        // Previously
        // BookView(book: book)
    }
}

Passing via Environment

struct BookView: View {
    @EnvironmentObject var book: Book

    // Previously
    // @ObservedObject var book: Book
    
    var body: some View {
        Text(book.title)
    }
}