Skip to content

Instantly share code, notes, and snippets.

@cleexiang
Last active July 29, 2021 04:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cleexiang/5fa1847903f1a78bc0c7403f7ec42e75 to your computer and use it in GitHub Desktop.
Save cleexiang/5fa1847903f1a78bc0c7403f7ec42e75 to your computer and use it in GitHub Desktop.
Wrap PHPickerViewController with PromiseKit
//
// PHPickerViewController+Promise.swift
//
// Created by cleexiang on 2021/5/22.
//
import Foundation
import PhotosUI
import PromiseKit
import Photos
@available(iOS 14, *)
extension UIViewController {
public func promise(_ vc: PHPickerViewController, completion: (() -> Void)? = nil) -> Promise<UIImage> {
let proxy = PHPickerViewControllerProxy()
vc.delegate = proxy
present(vc, animated: true, completion: completion)
return proxy.promise.ensure {
vc.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
}
@available(iOS 14, *)
extension PHPickerResult {
public func fetchImage() -> Promise<UIImage> {
return Promise { seal in
self.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
if let err = error {
seal.reject(err)
} else {
if let image = object as? UIImage {
seal.fulfill(image)
} else {
seal.reject(PMKError.emptySequence)
}
}
})
}
}
}
@available(iOS 14, *)
@objc private class PHPickerViewControllerProxy: NSObject, PHPickerViewControllerDelegate {
let (promise, seal) = Promise<UIImage>.pending()
var retainCycle: AnyObject?
required override init() {
super.init()
retainCycle = self
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
guard let asset = results.first else {
seal.reject(UIImagePickerController.PMKError.cancelled)
retainCycle = nil
return
}
let status = PHPhotoLibrary.authorizationStatus()
if status == .notDetermined {
PHPhotoLibrary.requestAuthorization({ _ in
asset.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
if let err = error {
self.seal.reject(err)
self.retainCycle = nil
} else {
if let image = object as? UIImage {
self.seal.fulfill(image)
self.retainCycle = nil
} else {
self.seal.reject(PMKError.emptySequence)
self.retainCycle = nil
}
}
})
})
} else {
asset.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
if let err = error {
self.seal.reject(err)
self.retainCycle = nil
} else {
if let image = object as? UIImage {
self.seal.fulfill(image)
self.retainCycle = nil
} else {
self.seal.reject(PMKError.emptySequence)
self.retainCycle = nil
}
}
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment