[SwiftUI] ObservableObject 뷰 업데이트
일반적으로 사용자 액션 없이 데이터 수정을 해도 뷰에 바로 반영이 안 되기 때문에 다음과 같이 해야 한다.
class DataModel : ObservableObject {
@Published public var state: Int
init(_ data: Int) {
self.state = data
}
}
struct ContentView: View {
@ObservedObject var data: DataModel
var body: some View {
HStack {
Text("\(self.data.state)")
}
}
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let dataModel = DataModel(0)
let contentView = ContentView(data: dataModel)
DispatchQueue.global().async {
while true {
DispatchQueue.main.async { // 업데이트는 꼭 메인 스레드에서 해야 합니다.
contentView.data.objectWillChange.send() // 먼저 실행
}
_ = PseudoUpdater.refresh(dataModel) // pseudo: 업데이트 코드 실행
usleep(500_000)
}
}
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
// ...
}
이렇게 하면 다음과 같은 결과를 얻는다
- 씬을 초기화 할 때 DataModel의 state 프로퍼티를 0으로 초기화해 생성한다.
- 컨텐트 뷰를 미리 생성한 DataModel과 함께 생성한다.
- DispatchQueue를 이용해 글로벌 스레드에서 비동기 작업으로 다음과 같은 작업을 무한 반복한다.
- 메인 스레드에서 contentView의 data에 데이터가 바뀐다는 신호를 보낸다.
- 의사코드: dataModel에 대한 업데이트 작업을 진행한다.
- 0.5초 대기한다.
- 기본 씬 생성 코드...
이렇게 하면 외부 코드(여기서는 PseudoUpdater의 refresh 메서드)에 따라서 dataModel 내의 데이터가 변경될 것이고 이에 우리는 변경될 것이라는 것을 SwiftUI에 알려줬으니 수치가 변경 되면 알아서 반영해줄 것이다.
p.s. 별 거 아닌데 내 조잡한 영어 실력으로 구글링 하면 죄다 BindableObject 같은 말도 안 되는 Deprecated 된 예시만 들어서 몇 시간 꼴았다. 갈 곳 잃은 분노를 식히고 하루 지나서야 포스트 작성.
'공부 > Swift/Objective-C' 카테고리의 다른 글
[Xcode] Xcode 구버전 다운 받기 (0) | 2015.02.19 |
---|---|
Section02. Project in iOS - 첫 앱 만들기 - iAlgebra 계산기 (2) (0) | 2014.08.23 |
Section02. Project in iOS - 첫 앱 만들기 - iAlgebra 계산기 (1) (0) | 2014.08.23 |
Section01. Project in iOS - Xcode5로 시작하기 (0) | 2014.08.22 |
Programing in Objective-C 2.0의 149p 연습문제가 너무 어렵다. (0) | 2014.03.14 |