UICollectionViewDataSourcePrefetching
概要
Prefetching とは、UICollectionView にて、データロードに伴う UX 向上のために用意されている機能で、Cell Prefetching と Data Prefetching の二種類がある。特に、後者は iOS 10 から利用できるようになった機能で、ネットワークを介した非同期かつコストの高いデータロードが発生する場合に有効。UICollectionViewDataSource の collectionView(_:cellForItemAt:) よりも、呼び出しタイミングが早い。
何が必要か?
UICollectionView には元々 dataSource プロパティに Data Source が設定できるが、Data Prefetching のためには、また別の Data Source を prefetchDataSource プロパティに設定する必要がある。ここに設定するオブジェクトが準拠すべきプロトコルが UICollectionViewDataSourcePrefetching である。
このプロトコルにて実装が必須のメソッドは collectionView(_:prefetchItemsAt:)。これは、セルの描画近づいてきたタイミング で呼び出される。このメソッドの責務は、高コストな非同期のデータ呼び出しの実行を開始すること。そして、その実行結果が後から参照できるようにしておくこと。
具体的には、このメソッドの後に DataSource の collectionView(_:cellForItemAt:) が呼び出されるので、そこから実行結果を参照できるようにしておく。すると、Data Source はその情報を利用して Cell/View を作成する。
ただし、Data Source のcollectionView(_:cellForItemAt:) が呼び出された段階で、Prefetch されたデータのフェッチが完了していることは保証されない。従って、collectionView(_:cellForItemAt:) は以下の3つの状態をハンドリングできるようになっている必要がある。
データがすでに Prefetch 完了していて、参照できる状態
データがまだ Fetch 中であり、参照できない状態
データの Fetch リクエストすら開始されておらず、参照できない状態
さらに、必要なくなったデータの取得はキャンセルできる必要もある。この責務は、UICollectionViewDataSourcePrefetching の collectionView(_:cancelPrefetchingForItemsAt:) が担う。
https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching
実装例
これをうまくするのに、Operation を使うというのが1つの方法。
サンプルコード
https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching/prefetching_collection_view_data