ios - FetchAssetsWithLocalIdentifiers 返回空数组

标签 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 == %@".并且总是相同的结果,很多时候获取结果是空的。
知道发生了什么吗?

最佳答案

我的问题是我没有以正确的方式保存照片,我正在调用 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);
        }
    }];
}

关于ios - FetchAssetsWithLocalIdentifiers 返回空数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39549226/

相关文章:

iphone - 我可以在 iPhone 应用商店 ID 字段中写入多少个 ID?

ios - 使用 Swift 4 中的 PHAssetCollection 从特定相册中获取特定照片

ios - PHAssetManager 在请求图像时忽略 targetSize?

ios - PhotoKit 框架 : What is assetSource of PHAsset?

ios - 如何在 fetch PHAssetCollection 语句中获取 "Camera Roll"、 "Videos"、 "Favorites"、 "Selfies"和 "Screenshots"- swift 4

ios - 在运行时增加 tableview 高度以包含全部内容

ios - Xcode 6 iPair Air 无法在设备上运行应用程序(操作系统版本)

ios - 在 block 中修改后,Swift 结构未更新

ios - 没有这样的文件或目录,但文件存在 Xcode

ios - 从现有 phAsset 修改元数据似乎不起作用