Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ObservationSallowDive

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 ObservationSallowDive

Avatar for elmetal

elmetal PRO

June 21, 2023
Tweet

More Decks by elmetal

Other Decks in Programming

Transcript

  1. 8IZ0CTFSWBUJPO 0UIFSNFDIBOJTNTGPSPCTFSWBUJPOJO4XJGU  w ,70 LFZWBMVFPCTFSWJOH 
 ˠ/40CKFDUͷܧঝ͕ඞཁ 
 ˠΠϕϯτͷΠϯλʔηϓτ͔͠ఏڙ͞Εͳ͍ͷͰɺ௨஌͕XJMM4FUͱEJE4FUͷؒͰߦΘΕΔ

    ˠΠϕϯτཻ౓ʹ͸ॊೈੑ͕͋Δ͕ɺ߹੒ੑʹ͚ܽΔ 
 ˠ0CKFDUJWF$ϥϯλΠϜʹґଘ͢Δ 
 ˠLFZQBUIͰڧ͍ܕ෇͚͕͞Ε͍ͯΔʹ΋ؔΘΒͣɺ࣮ࡍ͸จࣈྻܕ෇͚͞Ε͍ͯΔ w 0CTFSWBCMF0CKFDU 
 ˠ%BSXJOͰ͔͠࢖͑ͳ͍ 
 ˠQSFDPODVSSFODZͳ$PNCJOF͕ඞཁ 
 ˠܕͷ४ڌ͚ͩͰͳ͘ɺ؍ଌ͞ΕΔϓϩύςΟʹA!1VCMJTIFEA͕ඞཁ ˠDPNQVUFEQSPQFSUZΛ௚઀؍ଌͰ͖ͳ͍ 
 ˠDIBOHFFWFOUͷ։࢝࣌ʹੜ੒͞ΕΔͷͰɺ৽͍͠஋͕ઃఆ͞ΕΔલʹશͯͷ஋͕ྲྀΕΔ
  2. 6TJOH!0CTFSWBCMF 6TJOH0CTFSWBUJPO @Observable class FoodTruckModel { var orders: [Order] =

    [] var donuts = Donut.all } Ξϊςʔγϣϯ͸ҰՕॴ શϓϩύςΟ͕τϥοΩϯάͰ͖Δ 
  3. &YQBOE.BDSP 6TJOH0CTFSWBUJPO @Observable class FoodTruckModel { @ObservationTracked var orders: [Order]

    = [] @ObservationTracked var donuts = Donut.all @ObservationIgnored private let _$observationRegistrar = ObservationRegistrar() internal nonisolated func access<Member>( keyPath: KeyPath<FoodTruckModel , Member> ) { _$observationRegistrar.access(self, keyPath: keyPath) } internal nonisolated func withMutation<Member, T>( keyPath: KeyPath<FoodTruckModel , Member>, _ mutation: () throws -> T ) rethrows -> T { try _$observationRegistrar.withMutation(of: self, keyPath: keyPath, mutation) } @ObservationIgnored private var _orders: [Order] = [] @ObservationIgnored private var _donuts = Donut.all } extension FoodTruckModel : Observable {} 
  4. 4XJGU6*QSPQFSUZUSBDLJOH 6TJOH0CTFSWBUJPO @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() } } } } } 
  5. 4XJGU6*QSPQFSUZUSBDLJOH 6TJOH0CTFSWBUJPO @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() } } } } } Ξϊςʔγϣϯ͕ෆཁ 
  6. 6TJOH!4UBUF 6TJOH1SPQFSUZ8SBQQFS 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 } } } } 
  7. 6TJOH!&OWJSPONFOU 6TJOH1SPQFSUZ8SBQQFS  @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() } } } }
  8. 6TJOH!#JOEBCMF 6TJOH1SPQFSUZ8SBQQFS  @Observable class Donut { var name: String

    } struct DonutView: View { @Bindable var donut: Donut var body: some View { TextField("Name", text: $donut.name) } }
  9. 4UPSJOH!0CTFSWBCMFUZQFTJO"SSBZ 6TJOH1SPQFSUZ8SBQQFS  @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() } } } } }