[swift] IGListDiffKit과 함께하는 타임라인 구현

이번 블로그 포스트에서는 IGListDiffKit을 사용하여 타임라인을 구현하는 방법에 대해 알아보겠습니다.

타임라인은 일련의 이벤트를 시간순으로 표시하는 UI 요소입니다. 사용자는 이벤트를 추가하거나 수정할 수 있으며, 최신 이벤트가 항상 상단에 표시되어야 합니다.

IGListDiffKit 소개

IGListDiffKit은 Instagram에서 개발된 List 기반의 데이터 비교 도구입니다. 이 도구는 배열의 변경 사항을 감지하고 효율적으로 업데이트하는 역할을 수행합니다. IGListDiffKit을 사용하면 타임라인과 같은 복잡한 UI를 쉽게 구현할 수 있습니다.

IGListDiffKit 설치

IGListDiffKit은 CocoaPods을 통해 설치할 수 있습니다. Podfile에 다음과 같이 IGListDiffKit을 추가합니다.

pod 'IGListDiffKit'

그리고 터미널에서 pod install 명령어를 실행하여 IGListDiffKit을 프로젝트에 추가합니다.

IGListDiffKit을 사용한 타임라인의 구현

  1. TimelineEvent 클래스 생성

    먼저 TimelineEvent라는 모델 클래스를 생성합니다. 이 클래스는 타임라인에서 표시할 이벤트에 대한 정보를 가지고 있습니다.

    class TimelineEvent {
        var id: String
        var timestamp: Date
        var text: String
           
        init(id: String, timestamp: Date, text: String) {
            self.id = id
            self.timestamp = timestamp
            self.text = text
        }
    }
    
  2. 데이터 소스 클래스 생성

    다음으로 TimelineDataSource라는 데이터 소스 클래스를 생성합니다. 이 클래스는 타임라인에 표시할 이벤트들을 관리하고, IGListDiffKit의 ListDiffable 프로토콜을 구현합니다.

    class TimelineDataSource: NSObject, ListAdapterDataSource {
           
        var events: [TimelineEvent] = []
           
        // MARK: - ListAdapterDataSource
           
        func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
            return events
        }
           
        func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
            return TimelineSectionController()
        }
           
        func emptyView(for listAdapter: ListAdapter) -> UIView? {
            return nil
        }
    }
    
  3. 섹션 컨트롤러 클래스 생성

    마지막으로 TimelineSectionController라는 섹션 컨트롤러 클래스를 생성합니다. 이 클래스는 각 이벤트를 표시하는 셀의 생성과 구성을 담당합니다.

    class TimelineSectionController: ListSectionController {
           
        var event: TimelineEvent?
           
        override func sizeForItem(at index: Int) -> CGSize {
            return CGSize(width: collectionContext?.containerSize.width ?? 0, height: 100)
        }
           
        override func cellForItem(at index: Int) -> UICollectionViewCell {
            let cell = collectionContext!.dequeueReusableCell(of: TimelineCell.self, for: self, at: index) as! TimelineCell
            cell.configure(with: event)
            return cell
        }
           
        override func didUpdate(to object: Any) {
            event = object as? TimelineEvent
        }
    }
    
  4. 타임라인 뷰 컨트롤러 생성

    최종적으로 TimelineViewController라는 뷰 컨트롤러를 생성합니다. 이 뷰 컨트롤러는 IGListKit의 ListAdapter를 사용하여 타임라인을 표시합니다.

    class TimelineViewController: UIViewController {
           
        let collectionView: UICollectionView = {
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .vertical
            return UICollectionView(frame: .zero, collectionViewLayout: layout)
        }()
           
        lazy var adapter: ListAdapter = {
            return ListAdapter(updater: ListAdapterUpdater(), viewController: self)
        }()
           
        let dataSource = TimelineDataSource()
           
        override func viewDidLoad() {
            super.viewDidLoad()
               
            adapter.collectionView = collectionView
            adapter.dataSource = dataSource
            adapter.reloadData()
        }
    }
    

마무리

IGListDiffKit을 사용하여 타임라인을 구현하는 방법에 대해 알아보았습니다. IGListDiffKit은 데이터 변경 사항을 효율적으로 처리하여 성능을 높이고, 컴포넌트 기반 아키텍처를 쉽게 구현할 수 있도록 도와줍니다. 타임라인 이외에도 IGListDiffKit은 다양한 UI 요소를 구현하는 데 유용합니다. IGListDiffKit에 대한 자세한 내용은 공식 문서를 참조하세요.