PHChange changeDetailsForFetchResult - винаги връща нула

Използвам PHPhotoLibrary, за да извлека няколко колекции от снимки като тази:

_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];
}];


Методът analyzeCollectionInternal записва PHAssetCollections за по-късна употреба и показва съдържанието на колекциите.

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

    [...]
}


Освен това регистрирах наблюдател на промени в библиотеката със снимки по следния начин:

[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];


Класът, който действа като наблюдател, имплементира протокола PHPhotoLibraryChangeObserver по следния начин:

- (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];
        }
    });
}


Сега, ако отворя приложението Photos за добавяне/промяна/изтриване на снимки от „Всички снимки“-SmartAlbum, Change-Observer се извиква, но извикването на

[changeInstance changeDetailsForFetchResult:_smartAlbumsFetchResult]

връща само nil, дори ако обектът PHChange съдържа insertedObjectIDs и changedObjectIDs. Същото важи, когато правите екранна снимка с помощта на бутона Home и Lock на iDevice.


person Sebastian Krogull    schedule 05.10.2015    source източник
comment
Малко късно, но опитахте ли да извикате [PHAssetCollection fetchAssetCollectionsWithType:...] с различни от нула опции и с wantsIncrementalChangeDetails = YES?   -  person Ivan    schedule 15.12.2016


Отговори (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;
}

тогава: PHFetchResultChangeDetails *smartAlbumChanges = [changeInstance changeDetailsForFetchResult:[self.phAssetArray objectAtIndex:0]];

person RichardX    schedule 21.07.2016
comment
моля, вижте Как да отговоря - person JimHawkins; 21.07.2016