Я расскажу вам, как я нашел решение, чтобы помочь вам выяснить будущие решения ...
Я предполагаю, что структура, содержащая строки URL, называется Item
, и выУ вас есть Observable<[Item]>
, который вы используете в данный момент для загрузки представления коллекции.Я также предполагаю, что у вас есть только один раздел в вашей коллекции.
Во-первых, мы знаем, что что-то должно произойти, когда prefetchItemsAt
отправляет событие, поэтому мы начнем с этого:
let foo = collectionView.rx.prefetchItems
Теперь проверьте тип foo
и убедитесь, что это ControlEvent<[IndexPath]>
.ControlEvent - это вид наблюдаемого.Нам просто нужна часть items
IndexPaths, поэтому давайте map
, что:
let foo = collectionView.rx.prefetchItems
.map { $0.map { $0.item } }
(двойная карта является печальным следствием того, что Swift не поддерживает типы с более высоким типом). Теперь проверьте тип foo
.Это наблюдаемый массив целых чисел.Эти целые числа являются индексами в нашем массиве items.Таким образом, нам нужен доступ к последним испущенным элементам:
(as above)
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[$0] }
}
Таким образом, withLatestFrom
похож на combineLatest
, за исключением того, что он срабатывает только тогда, когда первичная наблюдаемая дает значение, а не когда вторичная наблюдаемая делает.
Теперь проверка типа foo
обнаружит, что это наблюдаемый массив предметов.Точные элементы, URL-адреса которых мы хотим отправить ImagePrefetcher.Поэтому нам нужно извлечь urlStrings в URL-адреса.
(as above)
.map { $0.compactMap { URL(string: $0.urlString) } }
И с этим у нас есть массив URL-адресов, который мы хотим использовать ImagePrefetcher.Поскольку он потребляет данные, он должен быть упакован в блок подписки.
(as above)
.subscribe(onNext: {
ImagePrefetcher(urls: $0).start()
})
На этом этапе foo
является одноразовым, поэтому его просто нужно собрать в нашей сумке для утилизации ... Здесьэто весь блок кода.
collectionView.rx.prefetchItems
.map { $0.map { $0.item } }
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[$0] }
}
.map { $0.compactMap { URL(string: $0.urlString) } }
.subscribe(onNext: {
ImagePrefetcher(urls: $0).start()
})
.disposed(by: bag)
Последний бит, чтобы очистить все ... Все между prefetchItems
и subscribe
можно переместить в ViewModel, если у вас есть.
Ключевым моментом здесь является то, что вы можете использовать типы, чтобы направлять вас, и вам нужно знать, какие операторы доступны для манипулирования наблюдаемыми объектами, которые вы можете найти в http://reactivex.io/documentation/operators.html