PHChange changeDetailsForFetchResult - always returns nil
Asked Answered
O

1

9

I am using the PHPhotoLibrary to retrieve several photo collections like this:

_smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil];
[_smartAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
    [self analyzeCollectionInternal:collection];
}];

_userAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:userAlbumsOptions];
[_userAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
    [self analyzeCollectionInternal:collection];
}];


The Method analyzeCollectionInternal saves the PHAssetCollections for later use and displays the contents of the collections.

- (void)analyzeCollectionInternal:(PHAssetCollection *)collection {
    NSLog(@"Album Title %@", collection.localizedTitle);
    if (![_collections containsObject:collection]) {
        [_collections addObject:collection];
    }

    [...]
}


Additionally I registered a change observer to the Photos library like this:

[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];


The class that acts as Observer implements the PHPhotoLibraryChangeObserver Protocol like this:

- (void)photoLibraryDidChange:(PHChange *)changeInstance {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"PicturesDataSource - photoLibraryDidChange");
        NSMutableArray *collectionsToAnalyze = [NSMutableArray new];
        NSMutableArray *collectionsToDelete = [NSMutableArray new];

        if (_smartAlbumsFetchResult) {
            PHFetchResultChangeDetails *smartAlbumChanges = [changeInstance changeDetailsForFetchResult:_smartAlbumsFetchResult];
            NSLog(@"PictureDataSource - changeDetailsForFetchResult(_smartAlbumsFetchResult): %@", smartAlbumChanges);
            if (smartAlbumChanges) {
                _smartAlbumsFetchResult = [smartAlbumChanges fetchResultAfterChanges];
                [collectionsToAnalyze addObjectsFromArray:smartAlbumChanges.insertedObjects];
                [collectionsToAnalyze addObjectsFromArray:smartAlbumChanges.changedObjects];
                [collectionsToDelete addObjectsFromArray:smartAlbumChanges.removedObjects];
            }
        }

        if (_userAlbumsFetchResult) {
            PHFetchResultChangeDetails *userAlbumChanges = [changeInstance changeDetailsForFetchResult:_userAlbumsFetchResult];
            NSLog(@"PictureDataSource - changeDetailsForFetchResult(_userAlbumsFetchResult): %@", userAlbumChanges);
            if (userAlbumChanges) {
                _userAlbumsFetchResult = [userAlbumChanges fetchResultAfterChanges];
                [collectionsToAnalyze addObjectsFromArray:userAlbumChanges.insertedObjects];
                [collectionsToAnalyze addObjectsFromArray:userAlbumChanges.changedObjects];
                [collectionsToDelete addObjectsFromArray:userAlbumChanges.removedObjects];
            }
        }

        for (PHAssetCollection *collectionToAnalyze in collectionsToAnalyze) {
            [self analyzeCollection:collectionToAnalyze];
        }

        for (PHAssetCollection *collectionToDelete in collectionsToDelete) {
            [self deleteCollection:collectionToDelete];
        }
    });
}


Now if I open the Photos app to Add/Change/Delete photos from the "All Photos"-SmartAlbum, the Change-Observer gets called, but the call of

[changeInstance changeDetailsForFetchResult:_smartAlbumsFetchResult]

only returns nil, even if the PHChange object contains insertedObjectIDs and changedObjectIDs. The same applies when taking a screenshot using the Home- and the Lock-Button of the iDevice.

Outstay answered 5/10, 2015 at 12:33 Comment(1)
A bit late, but have you tried to call [PHAssetCollection fetchAssetCollectionsWithType:...] with non-nil options and with wantsIncrementalChangeDetails = YES?Safir
S
-1
@property (nonatomic,strong) NSMutableArray *assetCollectionsArray;
@property (nonatomic,strong) NSMutableArray *phAssetArray;

-(void)initPHAssetData
{self.assetCollectionsArray = [self updateAssetCollections];
self.phAssetArray = [[NSMutableArray alloc] init];
for (int i=0; i<[self.assetCollectionsArray count]; i++) {
    PHFetchResult *cFetchResult = [self updateFetchRequest:(int)i];

    [self.phAssetArray addObject:cFetchResult];
}
}

- (NSMutableArray *)updateAssetCollections
{
NSArray *assetCollectionSubtypes = [NSArray arrayWithArray:self.phAssetSubTypeArray];

NSMutableDictionary *smartAlbums = [NSMutableDictionary dictionaryWithCapacity:assetCollectionSubtypes.count];
NSMutableArray *userAlbums = [NSMutableArray array];

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

PHFetchResult *userAlbums1 = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
NSArray *fetchResults = @[smartAlbumsFetchResult, userAlbums1];


for (PHFetchResult *fetchResult in fetchResults) {
    [fetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *assetCollection, NSUInteger index, BOOL *stop) {
        PHAssetCollectionSubtype subtype = assetCollection.assetCollectionSubtype;

        if (subtype == PHAssetCollectionSubtypeAlbumRegular) {
            if ([assetCollectionSubtypes containsObject:@(subtype)])
                [userAlbums addObject:assetCollection];
        } else if ([assetCollectionSubtypes containsObject:@(subtype)]) {
            if (!smartAlbums[@(subtype)]) {
                smartAlbums[@(subtype)] = [NSMutableArray array];
            }
            [smartAlbums[@(subtype)] addObject:assetCollection];
        }
    }];
}

NSMutableArray *assetCollections = [NSMutableArray array];

// Fetch smart albums
for (NSNumber *assetCollectionSubtype in assetCollectionSubtypes) {
    NSArray *collections = smartAlbums[assetCollectionSubtype];

    if (collections) {
        [assetCollections addObjectsFromArray:collections];
    }
}

// Fetch user albums
[userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *assetCollection, NSUInteger index, BOOL *stop) {
    [assetCollections addObject:assetCollection];
}];

return assetCollections;
}

- (PHFetchResult *)updateFetchRequest:(int)index
{
PHFetchResult *phFetchResult;
if (self.assetCollectionsArray || [self.assetCollectionsArray count]>0) {
    PHFetchOptions *options = [PHFetchOptions new];

    PHAssetCollection *assetCollection = [self.assetCollectionsArray objectAtIndex:index];

    switch (assetCollection.assetCollectionSubtype) {
        case PHAssetCollectionSubtypeAlbumMyPhotoStream:
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
            break;
        case PHAssetCollectionSubtypeSmartAlbumVideos:
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeVideo];
            break;
        case PHAssetCollectionSubtypeSmartAlbumUserLibrary:
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
            break;
        default:
            options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld || mediaType == %ld", PHAssetMediaTypeVideo,PHAssetMediaTypeImage];
            break;
            break;
    }

    phFetchResult = [PHAsset fetchAssetsInAssetCollection:[self.assetCollectionsArray objectAtIndex:index] options:options];
} else {
    phFetchResult = nil;
}

return phFetchResult;
}

then: PHFetchResultChangeDetails *smartAlbumChanges = [changeInstance changeDetailsForFetchResult:[self.phAssetArray objectAtIndex:0]];

Shylashylock answered 21/7, 2016 at 9:4 Comment(1)
please look at How to AnswerSector

© 2022 - 2024 — McMap. All rights reserved.