Getting Started with PhotoKit

In this tutorial, you’ll learn how to use PhotoKit to access and modify photos, smart albums and user collections. You’ll also learn how to save and revert edits made to photos. By Corey Davis.

4.5 (11) · 1 Review

Download materials
Save for later
Share

The Photos app manages image assets in iOS through a set of APIs known as PhotoKit. If you’ve been wondering how to build an app like Photos or just access the photo library, PhotoKit is the answer. This tutorial will focus on iOS, but PhotoKit is also available for macOS, Catalyst and tvOS.

You’ll work on NoirIt, an app that applies a gorgeous noir filter to your photos. To accomplish this, you’ll:

  • Learn about PhotoKit’s permission model.
  • Access image asset data.
  • Learn how to access user collection and smart album data.
  • Display image assets.
  • Modify asset metadata.
  • Edit an asset’s image.
  • Save a modified image asset.
  • Revert a modified image asset to the original image.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

Start by opening NoirIt.xcodeproj inside the starter folder. Expand the Resources folder and open Main.storyboard.

The NoirIt storyboard.

The layout of the app is pretty straightforward. There is an album collection view controller, a photos collection view controller and a photo detail view controller.

Build and run.

Launching NoirIt for the first time.

It might not be much to look at now, but it will be soon.

Prepping the Photos App

Before you start, create an album in Photos so you have at least one album to view in NoirIt later.

  1. Open Photos app. There is a bug in Photos when running on a simulator which might cause it to crash. If it does, re-open it.
  2. Tap Albums on the tab bar.
  3. Tap the + at the top of the screen.
  4. Select New Album.
  5. Name it My Cool Pics and tap Save.
  6. Select a few photos to add to the the new album.
  7. Navigate back to the main albums view and see your new album.

Adding an album to the Photos app.

That is all you need to do in Photos.

Getting PhotoKit Permissions

As with many iOS APIs, PhotoKit uses a permissions model. It presents users with a dialog box asking for permission for the app to access their images. Before you dive into accessing and modifying images, you must get permission. You do so using PHPhotoLibrary, a shared object that manages access to the photo library.

Modifying Info.plist

Your first step is to add a key to Info.plist describing why you want permission to access the library.

  1. Open Info.plist.
  2. Right-click Information Property List and select Add Row. A new line appears.
  3. Enter the key NSPhotoLibraryUsageDescription and press enter.
  4. In the value column, enter To add a noir filter. When iOS requests permission to access the library for the first time, it displays this information.

Your Info.plist should look like this:

The NoirIt info.plist.

Requesting Authorization

Open AlbumCollectionViewController.swift. Find getPermissionIfNecessary(completionHandler:) and replace its implementation with:

// 1
guard PHPhotoLibrary.authorizationStatus() != .authorized else {
  completionHandler(true)
  return
}
// 2
PHPhotoLibrary.requestAuthorization { status in
  completionHandler(status == .authorized)
}
  1. The first thing you do is get the current authorization status from PHPhotoLibrary. If it’s already authorized, call the completion handler with a value of true.
  2. If permission was not previously granted, request it. When requesting authorization, iOS displays an alert dialog box asking for permission. It passes back the status as a PHAuthorizationStatus object in its completion handler. Call your completion handler and return true if the status value is .authorized, otherwise return false.
Note: PHAuthorizationStatus is an enum, which can also return notDetermined, restricted, denied and, new to iOS 14, limited. You might want to check for these and handle them appropriately. For now, keep NoirIt simple.

viewDidLoad() is already calling this method, so build and run. iOS asks for permission to access the photo library when NoirIt launches. If you are using, iOS 13 tap OK or on iOS 14, tap Allow Access to All Photos.

The PhotoKit library permission dialog box.

Understanding Assets

Even though you eventually will be getting images, it’s important to understand that you mostly work with assets in PhotoKit. Think about how you interact with the Photos app. Sure, you look at images, but there is also metadata such as favorites and geocoded location data. And there are more than images. Photos contains LivePhotos and video. Stuffing these things into UIImage doesn’t make sense. And that is where PHAsset comes in.

PHAsset is metadata describing an image, LivePhoto or video. It is immutable and doesn’t contain the image itself, but does provide the information you need to get the image. It also contains tons of information, such as creation and modification dates, location data, favorite and hidden status, burst data and much more. As you’ll soon see, PHAsset is a real workhorse.

Sometimes you work with a group of assets. These are usually returned as a PHAssetCollection object.

Asset Data Models

Open AlbumCollectionViewController.swift. Near the top of the file, add the following under the declaration for the sections property:

private var allPhotos = PHFetchResult<PHAsset>()
private var smartAlbums = PHFetchResult<PHAssetCollection>()
private var userCollections = PHFetchResult<PHAssetCollection>()

You might say to yourself, “Hey, self, what are these PHFetchResult things? I thought I was getting PHAssets and PHAssetCollections?” A simplified way of thinking of PHFetchResult is to consider it an array, which it is, in essence. It contains all the same methods and conventions of arrays, such as count() and index(of:). Plus, it intelligently handles fetching data, caching it and re-fetching it as needed. You’ll be fine if you think of PHFetchResult as an intelligent array of assets or collections. These properties are the app’s data store.

Fetching Assets and Asset Collections

Still within AlbumCollectionViewController.swift, find fetchAssets() and add the following code to it:

// 1
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [
  NSSortDescriptor(
    key: "creationDate",
    ascending: false)
]
// 2
allPhotos = PHAsset.fetchAssets(with: allPhotosOptions)
// 3
smartAlbums = PHAssetCollection.fetchAssetCollections(
  with: .smartAlbum,
  subtype: .albumRegular,
  options: nil)
// 4
userCollections = PHAssetCollection.fetchAssetCollections(
  with: .album,
  subtype: .albumRegular,
  options: nil)
  1. When fetching assets, you can apply a set of options that dictate the sorting, filtering and management of results. Here, you create a sort descriptor that sorts assets by creation date from newest to oldest.
  2. PHAsset provides functionality for fetching assets and returning the results as a PHFetchResult. Here, you pass it the options created above and assign the result to allPhotos.
  3. The Photos app automatically creates smart albums, such as Favorites and Recents. Albums are a group of assets and, as such, belong in PHAssetCollection objects. Here you fetch smart album collections. You won’t sort these, so options is nil.
  4. Accessing user created albums is similar, except that you fetch the .album type.

With your data store now populated, the next task is to update the UI.

Layout with Swifty