'iOS 14: PHPickerViewController is there any way to load all assets at the same time PHPickerResult
Currently, I am trying to dive into PHPickerViewController for select multiple image at same time from Photos. so I want to array of image that selected by user, i tried it too many way but no luck. This is my code please tell me there is an best practice for to do it?
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
var images: [UIImage?] = []
var totalConversionsCompleted = 0
for (index,result) in results.enumerated() {
result.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
let image = object as? UIImage
images.append(image)
totalConversionsCompleted += 1
if totalConversionsCompleted == index {
print("completion happen \(images)")
}
})
}
}
Solution 1:[1]
I got it working using single DispatchGroup
. This is my delegate method implementation:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) // dismiss a picker
let imageItems = results
.map { $0.itemProvider }
.filter { $0.canLoadObject(ofClass: UIImage.self) } // filter for possible UIImages
let dispatchGroup = DispatchGroup()
var images = [UIImage]()
for imageItem in imageItems {
dispatchGroup.enter() // signal IN
imageItem.loadObject(ofClass: UIImage.self) { image, _ in
if let image = image as? UIImage {
images.append(image)
}
dispatchGroup.leave() // signal OUT
}
}
// This is called at the end; after all signals are matched (IN/OUT)
dispatchGroup.notify(queue: .main) {
print(images)
// DO whatever you want with `images` array
}
}
Solution 2:[2]
1 - Did you set your controller as delegate of PHPickerViewController?
To do that, your controller should conform to PHPickerViewControllerDelegate
class ViewController: UIViewController, PHPickerViewControllerDelegate {
And you should set your controller as delegate of PHPickerViewController
pickerController.delegate = self //if you create PHPickerViewController inside your viewController
And then you will get results on this method
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
2 - If you can't get multiple selection, you can change selection limit of PHPickerConfiguration object that you use with your PHPickerViewController
var confing = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
confing.selectionLimit = 5
let pickerController = PHPickerViewController(configuration: confing)
3 - And then you can work with objects in results array
let identifiers = results.compactMap(\.assetIdentifier)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Palli |
Solution 2 | Raman Shyniauski |