# PhotosPicker on SwiftUI

In this blog post I'll show you how to use the new SwiftUI PhotosPicker API that was announced in the WWDC22 session [What's new in the Photos picker](https://developer.apple.com/videos/play/wwdc2022/10023/).

![Picker API available on SwiftUI](https://cdn.hashnode.com/res/hashnode/image/upload/v1656375637291/nzJSm8STv.png align="left")

The new SwiftUI `PhotosPicker` API is available on all picker-supported platforms:
- iOS (16.0+)
- iPadOS (16.0+)
- macOS (13.0+)
- watchOS (9.0+)

You no longer have to use `UIViewControllerRepresentable` to wrap either `PHPickerViewController` or its older version `UIImagePickerController`.

The picker runs out of process, so your app doesn't need to request any library access to use it. 

![WWDC22 Presentation SwiftUI Picker multiSelection](https://cdn.hashnode.com/res/hashnode/image/upload/v1656376070829/MH1hYi89M.png align="left")

> The picker will automatically choose the best layout depending on the platform, your app's configuration, and available screen space. You don't need to worry about what the picker UI should be, so you just can focus on making your app better.

From a developer's perspective, there are two steps

1. Use `PhotosPicker` view to obtain one or more instances of `PhotosPickerItem`
2. Load the asset data on demand with `PhotosPickerItem.loadTransferable`

## Use `PhotosPicker` view to obtain one or more instances of `PhotosPickerItem`

There are various initializers for [`PhotosPicker `](https://developer.apple.com/documentation/photokit/photospicker?changes=lat_6_5) ,so I encourage you to read through the documentation.

Here is an example of using `PhotosPicker` to select a single image by clicking on an image.

![Example](https://cdn.hashnode.com/res/hashnode/image/upload/v1656378249928/myGPMTUUJ.png align="left")

## Load the asset data on demand with `PhotosPickerItem.loadTransferable`

Please note that asset data won't be loaded immediately. The load operation could also fail if an error was encountered, for example, when the picker was trying to download data from iCloud Photos but the device was not connected to the internet. 

The PhotosPicker uses `Transferable`, which is a new SwiftUI protocol for transferring data between apps and extensions.

During Apple's demo it is suggested that you can specify the type as `Image` and that [`loadTransferable(type:)`](https://developer.apple.com/documentation/photokit/photospickeritem/4030159-loadtransferable?changes=lat_6_5) will decode and return a respective `Image` instance.

```Swift
private func loadTransferable(from imageSelection: PhotosPickerItem) -> Progress {
    return imageSelection.loadTransferable(type: Image.self) { result in
        DispatchQueue.main.async {
            guard imageSelection == self.imageSelection else { return }
            switch result {
            case .success(let image?):
                self.imageState = .success(image)
            case .success(.none):
                self.imageState = .empty // <= during my testing I always ended up here
            case .failure(let error):
                self.imageState = .failure(error)
            }
        }
    }
}
```

However this was not working for me. Maybe it's a bug in the beta version. What worked for me was to specify the type as `Data`, use its data to create a `UIImage` instance and finally create an `Image` instance.

```Swift
private func loadTransferable(from imageSelection: PhotosPickerItem) -> Progress {
    return imageSelection.loadTransferable(type: Data.self) { result in
        DispatchQueue.main.async {
            guard imageSelection == self.imageSelection else { return }
            switch result {
            case let .success(data?):
                guard let uiImage = UIImage(data: data) else {
                    self.imageState = .empty
                    return
                }
                self.imageState = .success(Image(uiImage: uiImage))
            case .success(.none):
                self.imageState = .empty
            case let .failure(error):
                self.imageState = .failure(error)
            }
        }
    }
}
```

Apple has not released the code used from the WWDC22 session to demo `PhotosPicker`. I created essentially the same code and put it up on GitHub as a public gist.

%[https://gist.github.com/MarcoEidinger/a5f44d79f0dfc6619db5126e903903f9]
