[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple/UIKit

[UIKit] Diffable Datasource

inu 2021. 10. 20. 12:54
반응형
  • 기존의 DataSource와 UI는 각각 시간에 따라 변경되는 자신만의 버전(truth)을 가지고 있는데, 이것이 맞지 않으면 에러가 발생한다.
  • reloadData를 수행하기 전까지는 중앙화된 하나의 버전(truth)가 존재하지 않아 에러가 발생하기 쉽다.
  • reloadData를 수행하더라도 애니메이션없이 화면을 갱신하게 되기 때문에 사용자 경험을 저하시킬 수 있다.

Diffable Datasource

개념

  • 그에 따라 Apple에서 도입한 것이 Differble DataSource이다. performBatchUpdates()같은 복잡한 메소드를 사용하지 않고, apply()라는 하나의 메소드로 관리하게 된다.
  • Snapshot: UI의 버전(truth)를 저장하는 개념이다. 각 section과 item에 대한 unique identifier를 저장하고 이를 기반으로 업데이트를 수행한다. (IndexPath를 기반으로 업데이트하던 기존의 방식과 다른 점이다) apply()를 수행하면 새로운 snapshot이 적용된다.

사용방법

가장 먼저 UICollectionViewDiffableDataSource를 생성해야 한다. (TableView도 과정은 유사)

 

UICollectionViewDiffableDataSource의 정의를 보자.

  • 정의된 UICollectionViewDiffableDataSource를 보면 Generic Class임을 알 수 있다.
  • 또한 Generic에 해당하는 SectionIdentifierTypeItemIdentifierType 모두 Hashable을 준수하는 타입이어야한다.
  • cf. SectionIdentifierType : Section을 구분할 타입, 일반적으로 custom enum 혹은 int가 들어간다. (반드시 Hashable해야함)
  • cf. ItemIdentifierType : Item을 구분할 타입, 일반적으로 custom class가 들어간다. (반드시 Hashalbe해야함)
dataSource = UICollectionViewDiffableDataSource<Int, UUID>(collectionView: collectionView) {
    (collectionView: UICollectionView, indexPath: IndexPath, itemIdentifier: UUID) -> UICollectionViewCell? in
    // configure and return cell
}
  • 생성자를 통해 DiffableDataSource를 만든다. 나는 Apple 문서에 있는 예시를 그대로 사용했다.
  • collectionView 파라미터에는 dataSource가 사용될 collectionView를 넣어주면 된다.
  • 다음 파라미터가 되는 cellProvider(클로저)에는 cell을 구성하는 코드를 작성한다.
  • 클로저 내부에서 collectionView와 indexPath, itemIdentifier 모두 제공하기 때문에 이를 활용해 cell을 구현하면 된다. (collectionView에서 indexPath를 통해 cell을 가져오고 itemIdentifier를 기반으로 cell을 구성)

 

이제 Snapshot을 생성해서 apply해주어야 한다.

 

NSDiffableDataSourceSnapshot의 정의를 보자.

 

  • UICollectionViewDiffableDataSource와 마찬가지로 SectionIdentifierTypeItemIdentifierType를 필요로 한다.
  • UICollectionViewDiffableDataSource에서 선언해준 타입과 일치시켜주어야 한다.
// Create a snapshot.
var snapshot = NSDiffableDataSourceSnapshot<Int, UUID>()        

// Populate the snapshot.
snapshot.appendSections([0])
snapshot.appendItems([UUID(), UUID(), UUID()])

// Apply the snapshot.
dataSource.apply(snapshot, animatingDifferences: true)
  • 이제 NSDiffableDataSourceSnapshot을 통해 Snapshot을 생성하고 이를 datasource의 apply메소드에 전달해주는 방식으로 업데이트를 진행한다.
  • 원하는 곳에 위와 같은 구조의 코드를 입력해 갱신될 수 있도록 처리하면 된다.
  • animatingDifferences 옵션을 true로 하면 애니메이션과 함께 변경사항을 보여준다.

 

collectionView에 DiffableDataSource 적용이 완료되었다!


참고 :
https://zeddios.tistory.com/1197
https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource

반응형