Checking out the new PHPickerViewController in iOS 14
Tags: swift, ios, ios14
Published: 2020-06-25 13:04:48

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:

```swift
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:

```swift
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:

```swift
configuration.filter = .any(of: [.livePhotos, .images])
```

Next create the picker itself and set yourself as its `delegate`:

```swift
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
```

We have two things left. Present the picker:

```swift
present(picker, animated: true, completion: nil)
```

The UI is different depending if multi-selection is enabled or not.

![The new PHPhotoPickerViewController](https://nemecek.be/media/images/photo-picker.png)

And implement the delegate:

```swift
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:

```swift
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:

![](https://nemecek.be/media/images/Screenshot_2020-06-25_at_13.56.57.png)