I need to show a photo grid where each photo has a tiny preview stored in local DB, and I want to display these previews shortly until a bigger thumbnail is loaded from remote URL.
To load local previews I'm creating a custom ImageRequest like this:
let request = ImageRequest(
id: "preview_\(photoId)",
data: { await loadPreviewFromDb(photoId) },
options: [.disableDiskCache]
)
Now when the grid is shown only the first 6 previews are loaded and the rest are just ignored, even though I can confirm that the actual data is loaded from the DB correctly. In the logs I see Data loader returned empty data. errors.
Adding .skipDataLoadingQueue option kinda helps but I still see random blank previews from time to time.
It turns out the async data function is called eagerly when it's converted into Publisher (see DataPublisher.swift/publisher(...) code), and PassthroughSubject will ignore data that was sent while it had no subscribers (queued?).
I managed to fix it by using lazy Publisher created like this:
let request = ImageRequest(
id: "preview_\(photoId)",
dataPublisher: Future { await loadPreviewFromDb(photoId) },
options: [.disableDiskCache]
)
private extension Future where Failure == Error {
convenience init(action: @escaping () async throws -> Output) {
self.init { promise in
Task {
do {
let result = try await action()
promise(.success(result))
} catch {
promise(.failure(error))
}
}
}
}
}
This seems to work just fine, but I think it worth fixing it in the library as well.
I need to show a photo grid where each photo has a tiny preview stored in local DB, and I want to display these previews shortly until a bigger thumbnail is loaded from remote URL.
To load local previews I'm creating a custom
ImageRequestlike this:Now when the grid is shown only the first 6 previews are loaded and the rest are just ignored, even though I can confirm that the actual data is loaded from the DB correctly. In the logs I see
Data loader returned empty data.errors.Adding
.skipDataLoadingQueueoption kinda helps but I still see random blank previews from time to time.It turns out the async
datafunction is called eagerly when it's converted intoPublisher(see DataPublisher.swift/publisher(...) code), andPassthroughSubjectwill ignore data that was sent while it had no subscribers (queued?).I managed to fix it by using lazy
Publishercreated like this:This seems to work just fine, but I think it worth fixing it in the library as well.