5

In WWDC20 apple introduced PHPicker - the modern replacement for UIImagePickerController.
I'm wondering if it's possible to retrieve PHAsset using the new photo picker?


Here is my code:

private func presentPicker(filter: PHPickerFilter) {
    var configuration = PHPickerConfiguration()
    configuration.filter = filter
    configuration.selectionLimit = 0
    
    let picker = PHPickerViewController(configuration: configuration)
    picker.delegate = self
    present(picker, animated: true)
}


func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    dismiss(animated: true)
}
Arasuvel
  • 2,971
  • 1
  • 25
  • 40
Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48

1 Answers1

25

I managed to find an answer from the developers of this framework on the apple forum:

Yes, PHPickerResult has the assetIdentifier property which can contain a local identifier to fetch the PHAsset from the library. To have PHPicker return asset identifiers, you need to initialize PHPickerConfiguration with the library.

Please note that PHPicker does not extend the Limited Photos Library access for the selected items if the user put your app in Limited Photos Library mode. It would be a good opportunity to reconsider if the app really needs direct Photos Library access or can work with just the image and video data. But that really depend on the app.

The relevant section of the "Meet the new Photos picker" session begins at 10m 20s.

Sample code for PhotoKit access looks like this:

import UIKit
import PhotosUI
class PhotoKitPickerViewController: UIViewController, PHPickerViewControllerDelegate {
    @IBAction func presentPicker(_ sender: Any) {
            let photoLibrary = PHPhotoLibrary.shared()
            let configuration = PHPickerConfiguration(photoLibrary: photoLibrary)
            let picker = PHPickerViewController(configuration: configuration)
            picker.delegate = self
            present(picker, animated: true)
    }
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            picker.dismiss(animated: true)
            
            let identifiers = results.compactMap(\.assetIdentifier)
            let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
            
            // TODO: Do something with the fetch result if you have Photos Library access
    }
}
Arasuvel
  • 2,971
  • 1
  • 25
  • 40
Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48
  • 1
    Thanks for reporting this, good use of self Q and A on SO. – matt Jun 28 '20 at 17:25
  • 1
    Is it possible to obtain some meta data (like photo shot date) directly from the ItemProvider? Or as long as we need the meta, we need go through the PHAsset? – zrfrank Jul 17 '20 at 09:47
  • 4
    Is anyone else running into an issue where the fetchResult is always empty? The compactMap works and I get identifiers back, but the fetch result never returns any results for me. – JKo Sep 26 '20 at 19:31
  • 4
    @JKoko remember set `PHPhotoLibrary.shared()` in `PHPickerConfiguration` – Giang Oct 02 '20 at 08:56
  • I'm running into the same issue. @JKoko have you found a solution? – Preet Apr 26 '21 at 16:12
  • @JKoko It seems that you need access to All Photos, i.e. full permission in order to access a PHAsset. – dknchris Nov 16 '22 at 08:20