MacKuba

Kuba Suder's blog on Mac & iOS development

Photos

App ClipsAppKitExtensionsFoundationLocationLoggingMacMapsPerformancePhotosPrivacySafariSwiftSwiftUIUIKitWatchKitWWDC 14WWDC 16WWDC 18WWDC 19WWDC 20

View as index

Meet the new Photos picker

Categories: Photos, UIKit, WWDC 20 0 comments Watch the video

PHPicker: new system-provided picker screen that gives you access to photos and videos from the user’s photo library

New design and new easy to use API

It’s recommended that you use this picker instead of building your own custom photo selection UI

New version includes:

  • an integrated search
  • easy multi-select
  • zoom gesture

PHPicker is private by default:

  • the picker screen runs out of process and talks to the app via XPC
  • your app has no direct access to the photos library
  • it doesn’t need to get photo library permission (don’t ask for it unless you *really* need it)
  • you only get selected photos and videos in response

Elements of the API:

PHPickerConfiguration – lets you specify limits and filters:

  • selectionLimit – number of items that can be selected (1 by default, 0 = unlimited)
  • filter – e.g. .images or .any(of: [.videos, .livePhotos])

PHPickerViewController – the main VC handling the picker

  • the picker doesn’t dismiss itself automatically, call picker.dismiss(animated:) when you get the response

PHPickerViewControllerDelegate – delegate for the picker

  • picker(_: didFinishPicking results:)

PHPickerResult – an array of these objects is passed to the app in response

  • get itemProvider from the result
  • check itemProvider.canLoadObject(ofClass: UIImage.self)
  • get the image via itemProvider.loadObject(ofClass: UIImage.self) { … }

You can normally extract picked photos from PHPickerResult item providers without touching the PHPhotoLibrary at all, but if you do need to access the photo library anyway, then pass it to PHPickerConfiguration.init and get assetIdentifier references from the picker results

If you use PHPicker with photo library access and you only got limited access to a subset of photos, then:

  • PHPicker will still let the user choose photos from their whole library
  • but the selection you have direct access to will not be extended by what they choose in the picker

The photo library APIs from UIImagePickerController are deprecated

Handle the Limited Photos Library in your app

Categories: Photos, UIKit, WWDC 20 0 comments Watch the video

Current full photo library access: your app has full access to all contents of user’s photo library, can read and write to the photo database

Limited mode: you only have access to “user’s limited library selection” – a kind of filter for the photo library

You can only fetch assets and resources related to what the user has chosen to give you access to

When the user updates the selection, your app is notified so you can update your UI

This affects all apps using photo library, even apps that are already live

When the user is asked for access to photos, they can choose: Allow access to all / Don’t allow / Select photos

Selected photo set can be changed in the Settings

If an app hasn’t made any changes to support this new mode yet, you will be asked if you want to change selection every time the app accesses the photo library after a restart

Users usually have thousands or tens of thousands of photos in their library, possibly from many years, but they almost never want an app to have access to all of them

Other ways to access the library

How can you use the photo library without requesting access to it at all?

If your app only needs to let you choose a photo for an avatar, or to post to a chat  ⭢  use system photo picker (PHPickerViewController)

  • replacement for UIImagePickerController
  • improved with search and multi-select
  • doesn’t require user to grant photo library access

If you only need to save photos and images to the library, you can ask for add-only access

Full access makes sense for apps like photo browsing and editing apps, camera or backup apps

New APIs

When asking for and checking authorization, you need to specify PHAccessLevel: .readWrite / .addOnly

PHPhotoLibrary.authorizationStatus(for: accessLevel)

If the user gave you limited access (only to a subset of photos), then authorizationStatus == .limited

When requesting access, you can just send a request to the photo library when the user performs an action that requires it, and the popup will appear automatically

If you want to request access explicitly without making a request, do:

PHPhotoLibrary.requestAuthorization(for: accessLevel) { … }

Older authorizationStatus() and requestAuthorization(_ handler:) APIs will be deprecated and will just return .authorized

Other APIs should work the same regardless of access, they will just return fewer items if access is limited

A few exceptions:

  • assets created by your app are automatically accessible to your app
  • you can’t create or fetch user’s albums in limited mode
  • no assets to cloud shared assets or albums

If you want to let the user update the selection:

  • call PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: viewController)
  • monitor changes through PHPhotoLibraryChangeObserver
  • you may want to add some new button in the UI that lets the user access this screen

To prevent the selection alert from appearing after a relaunch, add the key PHPhotoLibraryPreventAutomaticLimitedAccessAlert to Info.plist

Steps to take when updating:

  1. 1. Reconsider if your app needs photo library access at all  ⭢  consider using system picker instead, or asking for write-only access
  2. 2. Adopt the new authorization APIs
  3. 3. Add a button which lets the user access the library selection UI if it makes sense
  4. 4. Add the Info.plist key to prevent the alert