[swift] IGListDiffKit을 활용한 방송 송출 구현

오늘은 IGListDiffKit을 활용하여 방송 송출 기능을 구현하는 방법에 대해 알아보겠습니다. IGListDiffKit은 iOS 앱에서 복잡한 리스트 UI를 관리하는 데 도움을 주는 강력한 도구입니다.

IGListDiffKit이란?

IGListDiffKit은 Facebook에서 개발된 오픈 소스 라이브러리로, iOS 앱에서 빠르고 효율적인 리스트 UI를 구현하기 위한 도구입니다. 이 라이브러리는 리스트의 데이터 변경을 추적하고, 변경된 부분만 업데이트하는 방식으로 성능을 향상시켜줍니다. IGListDiffKit을 사용하면 주어진 데이터 소스에 변경이 발생할 때마다 전체 리스트를 다시 그리는 것이 아니라 변경된 부분만 업데이트할 수 있어, 매끄러운 사용자 경험을 제공할 수 있습니다.

IGListDiffKit 사용 방법

  1. IGListDiffKit을 프로젝트에 추가합니다. CocoaPods를 사용하는 경우, Podfile에 다음을 추가하고 pod install 명령을 실행합니다.
pod 'IGListDiffKit'
  1. IGListDiffKit을 사용할 클래스에 IGListAdapterDataSource 프로토콜을 채택합니다.
class BroadcastViewController: UIViewController, IGListAdapterDataSource {
    // ...
}
  1. 데이터 모델과 데이터 소스를 구현합니다. IGListDiffable 프로토콜을 채택하는 데이터 모델을 만들고, 데이터 소스에서 해당 모델의 배열을 관리합니다.
class BroadcastViewController: UIViewController, IGListAdapterDataSource {
    private var broadcasts: [Broadcast] = []

    // ...

    // MARK: - IGListAdapterDataSource

    func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
        return broadcasts
    }

    func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
        return BroadcastSectionController()
    }

    func emptyView(for listAdapter: IGListAdapter) -> UIView? {
        // ...
    }
}

class Broadcast: NSObject, IGListDiffable {
    let id: String
    let title: String

    init(id: String, title: String) {
        self.id = id
        self.title = title
        super.init()
    }

    func diffIdentifier() -> NSObjectProtocol {
        return id as NSObjectProtocol
    }

    func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
        guard let object = object as? Broadcast else { return false }
        return id == object.id && title == object.title
    }
}
  1. 섹션 컨트롤러를 구현합니다. 섹션 컨트롤러는 데이터 모델을 표시할 셀을 생성하고, 셀에 데이터를 바인딩하는 역할을 합니다.
class BroadcastSectionController: IGListSectionController {
    private var broadcast: Broadcast?

    override func cellForItem(at index: Int) -> UICollectionViewCell {
        // 셀 생성 및 데이터 바인딩
    }

    override func sizeForItem(at index: Int) -> CGSize {
        // 셀 크기 반환
    }

    override func didSelectItem(at index: Int) {
        // 아이템 선택 시 동작 정의
    }

    override func didUpdate(to object: Any) {
        broadcast = object as? Broadcast
    }
}
  1. IGListAdapter를 생성하고 설정합니다.
class BroadcastViewController: UIViewController, IGListAdapterDataSource {
    private var broadcasts: [Broadcast] = []
    private lazy var adapter: IGListAdapter = {
        return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self)
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        adapter.dataSource = self
        adapter.collectionView = collectionView
    }
}
  1. 데이터 변경 시 IGListAdapter를 업데이트합니다. 데이터 소스에서 데이터 변경이 발생한 경우, 다음과 같이 adapter의 performUpdates 메서드를 호출하여 변경된 부분만 업데이트합니다.
class BroadcastViewController: UIViewController, IGListAdapterDataSource {
    // ...

    // 데이터 변경 예시
    func updateBroadcasts(newBroadcasts: [Broadcast]) {
        let result = IGListDiff(oldArray: broadcasts, newArray: newBroadcasts, option: .equality)
        self.broadcasts = newBroadcasts
        adapter.performUpdates(animated: true)
    }
}

결론

IGListDiffKit을 사용하면 iOS 앱에서 복잡한 리스트 UI를 효율적으로 관리할 수 있습니다. 이 라이브러리를 활용하여 방송 송출과 같은 기능을 구현하면, 데이터 변경 시 전체 리스트를 다시 그리지 않고 변경된 부분만 업데이트하여 성능을 향상시킬 수 있습니다. IGListDiffKit의 다양한 기능과 옵션을 잘 활용하면 매끄러운 사용자 경험을 제공할 수 있는 앱을 개발할 수 있습니다.

참고 자료