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

时间:2015-02-12 16:10:53

标签: ios photokit phasset

文档说:

  

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

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

如果图片不可用,我想让用户下载它(但不要自动进行,至少在没有Wifi的情况下不这样做。)

那么如何确定是否需要下载图像呢?

更加好奇:当我的结果块 requestImageForAsset:targetSize:contentMode:options:resultHandler: 调用需要下载的图像,在传递较小且降级的版本后,我使用requestedImage == nil进行最后一次调用。

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

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

在照片应用中打开图像后,结果处理程序的最后一次调用具有完整大小的图像,但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
}];

5 个答案:

答案 0 :(得分:13)

如果您在requestImageDataForAsset:设置为networkAccessAllowed的情况下致电NO,则如果尚未从iCloud下载剪辑,则返回的imageData将为nil。否则它将返回实际数据,即使剪辑存储在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
        }
    }
 }];

答案 1 :(得分:9)

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

答案 2 :(得分:1)

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

-MP

答案 3 :(得分:1)

检查PHAsset是否仍在云中的最佳方法是尝试通过PHImageManager使用networkAccessAllowed = NO访问它,如果您没有获得图像/资产,那么您知道它仍然在云中(它不会被下载):

    + (void)checkCloudStatusForPHAsset:(PHAsset*)phAsset completion:(void (^)(BOOL isInCloud))completionBlock
{
    if (phAsset) {
        if (phAsset.mediaType == PHAssetMediaTypeVideo) {
            PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
            options.version = PHVideoRequestOptionsVersionOriginal;
            options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
            options.networkAccessAllowed = NO;
            [[PHImageManager defaultManager] requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                completionBlock(asset == nil);
            }];
        }
        else if (phAsset.mediaType == PHAssetMediaTypeImage) {
            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.version = PHImageRequestOptionsVersionOriginal;
            options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
            options.resizeMode = PHImageRequestOptionsResizeModeNone;
            options.networkAccessAllowed = NO;
            [[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                completionBlock(imageData == nil);
            }];
        }
        else {
            completionBlock(NO);
        }
    }
    else {
        completionBlock(NO);
    }
}

答案 4 :(得分:0)

以防万一有人在尝试解决iOS 13中的错误时偶然发现了这个问题。

自iOS 8起,此线程中的方法已被弃用。

在iOS 13中,您需要改为调用此方法:

- (PHImageRequestID)requestImageDataAndOrientationForAsset:(PHAsset *)asset 
                                                   options:(PHImageRequestOptions *)options 
                                             resultHandler:(void (^)(NSData *imageData, NSString *dataUTI, CGImagePropertyOrientation orientation, NSDictionary *info))resultHandler;

https://developer.apple.com/documentation/photokit/phimagemanager/3237282-requestimagedataandorientationfo