21

我在 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 = <PLXPCShMemData: 0x1702214a0> 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;
})
4

4 回答 4

5

我在返回 nil 图像数据时遇到了类似症状的问题,requestImageDataForAsset但还伴随着这样的控制台错误消息:

[Generic] Failed to load image data for asset <PHAsset: 0x13d041940> 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 并从那时起升级到 11.2.5 后,问题突然开始出现在特定设备上,只有 iCloud 共享相册中的资产。考虑到可能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 照片共享”开关仍然可以修复它。据推测,恢复过程以某种方式破坏了一些缓存。我已将其报告为 Bug 38290463 给 Apple。

于 2018-02-09T01:29:10.157 回答
2

您可能正在遍历数组,并且内存没有及时释放,您可以尝试以下代码。确保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];
    }];
}
于 2015-01-27T12:53:50.400 回答
0

很长一段时间后回到这个问题,我已经解决了我的大部分问题。没有神秘,只是糟糕的代码:

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];
    ...
}

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

于 2016-12-07T02:32:10.413 回答
0

以下代码可能会有所帮助。我认为 PHImageRequestOptions 类有错误,所以我通过 nil ,然后修复错误。

   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                assetModel.size = imageData.length;
                NSString *filename = [asset valueForKey:@"filename"];
                assetModel.fileName = filename;
                dispatch_semaphore_signal(sema);
            }];
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
于 2019-11-04T01:41:19.947 回答