[머릿말]
테스트용으로 만든 서버에서 데이터를 받아와 앱에 띄우는 과정에서 이 경고를 마주하게 되었다.
이와 관련해서 이전에 GPT에게 무언가를 물어봤을 때 데이터의 갱신은 Main Thread에서 이뤄져야 한다고 답했던 기억이 어렴풋 난다. Synchronous, Asynchronous는 중요한 개념이므로 이 기회에 잘 정리해보고자 한다.
1. Main Thread vs Background Thread
SwiftUI에서 모든 UI 업데이트는 Main Thread에서 이뤄진다. 만약 시간이 오래걸리는 작업(ex. 다운로드 작업)을 Main Thread에서 수행한다면 해당 작업이 완료될 때까지 Main Thread는 다른 작업을 수행할 수 없으므로 앱이 일시정지된 것처럼 보이게 되고, 이는 좋지 않은 사용자 경험을 제공하게 된다.
이를 위해 시간이 걸리는 작업 등은 Main Thread가 아닌 Background Thread에서 비동기적(Asynchronous)으로 이뤄질 수 있도록 코드를 작성해야 한다. 그래야 작업이 수행되는 도중에도 앱의 사용이 가능하기 때문이다. 작업이 완료된 뒤에 최종 결과는 Main Thread에서 반영되도록 하여 UI 업데이트가 이뤄지도록 해야 한다.
1-1. 데이터 주도(Data Driven)
SwiftUI는 데이터의 변화에 따라 UI 업데이트가 이뤄지는 데이터 주도(Data Driven) 방식이다. 앞서 UI 업데이트는 Main Thread에서 이뤄져야 한다고 했는데, 이는 즉 데이터의 변화 역시 Main Thread에서 이뤄져야 함을 뜻한다.
또한 Background Thread는 UI 업데이트를 수행할 권한이 없기에 만약 Background Thread에서 데이터를 수정하면 예기치 못한 충돌(Crash)이 발생할 수 있다.
2. 내 코드에서 경고가 발생한 부분
내 코드에서 경고가 발생한 부분은 위 사진과 같다. 서버에서 데이터를 가져와 JSONDecoder를 사용하여 decode하고 그 결과를 Published 프로퍼티에 저장하는 부분에서 경고가 발생하였다. 즉, 데이터를 수정하는 부분에서 경고가 발생한 것이다.
사진 속 함수는 Background Thread에서 실행되는 비동기(async) 함수이다. Main Thread가 아닌 Background Thread에서 데이터의 수정이 이뤄지고 있으므로 위에서 언급한 것처럼 문제가 발생할 수 있기에 경고가 나타나게 된 것이다.
이 상태로 앱을 실행해보면 문제없이 실행될 때도 있지만 충돌(Crash)이 발생하여 앱이나 시뮬레이터가 종료될 때도 있었다.
2-1. 보라색 경고(Purple Warning)의 의미는?
보통 Xcode에서 경고(Warning)는 노란색으로 보여진다. 이는 컴파일 타임(Compile time)에서 확인되는 경고를 뜻한다. 반면 런타임(Runtime)에서 확인되는 경고는 실행 전에는 알 수 없으므로 빌드 전에는 나타나지 않다가 앱을 실행하던 도중에 보라색으로 보여진다.
3. 해결 방법
문제의 원인이 Background Thread에서 이뤄지는 값의 수정이므로 이를 Main Thread에서 이뤄지도록 해주면 문제는 해결된다.
3-1. DispatchQueue.main.async { ... }
이는 iOS 앱 개발에서 가장 많이 사용되는 코드로, Main Thread에서 실행될 작업을 전달할 때 사용한다.
DispatchQueue도 중요한 내용이기에 추후 관련 포스팅을 진행하여 여기에 링크로 첨부할 예정이다. 일단은 간단히만 알고 넘어가자🫠
아래 사진은 이를 내 코드에 적용한 결과다.
이렇게 하면 Background Thread에서 비동기 작업이 처리된 뒤 그 결과가 Main Thread에서 반영되게 된다. 앞서 발생했던 보라색 경고도 더이상 발생하지 않는다!
SwiftUI를 처음 공부할 때 비교적 초반에 async/await 관련 내용을 접하며 추후에 상당히 중요한 부분이 될 것이라는 생각을 했었다.
이 중요성을 기능 코드를 작성하는 요즘에 정말 자주 느끼고 있다.
단순 레이아웃을 짜는 것보다 재밌기도 하면서 봐도봐도 헷갈리기도 하고 그렇다...🤣
'[Programming Language] > [SwiftUI]' 카테고리의 다른 글
[SwiftUI] NavigationLink 파란색 오버레이 변경 방법 (0) | 2024.11.03 |
---|---|
[SwiftUI] NavigationStack 에서 back 버튼 색상 변경하는 방법 (0) | 2024.11.02 |
[SwiftUI] Non-constant range: argument must be an integer literal (1) | 2024.11.01 |
[SwiftUI] 라이트 모드(Light mode) or 다크 모드(Dark mode) 설정 방법 (0) | 2024.10.31 |
[SwiftUI] Invalid frame dimension (negative or non-finite) 오류 (0) | 2024.10.30 |