私はiOS8.1で写真フレームワークを使用しており、requestImageDataForAssetを使用してアセットの画像データをリクエストしています...ほとんどの場合それは機能し、画像データと以下に表示される内容を含む辞書を取得します。しかし、呼び出しが完了することもありますが、データはnilであり、ディクショナリには3つの一般的なエントリが含まれています。
呼び出しは順番に、同じスレッドで実行されます。特定の画像に固有のものではありません。このエラーは、過去に正常に開いた画像で発生します。誰かがこれに遭遇しましたか?
+ (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;
})
配列を反復処理している可能性が高く、メモリが適時に解放されていません。以下のコードを試すことができます。 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 <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
が(情報ディクショナリのPHImageFileURLKey
キーから)/var/mobile/Media/PhotoData/PhotoCloudSharingData/
にローカルにキャッシュされたファイルを使用しようとしていて、キャッシュが壊れている可能性があると思って、そのキャッシュをクリアする方法について考えました。
IOSの「iCloud写真共有」スイッチの切り替え設定->アカウントとパスワード-> iCloud->写真でうまくいったようです。 requestImageDataForAsset
は、以前は失敗していたアセットで機能するようになりました。
2018年3月9日更新
この問題を再現できます。 iTunesからバックアップを復元した後に発生するようです:
「iCloud写真共有」スイッチを切り替えると、まだ修正されます。おそらく復元プロセスが何らかのキャッシュを破壊しています。バグ38290463としてAppleに報告しました。
次のコードが役立つかもしれません。 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);
久しぶりにこれに戻り、問題の大部分を解決しました。謎はなく、ただ悪いコード:
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
がデフォルトの情報オブジェクトを返すことでした。