I use 3 apis to get datas for my tableview. First, feedRepository.findOtherFeed which returns Observable of Tuple containing data array and Bool. For each element in the data array I call userRepository.findProfileImg which fetches the profile image for each data. And each data has a property called userFeed.imageIdList, and for each id I call feedRepository.findFeedImage to get the image for the data.
These datas are going to be displayed in tableView. I want to show the users as fast as I can meaning I can't wait for all data's imageIdList calling feedRepository.findFeedImage. Whenever userRepository.findProfileImg is done I want to show the users first with what I've got and then when feedRepository.findFeedImage is all done I want to update the datas.
I'm not that fluent using RxSwift, so I am struggling with how I can implement this.
private func fetchAndProcessFeedsFinal(setSortOption: SortOption, page: Int?) -> Observable<Mutation> {
if page != nil {
resetPagination()
} else if isLastPage {
return .empty()
} else {
pages += 1
}
let nickname = "lemon""
return feedRepository.findOtherFeed(request: FindOtherFeedRequest(nickname: nickname, date: requestDate, page: pages, size: 7))
.flatMap { [weak self] (userFeeds, isLast) -> Observable<Mutation> in
guard let self = self else { return .empty() }
isLastPage = isLast
if userFeeds.isEmpty { return Observable.just(.updateDataSource([])) }
// MARK: inside processFeedWithProfileImage function it calls findProfileImg
let observables: [Observable<UserFeedSection.Item>] = userFeeds.map {[weak self] feed in
guard let self = self else { return Observable.just(.feed(FeedReactor(userFeed: feed, feedRepository: FeedRepository(), userRepository: UserRepository()))) }
return processFeedWithProfileImage(feed)
}
let feedWithImage = userFeeds.flatMap { userFeed in
userFeed.imageIdList.map { [weak self] imageId in
return self?.feedRepository.findFeedImage(request: FindFeedImageRequest(imageId: imageId))
}
}
return Observable.zip(observables)
.map { items in
return Mutation.updateDataSource(items)
}
}
}
I've tried zip and combineLatest but I think I didn't use it the right way..
This is a pretty complex ask, especially because of pagination. There isn't enough info in your sample to handle the full ask.
Here is how I would likely do something like this using my CLE system.
The basic idea is as follows:
The idea then is to follow the output of the
example(api:tableView:)function. Whenever a page or image comes in, the state will be updated. Itsitemsarray will contain all of the UserFeeds downloaded so far and all the images for each userFeed object inside aCellDisplayableobject.