Select images from PHPickerController asynchronously

Updated
Jan 4, 2022 6:03 PM
Created
Jan 4, 2022 6:02 PM
Tags
SwiftConcurrency
Attributes

func selectImageFromPicker() async -> [PHPickerResult] {

  await withCheckedContinuation { continuation in

    let configuration = PHPickerConfiguration(photoLibrary: .shared())&>.modify {
      $0.filter = .any(of: [.images, .livePhotos])
    }

    var ref: Unmanaged<PickerDelegateProxy>?

    let controller = PHPickerViewController(configuration: configuration)
    let proxy = PickerDelegateProxy(onDidFinishPicking: { results in
      continuation.resume(returning: results)
      controller.dismiss(animated: true, completion: nil)
      ref?.release()
    })

    ref = Unmanaged.passRetained(proxy)

    controller.delegate = proxy

    present(controller, animated: true, completion: nil)

  }

}

fileprivate final class PickerDelegateProxy: PHPickerViewControllerDelegate {

  private let onDidFinishPicking: ([PHPickerResult]) -> Void

  init(onDidFinishPicking: @escaping ([PHPickerResult]) -> Void) {
    self.onDidFinishPicking = onDidFinishPicking
  }

  func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    onDidFinishPicking(results)
  }
}

let results = await selectImageFromPicker()