-
Notifications
You must be signed in to change notification settings - Fork 1
Combine을 활용한 데이터 전달
알쏭달쏭은 멀티플레이어 게임으로, 모든 기기에서 동일한 데이터를 실시간으로 동기화해야 하는 요구사항이 있었습니다. 이를 해결하기 위해 Firebase를 도입하여 서버 역할을 대신하고, Firebase에서 Firestore를 통해 데이터의 변경사항을 감지하고, Combine을 통해 데이터의 변경을 실시간으로 뷰모델과 View에 전달하는 구조를 구현하였습니다.
Combine을 사용한 주요 이유는 Firebase의 실시간 데이터 리스닝 기능과 원활하게 통합하기 위함이었습니다.
Firebase의 Firestore와 Realtime Database는 실시간으로 데이터 변경 사항을 감지할 수 있는 리스닝 기능을 제공합니다.
이러한 실시간 데이터 변경 사항에 대한 비동기 이벤트를 뷰까지 전달이 필요했습니다.
이 사이에 stream 이라는걸만들어서 연결시키고 데이터를 거기다가 흘려보내고 싶었고,
Combine 프레임워크를 사용하여 각기 다른 시간에 발생하는 비동기이벤트를 처리하기 위해 사용했습니다.
Firebase는 데이터를 Collection -> Document -> Field
계층 구조로 관리합니다.
그러나 Firebase SDK에서는 Document의 변경사항만을 감지할 수 있으며,
Field 단위의 변경사항은 직접적으로 감지할 수 없습니다.
저희 알쏭달쏭에서는 특정 필드의 변경사항을 실시간으로 감지하여
뷰모델과 하위 컴포넌트에 전달해야 하는 요구사항이 있었습니다.
이를 해결하기 위해 MainRepository와 하위 레포지토리로 구조를 분리하였습니다
-
MainRepository: Firestore의 Document 변경사항을 감지하고, 전체 Document 데이터를 MainRepository의
CurrentValueSubject
에 업데이트합니다. - 하위 레포지토리: MainRepository의 데이터를 구독하며, 특정 필드의 변경을 감지하여 필요한 컴포넌트에 전달하는 역할을 담당합니다. 이를 통해 Field 단위의 세밀한 변경사항을 관리할 수 있게 되었습니다.
- 비슷한 구독 로직이 여러 ViewModel이나 Repository에 중복될 수 있습니다.
- 여러 Publisher가 조합된 복잡한 데이터 흐름에서 문제가 발생했었 을 때, 데이터가 어떻게 흘러가는지 디버깅하기 어려웠습니다.
- 뷰 컴포넌트에서 Publisher만 bind할 수있도록 만들었는데, 항상 Published 데이터만 받아서 유연성이 조금 떨어짐
- 📒 기획의 과정과 의도
- 📒 swift6 도입기 ‐ @unchecked Sendable을 사용해야만 했던 이유
- 📒 WaveForm(파형) 제작기
- 📒 프로젝트 구조와 이유
- 📒 화면 전환(Game NavigationController)
- 📒 DIContainer를 사용한 계기
- 📒 AudioHelper 제작기
- 📒 음악 플레이어의 compact 버전 제작기
- 📒 Combine을 이용한 데이터 전달
- 📒 파이어베이스를 쓰며 있었던 일
- 📒 캐싱 모듈 구현과 문제점
- 📒 로그 시스템 제작기
- ❗ Data 끼리의 비교
- ❗ 프레임워크 Reference 안잡히는 문제
- ❗ actor 안에서 timer가 실행되지 않는 문제
- ❗ NSLayoutConstraint 옵셔널 문제
- ❗ 테이블 뷰가 보고 있는 배열과 bind하고 있는 배열 간의 race condition 문제
- ❗ 테스트끼리의 독립성
- ❗ 네트워크 테스팅 시 Error 핸들링
- ❗ 여러 클라이언트가 서버에 동시 요청시, 데이터가 반영이 안되는 이슈 해결
- ❗ 의존성 framework 추가시 불러오지 못하는 문제
- ❗ Timer를 6초 설정해도 더 실행되는 문제
- ❗ Music Kit Data Request 에러
- ❗ DI Container 에서 생성한 인스턴스가 동시에 존재 하는 이슈