检查给定的PHAsset是否是iCloud资产?

我试图获得PhAsset对象。 我想分离iCloud资产。 这是我的代码,

PHFetchResult *cloudAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; [cloudAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop){ if(collection != nil){ PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; [result enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { // check asset is iCloud asset }]; } }]; 

请告诉我如何findPHAsset是iCloud资产?

实际上有两种情况:1.照片被该设备捕获,并上传到iCloud。 然后,您可以使用progressHandler来检查是否需要iCloud下载。

 __block BOOL isPhotoInICloud = NO; PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.networkAccessAllowed = YES; options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){ isPhotoInICloud = YES; }); [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { if (isPhotoInICloud) { // Photo is in iCloud. } }); 
  1. 照片在iCloud中,但从其他设备上传。 而且你没有把它保存到你的本地照片库。 所以progressHandler块永远不会被调用。 我不知道为什么,但是这是真的,我认为这是一个PhotoKit框架的错误。 对于这种情况,如果使用PHImageResultIsInCloudKey,那也很困难。 因为您可以只在requestImageForAsset的resultHandler块中知道PHImageResultIsInCloudKey值。 但这是照片请求启动后的时间。

因此,至less在我看来,无法检查照片是否存储在iCloud中。 也许还有其他更好的方法,请让我知道。 非常感谢!

以下是一个可以实现的方法来获取Photos应用程序的Videos文件夹中的所有video,该应用程序使用PHFetchRequest的谓词来仅过滤存储在iPhone本身而不是iCloud中的video:

 // Collect all videos in the Videos folder of the Photos app - (PHFetchResult *)assetsFetchResults { __block PHFetchResult *i = self->_assetsFetchResults; if (!i) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ PHFetchOptions *fetchOptions = [PHFetchOptions new]; fetchOptions.predicate = [NSPredicate predicateWithFormat:@"(sourceType & %d) != 0", PHAssetSourceTypeUserLibrary]; PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumVideos options:fetchOptions]; PHAssetCollection *collection = smartAlbums.firstObject; if (![collection isKindOfClass:[PHAssetCollection class]]) collection = nil; PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init]; allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]; i = [PHAsset fetchAssetsInAssetCollection:collection options:allPhotosOptions]; self->_assetsFetchResults = i; }); } return i; } 

苹果关于PHFetchResult的文档指出,只有一部分属性可以用于谓词; 因此,如果上述代码不适用于您,请删除PHFetchOptions谓词,并将PHFetchRequest中的相应引用replace为nil:

 // Collect all videos in the Videos folder of the Photos app - (PHFetchResult *)assetsFetchResults { __block PHFetchResult *i = self->_assetsFetchResults; if (!i) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumVideos options:nil]; PHAssetCollection *collection = smartAlbums.firstObject; if (![collection isKindOfClass:[PHAssetCollection class]]) collection = nil; PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init]; allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]; i = [PHAsset fetchAssetsInAssetCollection:collection options:allPhotosOptions]; self->_assetsFetchResults = i; }); } return i; } 

然后,添加这一行:

 // Filter videos that are stored in iCloud - (NSArray *)phAssets { NSMutableArray *assets = [NSMutableArray arrayWithCapacity:self.assetsFetchResults.count]; [[self assetsFetchResults] enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { if (asset.sourceType == PHAssetSourceTypeUserLibrary) [assets addObject:asset]; }]; return [NSArray arrayWithArray:(NSArray *)assets]; } 

当您请求图像时,您会在信息字典中获得一个密钥,告诉您资产是否存在于iCloud中。

 [cloudAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) { PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; [result enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.resizeMode = PHImageRequestOptionsResizeModeFast; options.synchronous = YES; __block BOOL isICloudAsset = NO; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { if ([info objectForKey: PHImageResultIsInCloudKey].boolValue) { isICloudAsset = YES; } }]; }]; }]; 

这是一种黑客攻击,我不得不挖掘资源arrays和debugging,以找出我所需的信息。 但它的作品。 虽然这是一个无证的代码,我不确定苹果是否会因为这个而拒绝这个应用程序。 试一试,看看会发生什么!

 // asset is a PHAsset object for which you want to get the information NSArray *resourceArray = [PHAssetResource assetResourcesForAsset:asset]; BOOL bIsLocallayAvailable = [[resourceArray.firstObject valueForKey:@"locallyAvailable"] boolValue]; // If this returns NO, then the asset is in iCloud and not saved locally yet 

您还可以从资产资源中获得一些其他有用的信息,例如 – 原始文件名,文件大小,文件URL等。