Prefetching with URL then loading in SwiftUI by custom key #2051
-
In our rather complex app we want to load images stored on S3, where we only store the associated keys in our database. So the flow to get an image onto the device is:
In theory this should work, however I cannot figure out how to load an image in SwiftUI purely by custom cacheKey. I cannot use |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I have tried using this @State private var loadedImage: UIImage?
// and when initialising filling this state variable using this:
ImageCache.default.retrieveImage(forKey: "123") { result in
switch result {
case .success(let value):
print(value)
loadedImage = value.image
case .failure(let error):
print(error)
}
print(loadedImage) // this is still nil for some really odd reason
} however somehow the UIImage is always nil |
Beta Was this translation helpful? Give feedback.
-
Hi, I guess this should do the trick. Instead of using the URL-based loading, try to define an struct CacheProvider: ImageDataProvider {
enum E: Error {
case malformedData
case notInCache
}
let cacheKey: String
let options: KingfisherOptionsInfo?
func data(handler: @escaping (Result<Data, Error>) -> Void) {
ImageCache.default.retrieveImage(forKey: cacheKey, options: .init(options)) { result in
switch result {
case .success(let r):
if let image = r.image {
if let data = image.pngData() {
handler(.success(data))
} else {
handler(.failure(E.malformedData))
}
} else {
handler(.failure(E.notInCache))
}
case .failure(let error):
handler(.failure(error))
}
}
}
} Then on the KFImage(
source: .provider(
CacheProvider(cacheKey: "my-cache-key", options: nil)
)
) And sure, you need to have a way to download it first before showing it. Say, using an ImagePrefetcher(
resources: [
ImageResource(downloadURL: .init(string: "https://onevcat.com/assets/images/avatar.jpg")!, cacheKey: "my-cache-key")
],
completionHandler: { skippedResources, failedResources, completedResources in
print("Prefetch skipped: \(skippedResources)")
print("Prefetch completed: \(completedResources)")
}
).start() Then, once the prefetching is done, you should be able to load the Some points:
ImagePrefetcher(
resources: [
ImageResource(downloadURL: .init(string: "https://onevcat.com/assets/images/avatar.jpg")!, cacheKey: "my-cache-key")
],
+ options: [.processor(RoundCornerImageProcessor(cornerRadius: 5.0))],
completionHandler: { skippedResources, failedResources, completedResources in
print("Prefetch skipped: \(skippedResources)")
print("Prefetch completed: \(completedResources)")
}
).start() You also need to pass the same options to KFImage(
source: .provider(
- CacheProvider(cacheKey: "my-cache-key", options: nil)
+ CacheProvider(cacheKey: "my-cache-key", options: [.processor(RoundCornerImageProcessor(cornerRadius: 5.0))])
)
) |
Beta Was this translation helpful? Give feedback.
Hi,
I guess this should do the trick. Instead of using the URL-based loading, try to define an
ImageDataProvider
: