-
[SwiftUI + TCA] 에러 Perceptible state was accessed but is not being tracked개발/Swift 2025. 2. 7. 09:10
iOS Clean Architecture & MVVM: RxSwift 완전 정복 강의 | 덤벨로퍼 - 인프런
덤벨로퍼 | , iOS Clean Architecture & MVVM: RxSwift 완전 정복현업에서 Clean Architecture와 MVVM 패턴은 이미 널리 사용되고 있으며, 많은 채용 공고에서도 필수 역량으로 요구되고 있습니다. 이 강의는 Clean Ar
www.inflearn.com
SwiftUI TCA로 기능을 구현중입니다. 아직 초보자 수준이라 매시간이 도전이고 고비입니다. 그러던 중 다음과 같은 에러가 나타났습니다. 런타임에 발생하며 크래시는 안 나지만 UI가 심하게 버벅이면서 에러가 자꾸 났습니다.Perceptible state was accessed but is not being tracked. Track changes to state by wrapping your view in a 'WithPerceptionTracking' view. This must also be done for any escaping, trailing closures, such as 'GeometryReader', `LazyVStack` (and all lazy views), navigation APIs ('sheet', 'popover', 'fullScreenCover', etc.), and others.
'Perceptible state was not tracked' 에러, 원인 파악하기
이 에러는 Swift 5.9에서 나온 Observation Tool에 대응하기 위해 Perceptible 매크로가 TCA 1.7에서 나오면서 관련된 내용이라고 합니다.store를 사용할 때 @Perception.Bindable var store: StoreOf<MyProfileUpdateNameReducer> 와 같이 사용합니다.@Perception.Bindable var store: StoreOf<MyProfileUpdateNameReducer>
이제 View에서는 store에서 상태값을 불러오고 send action 같은 행위를 할 텐데,
properly observe changes to a “perceptible” model // WithPerceptionTracking
“perceptible” model을 위해 **WithPerceptionTracking**으로 감싸서 쓰라고 합니다.그래서 가장 상위 뷰에 감싸줬습니다.var body: some View { WithPerceptionTracking { ....
첫 번째 난관: ForEach와 같은 Lazy View 문제근데 이게 아무리 감싸도 에러가 안 사라집니다. 스유에는 많은 “lazy” closures가 있습니다.ForEach 같이 excaping closure에서 view를 리턴하는 것들을 말합니다.얘네들 쓸 때 **WithPerceptionTracking**으로 감싸라고 합니다.ForEach(store.listItems, id: \\.self) { item in WithPerceptionTracking { MyView(item).. } }
이렇게 하니 에러가 사라졌습니다.두 번째 난관: TextField 바인딩 시 에러 발생
또 개발하다 TextField를 바인딩할 일이 있었는데, 이 에러가 또 나타났습니다. 그래서 자신감 있게 **WithPerceptionTracking**를 감싸줬습니다.let text: Binding<String> // store 로 부터 세팅함 WithPerceptionTracking { TextField(Localized.name, text: text) // .frame(height: 48) }
근데 에러가 안 사라졌습니다. 상위 뷰에서 이렇게 바인딩 했었습니다.MyTextField(text: Binding( get: { store.name }, set: { store.send(.inputName($0)) } ))
해결 방법 2: TCA 공식 바인딩 문법 활용
Binding()에 get set을 세팅해서 넘겨줬었습니다. 지우고 넣고 아무리 해도 에러가 사라지지 않아, 수소문 끝에 문제를 찾았는데 문제는 바인딩이었습니다.MyTextField(text: $store.name.sending(\.inputName))
이런식으로 바인딩해야함
공식문서 참조
'개발 > Swift' 카테고리의 다른 글
[Swift] 애니메이션 동작시 터치 이벤트가 동작 안하는 이유 (0) 2025.02.26 SwiftUI + TCA 활용 액션 시트 구현 confirmationDialog (0) 2025.02.07 TCA에서 AsyncStream 사용해서 타이머 구현하기 (0) 2025.01.15 [Tuist] 모듈 생성 과 모듈 내 테스트 타겟 생성 (0) 2025.01.14 [Swift] XIB 만 가지고 이벤트 핸들링 하는법, xib cell 내부에 또 cell 이있는경우 (0) 2024.12.21