Observable objects, environment objects, and @Published
SwiftUI/Building a complete project 2019. 11. 7. 15:20
Hacking with Swift 사이트의 강좌 번역본입니다.
Observable objects, environment objects, and @Published
[동영상 강좌 : https://youtu.be/q56YCnmnnME]
우리는 사람들이 항목을 선택하고 카트에 추가해서 주문하길 바랍니다. 이미 항목 배열을 가지고 있는 전용 Order 클래스를 주었으므로, 전용 주문 뷰에 보여주도록 항목들을 추가할 것입니다.
하지만 단점이 있습니다: ItemDetail 안쪽에 추가하는 경우에, 완진히 구분된 OrderView에서 그것들을 어떻게 보여줄수 있나요? 더 중요한 것은, 변하는 것에 따라 어떻게 2가지 모두 업데이트 하나요?
음, SwiftUI는 environment objects라는 훌륭한 해결책을 가지고 있습니다. 이것들은 뷰에서 무료로 사용할 수 있는 객체 이지만, 만들거나 관리하지 않습니다 - 그것들은 다른 곳에서 만들어지며, 뷰에서 사라지더라도 남아 있습니다.
앱에서, 앱을 실행할때 주문(order) 인스턴스를 만들고나서, 컨텐츠 뷰 안으로 전달할 것입니다. 컨텐츠 뷰 안쪽에 있는 모든 뷰(컨텐츠 뷰를 그 조상이라고 부를수 있는 모든 뷰)는 자동으로 해당 environment object를 접근할 것입니다. 더 좋은 것은, 뷰가 변경될때 다른 모든 장소에 있는 것도 자동으로 업데이트합니다.
지금 사용해봅시다. ContentView의 초기 인스턴스가 만들어지는 SceneDelegate.swift을 열어주세요. 이제 다음 프로퍼티를 제공합니다.
var order = Order()
앱이 시작할때 새로운 주문(order)을 만들고, 우리가 어떤 뷰를 보든 상관없이 유지합니다. 이제 willConnectTo 메소드 안에서 생성될때 ContentView 구조체 안쪽으로 전달 할 수 있습니다 - 다음 줄을 찾으세요.
let contentView = ContentView()
그리고 그것을 다음에 오는 것으로 교체하세요.
let contentView = ContentView().environmentObject(order)
코드를 컴파일 하려는 경우, 동작하지 않는다는것을 알게 될 것입니다 - Swift는 Argument type ‘Order’ does not conform to expected type ‘ObservableObject’(인자 타입 ‘Order'는 예상했던 타입 'ObservableObject'를 준수하지 않습니다) 라인을 오류로 표시 합니다.
이 의미는 SwiftUI가 사용자 인터페이스가 Order 클래스의 변경사항을 어떻게 감시해야 하는지 이해하지 못한다는 것입니다 - 데이터 변경되는 알림을 보내고 받는 방법을 이해하지 못합니다.
생각해보세요: 메뉴에서 음식을 선택하고 주문에 추가하는 경우, 주문 페이지에 즉시 나타나길 원합니다 - 갱신을 누르거나, 약간 기다리는 것을 원하지 않으며, 즉시 처리되길 원합니다. 그리고 그게 동작하려면, SwiftUI는 Order 같은 객체가 누군가 나를 보고 있다면, 내 데이터가 방금 바뀐것을 알아야 합니다.라고 말하는 표준 방법이 필요합니다.
이러한 표준은 이미 존재하고, 그것은 ObservableObject 프로토콜 입니다. ObservableObject를 준수하는 모든 것들을 SwiftUI 내부에서 사용할 수 있고, 값이 변경될때 공지를 게시해서 사용자 인터페이스를 업데이트 할 수 있습니다.
Apple은 변경 공지사항을 게시하는 몇가지 다른 방법을 제공하지만, 가장 쉬운 것은 변경 알림을 시작하는 프로퍼티 앞에 @Published 프로퍼티 래퍼(property wrapper)를 사용하는 것입니다. 프로퍼티 래퍼는 Swift 5.1에서 도입되었고, 프로퍼티가 읽고 쓰기는 방법을 제어할 수 있습니다. 이 경우에, 프로퍼티 앞에 @Published을 붙이는 것으로 그 변경사항을 보고 SwiftUI 뷰를 업데이트하기에 충분합니다 - 정말로 강력합니다.
따라서, Order.swift를 열고 items 프로퍼티를 변경합니다.
@Published var items = [MenuItem]()
그게 다 입니다! 이제 우리 클래스는 제대로 구성되었으며, 다음과 같이 ObservableObject를 준수하도록 만들 수 있습나다.
class Order: ObservableObject {
그리고 우리 코드는 다시 컴파일합니다.
'SwiftUI > Building a complete project' 카테고리의 다른 글
Two-way bindings in SwiftUI (0) | 2019.11.13 |
---|---|
Bindings and forms (0) | 2019.11.08 |
Adding TabView and tabItem() (0) | 2019.11.08 |
Adding items to an order with @EnvironmentObject (0) | 2019.11.08 |
Displaying a detail screen with NavigationLink (0) | 2019.11.07 |
Polishing designs with fonts and colors (0) | 2019.11.06 |
Composing views to create a list row (0) | 2019.11.06 |
Building a menu using List (0) | 2019.11.06 |