PHPhotoLibrary change observer not called

klcjr89 picture klcjr89 · Jun 9, 2015 · Viewed 9.4k times · Source

I seem to be having a random problem that I have no idea why is happening. I cannot seem to get the photoLibraryDidChange:(PHChange *)changeInstance to be called by the observer. I've made several blank projects and all are demonstrating this issue, the change observer will sometimes be called upon initial app installation, but is never called after when I perform changes in the Photos app. I've also reset the simulator to no avail. I'd appreciate any help offered.

Code:

#import <UIKit/UIKit.h>
#import <Photos/Photos.h>

@interface ViewController : UIViewController <PHPhotoLibraryChangeObserver>

@end

- (void)viewDidLoad
{
    [super viewDidLoad];

    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status)
     {
         if (status == PHAuthorizationStatusAuthorized)
         {
             [PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];

              dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
              {
                 [self setup];
              });
         }
     }];
}

- (void)setup
{
    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc]init];

    fetchOptions.wantsIncrementalChangeDetails = YES;

    PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions];

    for (PHAssetCollection *sub in smartAlbumsFetchResult)
    {
        PHFetchResult *fetch = [PHAsset fetchAssetsInAssetCollection:sub options:fetchOptions];
    }
}

- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    NSLog(@"Not called");
}

- (void)dealloc
{
   [PHPhotoLibrary.sharedPhotoLibrary unregisterChangeObserver:self];
}

Answer

matt picture matt · Jun 9, 2015

I think there is something wrong with how you are testing. It works fine for me. Here's what I did.

This is the entire code of my one view controller:

#import <UIKit/UIKit.h>
@import Photos;
#import "ViewController.h"

@interface ViewController() <PHPhotoLibraryChangeObserver>
@end
@implementation ViewController : UIViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
         if (status == PHAuthorizationStatusAuthorized) {
             [PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];
         }
     }];
}
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    NSLog(@"Here");
}
@end
  • I run the app in the Simulator. Authorization is requested. I authorize. Behind the Simulator, where Xcode is running, I see "Here" in the console - this is expected, because we get a change notification when the library "comes to life" after authorization. That is exactly how the observer is supposed to behave.

  • Still in the Simulator, I hit Shift-Command-H to go to the springboard. I switch to the Photos app and delete a photo.

  • In the Simulator, I hit Shift-Command-H twice to go the app switcher.

  • In the Simulator, I click on the still-running test app to return to it. Behind the Simulator in Xcode, I see "Here" in the console, because while we were out, a photo was deleted. Again, that is exactly how the observer is supposed to behave.