PHPhotoLibrary を使用して写真を保存しようとしています。その写真を一時ファイルとしてアプリのドキュメント フォルダーに保存しました。
以下は私の店の写真コードで、NSOperationQueue を使用してバックグラウンドで実行されています
- (void)_storePhotoToAblum:(NSDictionary *)photoDic {
NSString *fileName = (NSString *)[photoDic valueForKey:@"Path"];
NSString *fileURL = [NSString stringWithFormat:@"%@/%@", _rootPath, fileName];
NSArray *folders = (NSArray *)[photoDic objectForKey:@"albumName"];
// Add it to the photo library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:[NSURL fileURLWithPath:fileURL]];
for (NSString *folderID in folders) {
// if have custom albums
PHFetchOptions *options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:@"title = %@", folderID];
PHAssetCollection *collection = [[PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:options] firstObject];
if (collection) {
// Save photo in album
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
[assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
}
}
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
[self.delegate updateDuplicatePhoto:fileURL withPhotoInfo:photoDic success:YES orError:nil];
} else {
NSLog(@"Error:%@", error.localizedDescription);
[self.delegate updateDuplicatePhoto:fileURL withPhotoInfo:photoDic success:NO orError:error];
}
}];
}
photoDic
"path" を文字列、"size" を文字列、"albumName" を配列として含む辞書です。
写真の保存プロセスを開始する前に、すべての顧客アルバムを作成しました。
また、完了ハンドラーのデリゲート関数は、アプリ ドキュメント フォルダー内の一時ファイルを削除するためだけのものです。
しかし、以下のクラッシュレポートを入手しました。
OS Version: iOS 8.4 (12H143)
Report Version: 105
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread: 8
Last Exception Backtrace:
0 CoreFoundation 0x183c642d8 __exceptionPreprocess + 132
1 libobjc.A.dylib 0x1959380e4 objc_exception_throw + 60
2 CoreFoundation 0x183b4af70 -[__NSPlaceholderArray initWithObjects:count:] + 412
3 CoreFoundation 0x183b57200 +[NSArray arrayWithObjects:count:] + 60
4 Content Transf 0x1001048bc __39-[PhotoStoreHelper _storePhotoToAblum:]_block_invoke + 588 (PhotoStoreHelper.m:109)
5 Photos 0x187d36424 __51-[PHPhotoLibrary performChanges:completionHandler:]_block_invoke + 48
6 libdispatch.dylib 0x195fb5994 _dispatch_call_block_and_release + 24
7 libdispatch.dylib 0x195fb5954 _dispatch_client_callout + 16
8 libdispatch.dylib 0x195fc00a4 _dispatch_queue_drain + 1448
9 libdispatch.dylib 0x195fb8a5c _dispatch_queue_invoke + 132
10 libdispatch.dylib 0x195fc2318 _dispatch_root_queue_drain + 720
11 libdispatch.dylib 0x195fc3c4c _dispatch_worker_thread3 + 108
12 libsystem_pthread.dylib 0x19619522c _pthread_wqthread + 816
13 libsystem_pthread.dylib 0x196194ef0 start_wqthread + 4
Thread 8 name:
Thread 8 Crashed:
0 libsystem_kernel.dylib 0x00000001960fb270 __pthread_kill + 8
1 libsystem_pthread.dylib 0x000000019619916c pthread_kill + 108
2 libsystem_c.dylib 0x0000000196072b14 abort + 108
3 libc++abi.dylib 0x0000000195105414 abort_message + 112
4 libc++abi.dylib 0x0000000195124b88 default_terminate_handler() + 300
5 libobjc.A.dylib 0x00000001959383bc _objc_terminate() + 124
6 libc++abi.dylib 0x0000000195121bb0 std::__terminate(void (*)()) + 12
7 libc++abi.dylib 0x0000000195121474 __cxa_throw + 132
8 libobjc.A.dylib 0x0000000195938200 objc_exception_throw + 344
9 CoreFoundation 0x0000000183b4af6c -[__NSPlaceholderArray initWithObjects:count:] + 408
10 CoreFoundation 0x0000000183b571fc +[NSArray arrayWithObjects:count:] + 56
11 Content Transf 0x00000001001048b8 __39-[PhotoStoreHelper _storePhotoToAblum:]_block_invoke + 584 (PhotoStoreHelper.m:109)
12 Photos 0x0000000187d36420 __51-[PHPhotoLibrary performChanges:completionHandler:]_block_invoke + 44
13 libdispatch.dylib 0x0000000195fb5990 _dispatch_call_block_and_release + 20
14 libdispatch.dylib 0x0000000195fb5950 _dispatch_client_callout + 12
15 libdispatch.dylib 0x0000000195fc00a0 _dispatch_queue_drain + 1444
16 libdispatch.dylib 0x0000000195fb8a58 _dispatch_queue_invoke + 128
17 libdispatch.dylib 0x0000000195fc2314 _dispatch_root_queue_drain + 716
18 libdispatch.dylib 0x0000000195fc3c48 _dispatch_worker_thread3 + 104
19 libsystem_pthread.dylib 0x0000000196195228 _pthread_wqthread + 812
20 libsystem_pthread.dylib 0x0000000196194eec start_wqthread + 0
オンラインでクラッシュしました:
[assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
assetChangeRequest プレースホルダーが nil を返すようです。この nil を配列に追加しています。
この問題を再現しようとしていますが、photoDic に nil が含まれていると、作成している URL が正しくなくなり、この関数は失敗ハンドラーをエラーと共に返します。
fileURL が正しくなく、ファイルが見つからない場合、この関数はアプリをクラッシュさせる代わりに操作を終了できないというエラーを含む失敗ハンドラーを返します。
フォルダー情報の取得に何か問題があった場合、空のケースを処理する for ループと if 句があるため、クラッシュした行が呼び出されることはありません。
その行でクラッシュすることはありません。
placeholderForCreatedAsset
ゼロになるケースはありますか?または、私がカバーしていない他のケースがこの問題を引き起こし、このクラッシュレポートを生成する可能性がありますか?