[swift] IGListDiffKit을 이용한 무한 스크롤 처리

많은 iOS 앱에서는 테이블 뷰나 컬렉션 뷰를 사용하여 데이터를 표시하고, 무한 스크롤 처리를 구현해야하는 경우가 많습니다. IGListDiffKit은 데이터를 업데이트하고, 변화된 부분만 업데이트하는 데 특화된 라이브러리입니다. 이번 포스트에서는 IGListDiffKit을 이용하여 무한 스크롤 처리를 구현하는 방법에 대해 알아보겠습니다.

IGListDiffKit 소개

IGListDiffKit은 코코아포드로 제공되는 오픈소스 라이브러리로, 데이터의 변경 사항을 추적하여 효율적인 업데이트를 가능하게 합니다. IGListDiffKit의 핵심은 큰 데이터 세트에서 변경 사항을 찾아내는 Diff 알고리즘입니다. 변경 내용을 찾아내고, 변화된 부분만 갱신함으로써 앱의 성능을 향상시킬 수 있습니다.

무한 스크롤 처리 구현하기

무한 스크롤 처리를 구현하기 위해서는 데이터를 동적으로 로드하고 기존의 데이터와 합쳐야합니다. IGListDiffKit은 이러한 데이터의 변경과 합침을 쉽게 처리할 수 있는 기능을 제공합니다.

먼저, 데이터를 관리하는 클래스를 만들어야합니다. 예를 들어, MyDataController라는 클래스를 생성하고, 다음과 같은 메소드를 구현합니다.

class MyDataController {
    var items: [String] = []
    
    func loadNextPage(completion: @escaping ([String]) -> Void) {
        // 다음 페이지 데이터를 로드한다.
        let nextPage = ...
        
        // 로드한 데이터를 기존 데이터와 합친다.
        let mergedItems = self.items + nextPage
        self.items = mergedItems
        
        // 합친 데이터를 반환한다.
        completion(mergedItems)
    }
}

다음으로, IGListKit에서 제공하는 IGListAdapterDataSource 프로토콜을 채택하여 데이터를 표시하는 뷰 컨트롤러를 생성합니다.

class MyViewController: UIViewController, IGListAdapterDataSource {
    let dataController = MyDataController()
    var items: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // IGListAdapter를 설정한다.
        let adapter = IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
        adapter.dataSource = self
        adapter.collectionView = collectionView
    }
    
    // 데이터를 업데이트하고 새로운 데이터를 로드하는 메소드
    func loadNextPage() {
        dataController.loadNextPage { [weak self] items in
            // 로드한 데이터를 업데이트한다.
            self?.items = items
            // IGListAdapter에 변경 내용을 알린다.
            adapter.performUpdates(animated: true)
        }
    }
    
    // MARK: - IGListAdapterDataSource
    
    // 데이터 소스 메소드를 구현한다.
    func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
        return items.map { IGListDiffableBox(value: $0) }
    }
    
    // 셀을 구성하는 메소드를 구현한다.
    func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
        return MySectionController()
    }
    
    func emptyView(for listAdapter: IGListAdapter) -> UIView? {
        return nil
    }
    
    // MARK: - UIScrollViewDelegate
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let threshold: CGFloat = 100
        let contentOffsetY = collectionView.contentSize.height - collectionView.bounds.height - scrollView.contentOffset.y
        
        if contentOffsetY < threshold {
            // 스크롤이 일정 값 이하로 내려갈 경우, 다음 페이지를 로드한다.
            loadNextPage()
        }
    }
}

위의 코드에서는 loadNextPage 메소드가 스크롤이 일정 값 이하로 내려갈 경우 호출되며, 다음 페이지를 로드하여 기존 데이터에 합칩니다. 그리고 IGListAdapterperformUpdates 메소드를 호출하여 변경 내용을 알립니다.

결론

IGListDiffKit을 사용하면 무한 스크롤 처리와 같은 데이터의 동적 로딩을 효율적으로 구현할 수 있습니다. IGListDiffKit을 사용하면 데이터 변경 사항을 추적하고, 변화된 부분만 갱신함으로써 앱의 성능을 개선할 수 있습니다. 추후 IGListKit을 사용하는 iOS 앱에서 무한 스크롤을 구현해야할 경우에는 IGListDiffKit을 고려해보세요.

참고 자료