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


@protocol PHPhotoLibraryChangeObserver


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 registerChangeObserver: 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 fetchAssetsInAssetCollection: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

- (void)photoLibraryDidChange:(PHChange *)changeInfo {
    // Photos may call this method on a background queue;
    // switch to the main queue to update the UI.
    dispatch_async(dispatch_get_main_queue(), ^{
        // Check for changes to the displayed album itself
        // (its existence and metadata, not its member assets).
        PHObjectChangeDetails *albumChanges = [changeInfo changeDetailsForObject:self.displayedAlbum];
        if (albumChanges) {
            // Fetch the new album and update the UI accordingly.
            self.displayedAlbum = [albumChanges objectAfterChanges];
            self.navigationController.navigationItem.title = self.displayedAlbum.localizedTitle;
        // Check for changes to the list of assets (insertions, deletions, moves, or updates).
        PHFetchResultChangeDetails *collectionChanges = [changeInfo changeDetailsForFetchResult:self.albumContents];
        if (collectionChanges) {
             // Get the new fetch result for future change tracking.
            self.albumContents = collectionChanges.fetchResultAfterChanges;
            if (collectionChanges.hasIncrementalChanges)  {
                // Tell the collection view to animate insertions/deletions/moves
                // and to refresh any cells that have changed content.
                [self.collectionView performBatchUpdates:^{
                    NSIndexSet *removed = collectionChanges.removedIndexes;
                    if (removed.count) {
                        [self.collectionView deleteItemsAtIndexPaths:[self indexPathsFromIndexSet:removed]];
                    NSIndexSet *inserted = collectionChanges.insertedIndexes;
                    if (inserted.count) {
                        [self.collectionView insertItemsAtIndexPaths:[self indexPathsFromIndexSet:inserted]];
                    NSIndexSet *changed = collectionChanges.changedIndexes;
                    if (changed.count) {
                        [self.collectionView reloadItemsAtIndexPaths:[self indexPathsFromIndexSet:changed]];
                    if (collectionChanges.hasMoves) {
                        [collectionChanges enumerateMovesWithBlock:^(NSUInteger fromIndex, NSUInteger toIndex) {
                            NSIndexPath *fromIndexPath = [NSIndexPath indexPathForItem:fromIndex inSection:0];
                            NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:toIndex inSection:0];
                            [self.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
                } completion:nil];
            } else {
                // Detailed change information is not available;
                // repopulate the UI from the current fetch result.
                [self.collectionView reloadData];


Observing Photo Library Changes

- photoLibraryDidChange:

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



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.

- registerChangeObserver:

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

- unregisterChangeObserver:

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


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


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


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