
문제점
💡 뷰를 푸시 즉시 API 호출을 통해 결제할 수 있는 상품 아이템 리스트를 가져오는 뷰
분명 아이템 배열이 표시가 되었지만 바로 사라지는 문제 발생

원하는 모습..!
문제 가능성
- API 통신이 2번 된다. (X)
⇒ print가 한번만 일어났다.
case .lists(let response):
print("list 받기 \(response)")
Task{@MainActor in
self.payAmountList = response
}

- 뷰 모델에 list가 2번 set된다. (X)
⇒ didSet으로 추적한 결과 한번만 일어났다.
@MainActor @Published var payAmountList: [PayAmountResponse] = []{
didSet{print("amountList:",payAmountList)}
}

View에 onChange를 이용해서 추적

🚨 분명 뷰 모델의 값은 1번만 바뀌었는데 2번 변경이 일어났다
문제 정의
뷰에서 뷰 모델의 추적이 제대로 되지 않는다. (데이터 정합성 문제)
- Swift Concurrency Actor 문제 (X)
⇒ 모든 값 할당을 MainActor에서 진행함
- SwiftUI Observing 관련 문제
⇒ 뷰 모델 Observing 프로퍼티를 StateObject로 바꿈 ✅
문제 원인
문제의 뷰 구조
struct PayView: View{
@ObservedObject var vm: PayVM
...
var body: some View{
ZStack{
listView
if vm.isPayment {
paymentView.frame(width: 0, height: 0).opacity(0)
.onBackgroundDisappear({
vm.action(type: .closePay)
}).environmentObject(vm)
}
}
}
@ViewBuilder var listView: some View{
...
Section {
ForEach(vm.payAmountList){ payAmount in
...
}
...
}
}
- 아이템 리스트(payAmount)를 표시하는 뷰를 ZStack으로 감싸고 있었다.
- 그 결과 뷰 모델에서 아이템 리스트 값이 바뀐 후, 상위 뷰에 있는 모든 데이터가 Re-Rendering 된다.
⚠️ 이 말은 뷰 모델에서 사용한 아이템 배열 값이 초기화 되어서 리스트를 뷰에 보여준다는 것이다. - 순서가 다음과 같이 진행하는 것이다.
- API를 통해 배열이 변경된다.
- 이 배열 값을 사용하는 리스트 뷰에서 변화를 준다.
- ObservedObject는 하위 뷰에서 사용하는 값만 변화가 생겨도 전체 뷰를 다시 그리는 역할을 한다.
⇒ 초기화를 진행한다. - 이로 인해, 이 뷰에서 사용하는 아이템 배열은 빈 배열이 된다.
문제 확인

사실 이 뷰 리스트 첫 번째 섹션에 있는 현재 코인 개수는 고정 값이었다.
✅ 이 값 또한, ObservedObject, 네트워크 통신을 통해서 나타내 보자
...
(Text("🌱 현재 보유한 코인") + Text(" \(vm.nowPossessionCoin)개")
.foregroundColor(.accentColor)).font(FontType.bodyBold.font)
...

기본 값 0으로 떨어지는 모습
StateObject로 변경 후 결과
StateObject | Apple Developer Documentation
A property wrapper type that instantiates an observable object.
developer.apple.com

✅ 뷰 모델에서 받은 데이터 그대로 값이 나타난다
'이모저모 > SwiftUI' 카테고리의 다른 글
| TCA - 뽀모도로 앱, Timer View Interaction (0) | 2024.05.07 |
|---|---|
| TCA에서 Stream 생성 및 주입 (0) | 2024.04.13 |
| Using @globalActor RealmSwift in TCA (0) | 2024.03.25 |
| TCA - Pagination TabView 사용 (0) | 2024.03.17 |
| Present, FullScreen 한 번에 처리하기 (0) | 2023.12.12 |
댓글