FetchAssetsWithLocalIdentifiers返回空数组

时间:2016-09-17 16:39:28

标签: ios phasset

我使用Photos.Framework将从相机拍摄的照片保存到我的图库中并检索它们。

这是我用来存储照片的代码:

    __block PHAssetCollection *album = [self getMyAlbumWithName:@"MyAlbumName"];
    if(album == nil)
    {
        [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) {

             album = [self getMyAlbumWithName:@"MyAlbumName"];
            [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
            {
                  _imageLocalIdentifier = imageId;
            } onError:^(NSError *error) {
                // No need to do anything
            }];
        } onError:^(NSError *error) {
            // No need to do anything
        }];
    }
    else
    {
        [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
        {
          _imageLocalIdentifier = imageId;
        } onError:^(NSError *error) {
            // No need to do anything
        }];
     }

-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName
{
    PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
                                                                               subtype:PHAssetCollectionSubtypeAlbumRegular
                                                                           options:nil];
    NSLog(@"assetCollections.count = %lu", assetCollections.count);
    if (assetCollections.count == 0) return nil;

    __block PHAssetCollection * myAlbum;
    [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) {
    NSLog(@"album:%@", album);
    NSLog(@"album.localizedTitle:%@", album.localizedTitle);
    if ([album.localizedTitle isEqualToString:AlbumName]) {
        myAlbum = album;
        *stop = YES;
        }
    }];

    if (!myAlbum) return nil;
    return myAlbum;
}

-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError
{
    //Check weather the album already exist or not
    if (![self getMyAlbumWithName:title])
    {
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            // Request editing the album.
            PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
            // Get a placeholder for the new asset and add it to the album editing request.
            PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection];
            if (placeHolder)
            {
                onSuccess(placeHolder.localIdentifier);
            }
        } completionHandler:^(BOOL success, NSError *error) {
            NSLog(@"Finished adding asset. %@", (success ? @"Success" : error));
            if (error)
            {
                onError(error);
            }
        }];
    }
}

-(void)addNewAssetWithImage:(UIImage *)image
                    toAlbum:(PHAssetCollection *)album
                  onSuccess:(void(^)(NSString *ImageId))onSuccess
                    onError: (void(^)(NSError * error)) onError
{
     [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        // Request creating an asset from the image.
        PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        // Request editing the album.
        PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
        // Get a placeholder for the new asset and add it to the album editing request.
        PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset];
        [albumChangeRequest addAssets:@[ placeHolder ]];
        NSLog(@"%@",placeHolder.localIdentifier);
        if (placeHolder) {
            onSuccess(placeHolder.localIdentifier);
        }
    } completionHandler:^(BOOL success, NSError *error) {
        NSLog(@"Finished adding asset. %@", (success ? @"Success" : error));
        if (error) {
            onError(error);
        }
    }];
}

这是我用来检索此照片的代码:

    PHImageManager *imgManager = [[PHImageManager alloc] init];
    PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[_imageLocalIdentifier] options:nil];
    if([fetchResult count] > 0)
    {
        PHAsset *asset = [fetchResult objectAtIndex:0];
        PHImageRequestOptions *option = [PHImageRequestOptions new];
        option.synchronous = NO;
        option.version = PHImageRequestOptionsVersionCurrent;
        option.networkAccessAllowed = YES;
        option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
        option.resizeMode = PHImageRequestOptionsResizeModeFast;
        [imgManager requestImageForAsset:asset
                              targetSize:CGSizeMake(CAMERA_GALLERY_SIZE, CAMERA_GALLERY_SIZE)
                             contentMode:PHImageContentModeDefault
                                 options:option
                           resultHandler:^(UIImage *result, NSDictionary *info) {
                               [cell.photoIV setImage:result];
                           }];
    }

使用这段代码,在存储的12张照片的样本中(他们在我的相册中可以正常)4或5个本地标识符返回空的获取结果。 这是在iOS 8,iOS 9和iOS 10中测试的(iOS 10确实更糟糕,因为几乎所有的获取结果都是空的。)

我已经读到类似于此的内容是以前版本的iOS中的一个错误,但我想这不是现在的原因。

我已尝试使用此方法检索照片:

- (PHAsset *)getAssetFromGallery:(NSString *)identifier
{
    PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[identifier] options:nil].lastObject;
    if(asset != nil)
        return asset;

    __block PHAsset *result;
    PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    [fetchOptions setPredicate:[NSPredicate predicateWithFormat:@"localIdentifier == %@", identifier]];

    [userAlbums enumerateObjectsUsingBlock:^(id  _Nonnull objectCollection, NSUInteger idx, BOOL * _Nonnull stopCollectionEnumeration) {

        PHAssetCollection *collection = nil;
        if(![objectCollection isKindOfClass:[PHAssetCollection class]])
            return;
        collection = (PHAssetCollection *)objectCollection;

        PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
        [assetsFetchResult enumerateObjectsUsingBlock:^(id  _Nonnull objectAsset, NSUInteger idx, BOOL * _Nonnull stopAssetEnumeration) {
            PHAsset *asset = nil;
            if(![objectAsset isKindOfClass:[PHAsset class]])
                return;
            result = asset;
            *stopAssetEnumeration = YES;
            *stopCollectionEnumeration = YES;
        }];

    }];

    return asset;
}

我已尝试使用PHAssetCollectionSubtypeAlbumMyPhotoStream代替PHAssetCollectionSubtypeAny。 我尝试使用@"localIdentifier ==[cd] %@"代替@"localIdentifier == %@". 并且总是相同的结果,很多时候获取结果都是空的。 知道它发生了什么吗?

1 个答案:

答案 0 :(得分:1)

我的问题是我没有以正确的方式保存照片,我正在调用onSuccess(placeHolder.localIdentifier);在performChanges块内,而不是在completionHandler块内。

这是我现在用来保存照片的代码:

__block PHAssetCollection *album = [AuxiliaryFunctions getMyAlbumWithName:@"MyAlbumName" orWithIdentifier:@""];
if(album == nil)
    [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) {

        album = [self getMyAlbumWithName:@"MyAlbumName" orWithIdentifier:AlbumId];
        [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
         {
            _imageLocalIdentifier = imageId;
        } onError:^(NSError *error) {
            // No need to do anything
        }];
    } onError:^(NSError *error) {
        // No need to do anything
    }];
else
{
    [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) 
     {
            _imageLocalIdentifier = imageId;
    } onError:^(NSError *error) {
        // No need to do anything
    }];
}


-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName orWithIdentifier:(NSString *)identifier
{
    PHFetchResult *assetCollections = nil;
    if(![identifier isEqualToString:@""])
    {
        PHFetchOptions *options = [PHFetchOptions new];
        options.predicate = [NSPredicate predicateWithFormat:@"localIdentifier = %@ OR title = %@", identifier, AlbumName];
        assetCollections = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[identifier]
                                                                                options:options];
    }
    else
    {
        PHFetchOptions *options = [PHFetchOptions new];
        options.predicate = [NSPredicate predicateWithFormat:@"title = %@", AlbumName];
        assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
                                                                                   subtype:PHAssetCollectionSubtypeAny
                                                                                   options:options];
    }

    NSLog(@"assetCollections.count = %lu", assetCollections.count);
    if (assetCollections.count == 0) return nil;

    __block PHAssetCollection * myAlbum;
    [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) {
        NSLog(@"album:%@", album);
        NSLog(@"album.localizedTitle:%@", album.localizedTitle);
        if ([album.localizedTitle isEqualToString:AlbumName]) {
            myAlbum = album;
            *stop = YES;
        }
    }];

    if (!myAlbum) return nil;
    return myAlbum;
}

-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError
{
    __block NSString *localIdentifier = @"";
    //Check weather the album already exist or not
    if (![self getMyAlbumWithName:title orWithIdentifier:@""])
    {
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            // Request editing the album.
            PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
            // Get a placeholder for the new asset and add it to the album editing request.
            PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection];
            if (placeHolder)
            {
                localIdentifier = placeHolder.localIdentifier;
                // This line was the problem
                //onSuccess(localIdentifier);
            }
        } completionHandler:^(BOOL success, NSError *error) {
            NSLog(@"Finished adding asset. %@", (success ? @"Success" : error));
            if(success)
            {
                onSuccess(localIdentifier);
            }
            if (error)
            {
                onError(error);
            }
        }];
    }
}

-(void)addNewAssetWithImage:(UIImage *)image
                    toAlbum:(PHAssetCollection *)album
                  onSuccess:(void(^)(NSString *ImageId))onSuccess
                    onError: (void(^)(NSError * error)) onError
{
    __block NSString *localIdentifier = @"";
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        // Request creating an asset from the image.
        PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        // Request editing the album.
        PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
        // Get a placeholder for the new asset and add it to the album editing request.
        PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset];
        [albumChangeRequest addAssets:@[ placeHolder ]];
        NSLog(@"%@",placeHolder.localIdentifier);
        if (placeHolder) {
            localIdentifier = placeHolder.localIdentifier;
            // This line was the problem
            //onSuccess(localIdentifier);
        }
    } completionHandler:^(BOOL success, NSError *error) {
        NSLog(@"Finished adding asset. %@", (success ? @"Success" : error));
        if(success)
        {
            onSuccess(localIdentifier);
        }
        if (error)
        {
            onError(error);
        }
    }];
}