문제 상황
- 폴링을 통해서 5초마다 현재 친구의 상태를 받아와야하고 공부중인 친구는 1초마다 친구의 공부 시간이 업데이트되어야한다.
고민 과정
폴링 방식으로 친구의 공부 시간 업데이트 로직을 구현하기 위해서는 일단 각각의 Cell 내부에 있는 UILabel이 1초마다 업데이트가 되어야한다.
그러면 업데이트를 해주는 역할은 ViewModel, UICollectionViewCell 두 개의 객체중에 어떤 객체가 역할을 가져야할지에 대해서 고민했다.
먼저, CollectionViewCell에 각각의 타이머와 상태값을 둬 Cell이 비즈니스 로직과 업데이트까지 처리하는 방식으로 구현해봤다.
누가 관리해줘야할까…?
ViewModel
- 모든 친구의 공부 상태를 데이터로 가지고 있는다.
- 폴링을 통해 받은 친구의 공부 상태가 바뀌는 경우 cell에 있는 View을 업데이트 시킨다.
- 폴링 이전 공부중 & 폴링으로 받은 상태가 공부끝 → 타이머 종료, Cell 업데이트
- 폴링 이전 공부중 & 폴링으로 받은 상태가 공부중 → 타이머가 작동되지 않은 경우라면 타이머 시작, Cell 업데이트
- 폴링 이전 공부끝 & 폴링으로 받은 상태가 공부끝 → 아무것도 안함
- 폴링 이전 공부끝 & 폴링으로 받은 상태가 공부중 → 타이머 시작, Cell 업데이트
- 장점
- 비즈니스 로직은 ViewModel에서 처리를 하게 되고 CollectionViewCell은 단순 업데이트만 하면 되기 때문에 역할 분리가 된다.
- 타이머를 ViewModel에서 관리하면 되기 때문에 Cell마다 Timer을 생성할 필요가 없다.
- 단점
- 로직이 상당히 복잡해진다.
- 폴링은 5초마다. cell 업데이트는 1초마다……
- 1초마다 계속 특정 cell을 찾아서 업데이트를 해줘야한다.
- 업데이트해야되는 Cell이 여러개인 경우 처리가 늦어질 수 도 있다.
- 5초마다 폴링, 1초마다 공부중인 친구 Label 업데이트를 해줘야한다.
- 폴링 이전의 값을 가지고 있고, 현재 공부중인지 아닌지에 따라서 로직을 처리해줘야한다.
CollectionViewCell
- ViewController에서 ViewModel에서 받은 친구 폴링 상태를 바인딩해서 snapshot과 diffableDataSource을 통해 아이디 값을 비교하여 특정 Cell에게 현재 친구의 상태값을 전달해준다.