照片框架requestImageDataForAsset偶尔会失败

我在iOS8.1上使用照片框架,并使用requestImageDataForAsset请求资产的图像数据……大多数时候它都可以工作,我得到的图像数据和包含你在下面看到的内容的字典。 但有时调用完成,但数据为零,字典包含三个通用的查找条目。

调用按顺序执行并在同一线程上执行。 它不是特定于任何特定图像。 错误将发生在我过去成功打开的图像上。 有没有人遇到过这个?

+ (NSData *)retrieveAssetDataPhotosFramework:(NSURL *)urlMedia resolution:(CGFloat)resolution imageOrientation:(ALAssetOrientation*)imageOrientation { __block NSData *iData = nil; PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[urlMedia] options:nil]; PHAsset *asset = [result firstObject]; PHImageManager *imageManager = [PHImageManager defaultManager]; PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init]; options.synchronous = YES; options.version = PHImageRequestOptionsVersionCurrent; @autoreleasepool { [imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { iData = [imageData copy]; NSLog(@"requestImageDataForAsset returned info(%@)", info); *imageOrientation = (ALAssetOrientation)orientation; }]; } assert(iData.length != 0); return iData; } 

这是我获得图像数据和元数据字典的理想结果:

 requestImageDataForAsset returned info({ PHImageFileDataKey =  bufferLength=1753088 dataLength=1749524; PHImageFileOrientationKey = 1; PHImageFileSandboxExtensionTokenKey = "6e14948c4d0019fbb4d14cc5e021199f724f0323;00000000;00000000;000000000000001a;com.apple.app-sandbox.read;00000001;01000003;000000000009da80;/private/var/mobile/Media/DCIM/107APPLE/IMG_7258.JPG"; PHImageFileURLKey = "file:///var/mobile/Media/DCIM/107APPLE/IMG_7258.JPG"; PHImageFileUTIKey = "public.jpeg"; PHImageResultDeliveredImageFormatKey = 9999; PHImageResultIsDegradedKey = 0; PHImageResultIsInCloudKey = 0; PHImageResultIsPlaceholderKey = 0; PHImageResultWantedImageFormatKey = 9999; }) 

这是我偶尔得到的。 图像数据为零。 字典包含的不是那么多。

 requestImageDataForAsset returned info({ PHImageResultDeliveredImageFormatKey = 9999; PHImageResultIsDegradedKey = 0; PHImageResultWantedImageFormatKey = 9999; }) 

您可能正在遍历数组,并且内存未及时释放,您可以尝试以下代码。 确保theData__block标记。

 @autoreleasepool { [imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { NSLog(@"requestImageDataForAsset returned info(%@)", info); theData = [imageData copy]; }]; } 

我有一个类似症状的问题,其中requestImageDataForAsset返回nil图像数据,但也伴随着如下控制台错误消息:

[Generic] Failed to load image data for asset 87CCAFDC-A0E3-4AC9-AD1C-3F57B897A52E/L0/001 mediaType=1/0, sourceType=2, (113x124), creationDate=2015-06-29 04:56:34 +0000, location=0, hidden=0, favorite=0 with format 9999

在我的情况下,在从iOS 10.x升级到11.0.3之后,从iCloud共享相册中的资产突然开始在特定设备上发生问题,从那时到11.2.5。 想想可能requestImageDataForAsset试图使用本地缓存在/var/mobile/Media/PhotoData/PhotoCloudSharingData/ (来自信息字典的PHImageFileURLKey键)并且缓存可能已损坏我想到了如何清除缓存。

切换iOS 设置 – >帐户和密码中的’iCloud照片共享’开关– > iCloud – >照片似乎已经完成了这一操作。 requestImageDataForAsset现在适用于那些以前失败的资产。

2018年3月9日更新

我现在可以重现这个问题。 它似乎是从iTunes恢复备份后发生的:

  1. 使用iOS应用程序并从iCloud共享相册中检索照片。
  2. 使用iTunes备份iOS设备。
  3. 使用iTunes恢复备份。
  4. 再次使用该应用程序从iCloud共享相册中检索相同的照片现在失败,并显示上述控制台消息。

切换“iCloud照片共享”开关仍可修复它。 据推测,恢复过程会以某种方式破坏某些缓存。 我已将其报告为Apple的Bug 38290463。

经过一段时间的回归,我解决了我的大部分问题。 没有神秘感,只是糟糕的代码:

 PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[urlMedia] options:nil]; PHAsset *asset = [result firstObject]; if (asset != nil) { // the fix PHImageManager *imageManager = [PHImageManager defaultManager]; PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init]; ... } 

对我来说最常见的原因是传递给fetchAssetsWithALAssetURLs的媒体URL出现问题,导致资产为nil, requestImageDataForAsset返回默认信息对象。