文档说:
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
}];
答案 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;