[SwiftUI] View와 Interactor 간의 통신을 ObservableObject으로 우회하여 통신하기 - Delegate 패턴
08 February 2020
SwiftUI의 View는 struct이기 때문에, View를 소유하고 있는 곳(예, UIHostingController)에서 View에 일어난 행동(예, onAppear)를 어떻게 처리해야할지 고민을 했습니다.
View에는 Model을 Binding하여 View를 다시 그리게 하는 @ObservedObject
를 이용하는 것입니다.
기본적인 View와 ViewState를 만듭니다.
class ViewState: ObservableObject {
@Published var text: String = "Hello world"
}
struct MainView {
@ObservedObject var state: ViewState
var body: some View {
Text(state.text)
}
}
View가 나타날때 호출할 onAppear를 추가하여 ViewState가 이를 받도록 합니다.
class ViewState: ObservableObject {
@Published var text: String = "Hello world"
func onAppear() {
}
}
struct MainView {
@ObservedObject var state: ViewState
var body: some View {
Text(state.text)
.onAppear(perform: state.onAppear)
}
}
이제 ViewState를 발행하는 Interactor에서 onAppear를 처리하도록 protocol을 정의합니다.
struct MainView {
@ObservedObject var state: ViewState
var body: some View {
Text(state.text)
.onAppear(perform: state.onAppear)
}
}
protocol ViewStateListener: class {
func onAppear()
}
class ViewState: ObservableObject {
@Published var text: String = "Hello world"
weak var listener: ViewStateListener?
func onAppear() {
listener?.onAppear()
}
}
class Interactor: ViewStateListener {
@ObservedObject private var state: ViewState
init() {
self.state = ViewState()
// 부모 class가 있다면, super.init() 호출
self.state.listener = self
}
func onAppear() {
print(#file, #function)
}
}
이제 View에서 onAppear가 호출되었을 때, Interactor에서 특정 행동을 할 수 있게 되었습니다.