• SwiftUI의 Observation 알아보기

    Observation을 통해 SwiftUI 데이터 모델을 단순화하세요. Observable 매크로는 모델을 단순화해 앱의 성능을 향상합니다. Observation과 매크로의 기초를 익히고 ObservableObject에서 Observable로 마이그레이션하는 방법을 확인하세요.

    챕터

    리소스

    관련 비디오

    WWDC23

  • 다운로드
    Array
    • 1:26 - Using @Observable

      @Observable class FoodTruckModel {    
          var orders: [Order] = []
          var donuts = Donut.all
      }
    • 2:12 - SwiftUI property tracking

      @Observable class FoodTruckModel {    
        var orders: [Order] = []
        var donuts = Donut.all
      }
      
      struct DonutMenu: View {
        let model: FoodTruckModel
          
        var body: some View {
          List {
            Section("Donuts") {
              ForEach(model.donuts) { donut in
                Text(donut.name)
              }
              Button("Add new donut") {
                model.addDonut()
              }
            }
          }
        }
      }
    • 3:12 - SwiftUI computed property tracking

      @Observable class FoodTruckModel {    
        var orders: [Order] = []
        var donuts = Donut.all
  var orderCount: Int { orders.count }
      }
      
      struct DonutMenu: View {
        let model: FoodTruckModel
          
        var body: some View {
          List {
            Section("Donuts") {
              ForEach(model.donuts) { donut in
                Text(donut.name)
              }
              Button("Add new donut") {
                model.addDonut()
              }
            }
            Section("Orders") {
              LabeledContent("Count", value: "\(model.orderCount)")
            }
          }
        }
      }
    • 4:41 - Using @State

      struct DonutListView: View {
          var donutList: DonutList
          @State private var donutToAdd: Donut?
      
          var body: some View {
              List(donutList.donuts) { DonutView(donut: $0) }
              Button("Add Donut") { donutToAdd = Donut() }
                  .sheet(item: $donutToAdd) {
                      TextField("Name", text: $donutToAdd.name)
                      Button("Save") {
                          donutList.donuts.append(donutToAdd)
                          donutToAdd = nil
                      }
                      Button("Cancel") { donutToAdd = nil }
                  }
          }
      }
    • 5:14 - Using @Environment

      @Observable class Account {
        var userName: String?
      }
      
      struct FoodTruckMenuView : View {
        @Environment(Account.self) var account
      
        var body: some View {
          if let name = account.userName {
            HStack { Text(name); Button("Log out") { account.logOut() } }
          } else {
            Button("Login") { account.showLogin() }
          }
        }
      }
    • 6:27 - Using @Bindable

      @Observable class Donut {
        var name: String
      }
      
      struct DonutView: View {
        @Bindable var donut: Donut
      
        var body: some View {
          TextField("Name", text: $donut.name)
        }
      }
    • 7:53 - Storing @Observable types in Array

      @Observable class Donut {
        var name: String
      }
      
      struct DonutList: View {
        var donuts: [Donut]
        var body: some View {
          List(donuts) { donut in
            HStack {
              Text(donut.name)
              Spacer()
              Button("Randomize") {
                donut.name = randomName()
              }
            }
          }
        }
      }
    • 9:18 - Manual Observation

      @Observable class Donut {
        var name: String {
          get {
            access(keyPath: \.name)
            return someNonObservableLocation.name 
          }
          set {
            withMutation(keyPath: \.name) {
              someNonObservableLocation.name = newValue
            }
          }
        } 
      }