如何识别PHAsset是否没有完全从iCloud下载(所以我需要再次请求options.networkAccessAllowed)

文档说:

PHImageResultIsInCloudKey:一个布尔值,指示照片资产数据是存储在本地设备还是必须从iCloud下载。 (NSNumber)如果是,则不提供图像,因为资产数据必须从iCloud下载。 要下载数据,请提交另一个请求,并为networkAccessAllowed选项指定YES。

但是,当资产存储在iCloud照片库中时,即使已将其完全下载到设备(在我的应用程序中下载,也在照片应用程序中打开它),这个键始终为YES。

如果图像不可用,我想给用户一个下载的可能性(但不要自动执行,至less在没有Wifi的情况下)。

那么如何找出图像是否需要下载?

更好奇的是:当我的requestImageForAsset:targetSize:contentMode:options:resultHandler:结果块被调用,需要下载的图片时,我得到了最后一个调用requestedImage ==零后,一个较小的和退化的版本交付。

在这种情况下,降级是NO,即使我没有图像,图像仍然必须从iCloud下载,因为从应用程序只有一个小的缩略图到目前为止本地可用。

我在iPhone和iPad上testing了不同的iOS 8版本(8.1.x,8.2 beta,8.3 beta),这种行为总是一样的。

一旦我在照片应用程序中打开图像,结果处理程序的最后一次调用具有全尺寸的图像,但PHImageResultIsInCloudKey仍然是YES。

以下是我如何请求图像的一些代码:

 PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init]; options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; options.networkAccessAllowed = NO; [self.imageManager requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *requestedImage, NSDictionary *info) { // Checking for requestedImage and the info keys here // When a full sized image was loaded, the result of PHImageResultIsInCloudKey is still YES // When a full sized image couldn't be loaded cause it's in the cloud, isDegraded is NO and PHImageResultIsInCloudKey is YES (as always) and requestedImage is nil }]; 

我可以确认PHImageResultIsInCloudKey是不可靠的。 对于存储在iCloud中的图像,即使原始图像已下载到设备,也会返回1。 这种行为与文档相反,我build议在radar.apple.com上报告一个错误。 PhotoKit在我看来仍然是一个非常不成熟的框架 – 它包含了很多问题,也有一些奇怪的概念决定。

如果调用requestImageDataForAsset:networkAccessAllowed设置为NO ,如果剪辑尚未从iCloud下载,返回的imageDatanil 。 否则,即使剪辑存储在iCloud中,也会返回实际数据。

 PHImageManager *manager = [PHImageManager defaultManager]; PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.networkAccessAllowed = NO; [manager requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) { if ([[info valueForKey:PHImageResultIsInCloudKey] boolValue]) { // Image is in iCloud if (imageData) { // Image is downloaded } else { // Image is not downloaded } } }]; 

您可以使用progressHandler检查PHAsset是否来自iCloud。

 __block BOOL isPhotoInICloud = NO; PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){ isPhotoInICloud = YES; // some code to update the download progress }); options.networkAccessAllowed = YES; options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; options.synchronous = NO; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { // use the options to get the high quality image for only once time. });