Skip to content

Instantly share code, notes, and snippets.

@fellipecaetano
Created October 27, 2017 18:10
Show Gist options
  • Save fellipecaetano/246564a6111dd493d9a1f7b076b9e251 to your computer and use it in GitHub Desktop.
Save fellipecaetano/246564a6111dd493d9a1f7b076b9e251 to your computer and use it in GitHub Desktop.
A loader for asset images
import Photos
import RxSwift
final class PHAssetImageLoader: ImageLoader {
func loadImage(with url: URL) -> Single<UIImage> {
return Single<UIImage>.create { observer in
let imageManager = PHImageManager.default()
var requestIdentifier: PHImageRequestID?
DispatchQueue.global(qos: .userInitiated).async {
let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil)
guard let asset = fetchResult.firstObject else {
observer(.error(PHAssetImageLoaderError.assetNotFound))
return
}
let request = PHImageRequestOptions()
request.isSynchronous = true
request.deliveryMode = .highQualityFormat
request.resizeMode = .exact
let size = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
requestIdentifier = imageManager.requestImage(
for: asset,
targetSize: size,
contentMode: .aspectFill,
options: request) { image, info in
if let image = image {
observer(.success(image))
} else if let info = info, let isCancelled = info[PHImageCancelledKey] as? NSNumber, isCancelled == 1 {
observer(.error(PHAssetImageLoaderError.requestCancelled))
} else if let info = info, let error = info[PHImageErrorKey] as? Error {
observer(.error(error))
} else {
observer(.error(PHAssetImageLoaderError.unknownFailure))
}
}
}
return Disposables.create {
if let requestIdentifier = requestIdentifier {
imageManager.cancelImageRequest(requestIdentifier)
}
}
}
}
}
enum PHAssetImageLoaderError: Error {
case assetNotFound
case requestCancelled
case unknownFailure
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment