1. 내용 캡쳐
- 로그인 이전 View를 로그인 성공 여부에 따라서 메인 뷰로 Route해주기 위해서 @Published를 사용하였습니다. 로그인 방식은 Local Authentication을 사용하는 방식을 채택하였으며, 인증을 수행 후 성공 시 아래 코드 27줄에서 볼 수 있듯, @Published된 변수 값 변경을 통한 뷰의 전환을 수행하도록 하였으나 보라돌이 에러를 마주치고 말았다. Xcode에서 잘 만나기 힘들지만 중요한 순간에 한번씩 만나게 되는 보라색 에러는 주로 메모리 관련된 오류이며, 당장에 문제가 없을 지라도, 충돌 시 앱이 동작하지 않을 수 있는 중요한 에러 중 하나이다.
2. 원인 분석
- Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
경고 내용에서도 알 수 있 듯, 백그라운드로부터 발생한 publishing 변경 사항은 허용되지 않는다. 따라서 메인 스레드에서 진행하라고 권고한다.
1) Face Id, 지문인증 등 기기 인증을 사용하게 해주는 Local Authentication은 비동기 처리로 진행된다.
- 비동기 처리는 주로 서버에 데이터를 요청하는 네트워크 통신에 사용되는데, 화면 구성을 처리하는 스레드와 다른 스레드를 활용해서 화면 스크롤에 지장이 없도록 하기 위해서 사용된다.
-> 따라서 메인 스레드는 블록되지 않고, 메인 스레드를 제외한 백그라운드 스레드에서 인증 처리를 수행하게 된다.
2) 백그라운드 스레드에서 인증 성공 후 @Published된 변수 값 변경을 통해서 사용자 눈에 보이는 UI를 변경하라고 수행한다.
- 이 경우 이미 메인 스레드는 요청 순서대로 처리하고 있는데, 다른 스레드에서 본인이 사용하고 작업하는 UI뷰를 수정하려고 하기 때문에 발생하는 오류이다.
- 결론적으로 SwiftUI에서 View를 그려주는 UI처리는 주로 메인스레드에서 작동하도록 설계되어있다. 따라서 해당 오류는 백그라운드 스레드에서 UI를 업데이트 하려고 하거나, 비동기로 인한 값에서 UI 관련 요청을 할 때 발생한다.
-> 따라서 해당 작업을 메인스레드에서 수행하도록 보장해주어야 한다.
3. 결과
- DispatchQueue.main.async를 메인스레드에서 비동기적으로 처리할 수 있도록 코드를 수정해주었다.
4. 참고
🐛 [SwiftUI] @Published 변수 값을 비동기를 통해 변경 시 'Publishing changes from background threads is not allowe
삡삡 안녕하세요 이서에요🥸. SwiftUI의 @Published를 사용하여 네트워크 통신을 통해 받아온 값으로 변경하는 도중 아래와 같은 경고 메시지를 확인하여 이를 해결하는 방법에 대해 포스팅하고자
velog.io
https://todayssky.tistory.com/5
[Swift] Swift의 비동기 처리 (2) DispatchQueue.main
안녕하세요🐱 이번에는 GCD에 포함되어 있는 DispatchQue.main에 대해 다루어 보려고 합니다. DispatchQueue.main는 메인 스레드에서 처리되는 Serial queue입니다. 모든 UI 작업이 여기서 수행해야 합니다. syn
todayssky.tistory.com
https://velog.io/@yongchul/iOSThread%EC%9D%98-%EA%B8%B0%EB%B3%B8%EA%B0%9C%EB%85%90
[iOS]Thread의 이해(1) - Main Thread와 Background Thread
Main Thread는 오직 한개 뿐이며, 나머지는 모두 Background Thread 입니다.우리가 일반적으로 작성하는 대부분의 코드는 MainThread에서 실행됩니다. 이 사실을 잘 의식하지 못하는 이유는 우리가 작성한
velog.io