47 lines
1.5 KiB
Swift
47 lines
1.5 KiB
Swift
// Copyright 2024-present 650 Industries. All rights reserved.
|
|
|
|
import SDWebImage
|
|
import ExpoModulesCore
|
|
|
|
internal final class ImageLoader {
|
|
nonisolated(unsafe) static let shared = ImageLoader()
|
|
|
|
lazy var imageManager = SDWebImageManager(
|
|
cache: SDImageCache.shared,
|
|
loader: SDImageLoadersManager.shared
|
|
)
|
|
|
|
func load(_ source: ImageSource, options: ImageLoadOptions) async throws -> UIImage {
|
|
// This loader uses only the disk cache. We may want to give more control on this, but the memory cache
|
|
// doesn't make much sense for shared refs as they're kept in memory as long as their JS objects.
|
|
var context = createSDWebImageContext(forSource: source, cachePolicy: .disk)
|
|
|
|
if let maxSize = options.getMaxSize() {
|
|
// Note that setting the thumbnail size rasterizes vector images into a bitmap.
|
|
context[.imageThumbnailPixelSize] = maxSize
|
|
}
|
|
context[.imagePreserveAspectRatio] = true
|
|
|
|
let image = try await withCheckedThrowingContinuation { continuation in
|
|
imageManager.loadImage(with: source.uri, context: context, progress: nil) { image, _, error, _, _, _ in
|
|
if let image {
|
|
continuation.resume(returning: image)
|
|
} else {
|
|
continuation.resume(throwing: ImageLoadingFailed().causedBy(error))
|
|
}
|
|
}
|
|
}
|
|
|
|
if let tintColor = options.tintColor {
|
|
return image.withTintColor(tintColor)
|
|
}
|
|
return image
|
|
}
|
|
}
|
|
|
|
internal final class ImageLoadingFailed: Exception, @unchecked Sendable {
|
|
override var reason: String {
|
|
"Failed to load an image"
|
|
}
|
|
}
|