Protocol

PHPhotoLibraryChangeObserver

A protocol you can implement to be notified of changes that occur in the photo library.

Declaration

protocol PHPhotoLibraryChangeObserver

Overview

The PHPhotoLibraryChangeObserver protocol notifies you of changes that occur in the Photos library, regardless of whether those changes are made by your app, by a user in the Photos app, or by another app that uses the Photos framework. To receive change messages, register your observer with the photo library’s register(_:) method. For any assets or collections that you fetch, Photos sends change messages whenever those assets or collections change. Use this protocol to track changes across multiple parts of your app or respond to changes made in another app or extension.

Handling Changes: An Example

The example code below shows how you might implement this protocol in a view controller that uses a UICollectionView interface to display the contents of an album. The view controller keeps a reference to the PHAssetCollection object representing the displayed album and the PHFetchResult object (returned by the fetchAssets(in:options:) method) listing the album’s contents. Then, in its photoLibraryDidChange(_:) method, the view controller checks for differences between the objects it fetched and the new state of the photo library, and updates its collection view accordingly.

Listing 1

Handling photo library changes in a collection view

func photoLibraryDidChange(_ changeInstance: PHChange) {
    guard let collectionView = self.collectionView else { return }
    // Change notifications may be made on a background queue.
    // Re-dispatch to the main queue to update the UI.
    DispatchQueue.main.sync {
        // Check for changes to the displayed album itself
        // (its existence and metadata, not its member assets).
        if let albumChanges = changeInstance.changeDetails(for: assetCollection) {
            // Fetch the new album and update the UI accordingly.
            assetCollection = albumChanges.objectAfterChanges! as! PHAssetCollection
            navigationController?.navigationItem.title = assetCollection.localizedTitle
        }
        // Check for changes to the list of assets (insertions, deletions, moves, or updates).
        if let changes = changeInstance.changeDetails(for: fetchResult) {
            // Keep the new fetch result for future use.
            fetchResult = changes.fetchResultAfterChanges
            if changes.hasIncrementalChanges {
                // If there are incremental diffs, animate them in the collection view.
                collectionView.performBatchUpdates({
                    // For indexes to make sense, updates must be in this order:
                    // delete, insert, reload, move
                    if let removed = changes.removedIndexes where removed.count > 0 {
                        collectionView.deleteItems(at: removed.map { IndexPath(item: $0, section:0) })
                    }
                    if let inserted = changes.insertedIndexes where inserted.count > 0 {
                        collectionView.insertItems(at: inserted.map { IndexPath(item: $0, section:0) })
                    }
                    if let changed = changes.changedIndexes where changed.count > 0 {
                        collectionView.reloadItems(at: changed.map { IndexPath(item: $0, section:0) })
                    }
                    changes.enumerateMoves { fromIndex, toIndex in
                        collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
                                                to: IndexPath(item: toIndex, section: 0))
                    }
                })
            } else {
                // Reload the collection view if incremental diffs are not available.
                collectionView.reloadData()
            }
        }
    }
}

Topics

Observing Photo Library Changes

func photoLibraryDidChange(PHChange)

Tells your observer that a set of changes has occurred in the Photos library.

Required.

Relationships

Inherits From

See Also

Observing Changes to the Photo Library

Observing Changes in the Photo Library

Register an observer to be notified of changes to the photo library.

func register(PHPhotoLibraryChangeObserver)

Registers an object to receive messages when objects in the photo library change.

func unregisterChangeObserver(PHPhotoLibraryChangeObserver)

Unregisters an object so that it no longer receives change messages.

class PHChange

A description of a change that occurred in the photo library.

class PHObjectChangeDetails

A description of changes that occurred in an asset or collection object.

class PHFetchResultChangeDetails

A description of changes that occurred in the set of asset or collection objects listed in a fetch result.