The Photos app on iOS displays assets in a thumbnail grid. This sample demonstrates how to achieve a similar layout with a custom UICollectionViewController. It fetches asset thumbnails using PhotoKit, then displays them as a single photo, video, or Live Photo asset.
The sample app, PhotoBrowse, also demonstrates how to organize the user’s photos into albums and built-in collections, such as Recently Added and Favorites. It supports album creation, deletion, modification, as well as the editing and favoriting of individual assets.
List Albums and Built-in Collections
When the app first launches, it fetches all of the user’s photo assets. All requests for asset data—single photos, albums, and user collections—go through PhotoKit’s shared PHPhotoLibrary object, so the app registers the main view controller once its view loads:
To list all the user’s albums and collections, the app creates a PHFetchOptions object and dispatches several fetch requests:
The resulting PHFetchResult informs the app about the structure of the user’s photo library, allowing the user interface to show the number of photos in each album.
Display Assets in a Thumbnail Grid
The sample app implements thumbnail grid browsing by subclassing UICollectionViewController in AssetGridViewController.
After the grid view controller loads, it updates the image cache, which allows thumbnails to load quickly as the user scrolls:
Implement the UICollectionView delegate method cellForItemAtIndexPath: to use thumbnails instead of full assets. PhotoKit allows you to request assets directly, and even badge Live Photos to set them apart:
Show a Single Photo, Video, or Live Photo
AssetViewController implements the view of a single asset. If the asset is a video or Live Photo, the view controller also supports playback through a UIBarButtonItem:
On tvOS, PhotoKit supports Live Photo playback:
The view controller supports playback by creating an AVPlayer and layering it on top of the item once the PHImageManager fetches a video:
Apply Canned Filters in an Editing Interface
The AssetViewController view allows the user to edit the photo and save changes back to the photo library. It uses an alert controller to display a list of preset editing options, including sepia tone, chrome, and revert.
After the user picks a filter, the app applies it and outputs the saved asset immediately. There’s no UI state for having chosen—but not yet committed—an edit. As such, there’s no role for reading adjustment data to resume in-progress edits, since PhotoBrowse has no notion of in-progress. However, it’s still good practice to write adjustment data so that potential future versions of the app—or other apps that understand your adjustment data format—could make use of it.
Create a New Album
An alert controller allows the user to add a new album:
Add an Asset to a Collection
When the user chooses to add an asset by tapping the Add button (+) in the navigation bar, PhotoBrowse creates a mock photo from a random color at a random orientation. Like other changes to a user’s photo library, adding an asset requires the app to wrap the addition inside a PHAssetChangeRequest as follows:
Delete Assets and Albums
The user can delete an asset through the trash can button at the lower-right corner of AssetViewController. For removal from an album, PhotoBrowse wraps the deletion operation inside a PHAssetCollectionChangeRequest object. For removal from the entire photo library, PhotoBrowse wraps the deletion operation inside a PHAssetChangeRequest object:
Favorite an Asset
Users can favorite an asset by toggling the PHAsset parameter favorite:
Observe and Respond to Changes
Register your main view controller—and any view that shows the user assets—to observe changes to the photo library, so your app can receive and respond to notifications as assets change. These changes may not necessarily occur inside your app’s functionality; they could originate from other apps, other devices, iCloud Photos, or Shared Albums:
Be sure to unregister your change observer after the app’s main view controller goes away.