J'essaie d'utiliser RxSwift dans mon application. L'un des cas d'utilisation est un chargement asynchrone d'une image UITableView qui est déclenché par un bouton de recherche (ou le recyclage de la cellule). Ce que je n'arrive pas à faire fonctionner correctement, c'est l'élimination des résultats précédents.
Il est important pour moi de conserver un ordre de chargement correct et d'être en mesure d'écarter les demandes d'images inutiles sur le réseau.
Je travaille sur RxSwift, mais cela pourrait s'appliquer à RxJava et Android RecyclerView.
Le pseudo-code de l'état actuel est le suivant :
myModel
.searchString
.debounce(0.3)
.distinctUntilChanged()
.flatMapLatest({ return fetchImageUrlsFromNetwork($0) })
.bindTo(tableView.rx.items) { (url,cell,...) in
reactivelyLoadUrl(url)
.subscribe({ cell.imageView.image = UIImage(data:$0) })
}
Le problème dans le code, bien sûr, est l'absence de connexion entre l'observable de la cellule et l'observable extérieur, ce qui, je le sais, est une mauvaise pratique,
mais je ne sais pas comment utiliser les bindings RxCocoa pour UITableView avec la combinaison du chargement asynchrone des cellules. Le fait que les internes de la tableview utilisent le chargement lors du défilement et du recyclage des cellules ajoute également quelques complexités à ce scénario.
Il est également important que je n'aie pas à charger au préalable toutes les données de la tableview et donc à afficher toutes les images des cellules en même temps.
J'ai pensé à créer un observable global par index de tableview, de sorte que lorsqu'il est requis par le moteur d'interface utilisateur (soit déclenché par le recyclage, soit par le rappel des résultats du moteur de recherche), la demande entre dans une séquence qui est appliquée à l'aide de l'option flatMapLatest
et donc le chargement préserverait l'ordre par cellule, mais ce n'est pas si élégant.
Il en résulte que si je lance rapidement plusieurs requêtes de recherche, je peux parfois voir les images chargées précédemment l'emporter sur les nouvelles.