Filip Němeček
Posted on June 25, 2020
In iOS 14 there is a brand new way to let users select a photo(s) or video(s) from their library to use in your app and it has some cool features and benefits. Let's see what these are and how basic PHPickerViewController
usage looks like.
Benefits
No permissions required - you don't need to provide usage description in Info.plist
to present the new picker and system does not show the allow access dialog. That is because users have full control over what media they select and subsequently send to your app.
Modern UI consistent with Photos - the new picker is much easier to use because the UI is very similar to what you get in Photos and there is also a search. This should be much better selection experience for the users than with the UIImagePickerViewController
Multi-selection - what else to say? 🙂
Usage overview
Using the new PHPickerViewController
is pretty straightforward. It uses the traditional delegate model that will alert you when user finishes her selection. There is just a single delegate method to support and a bit of configuration.
Start by importing the PhotosUI
framework:
import PhotosUI
Then continue with creating the configuration object PHPickerConfiguration
. So far this allows to customize how many media files user can select and what kind of:
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 3
configuration.filter = .images
In this example we are setting the selectionLimit
to 3 (default is 1). You can also set 0
to mean unlimited. And next with filter
we are saying that we want just images.
You can also ask for videos
or livePhotos
and combine these with the any(of:
method like so:
configuration.filter = .any(of: [.livePhotos, .images])
Next create the picker itself and set yourself as its delegate
:
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
We have two things left. Present the picker:
present(picker, animated: true, completion: nil)
The UI is different depending if multi-selection is enabled or not.
And implement the delegate:
extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true, completion: nil)
guard !results.isEmpty else { return }
}
}
So far we are just dismissing the picker and checking that we have results.
Unlike with UIImagePickerViewController
we won't get the URL path to the file but instead a NSItemProvider
that we can ask to load a specific object. For images this may look like this:
if provider.canLoadObject(ofClass: UIImage.self) {
provider.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
if let image = image as? UIImage {
self.imageView.image = image
}
}
}
}
Just to be safe we first ask if the object can be loaded and then load it. To be honest I am not that well versed with NSItemProvider
.
With UIImagePickerViewController
there was a settings to specify the resolution for exported media which here does not appear to be a case. I plan to investigate this further and either update this post or write new one detailing how to get video or image with specific resolution.
In the WWDC 20 session about this new photo picker Apple specifically mentions that we should be using this new one instead of the older UIImagePickerViewController
. This is not deprecated yet but presets for image/video quality are as per new documentation:
Posted on June 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.