My application has function to downloads many photo and video files in tmp folder and save them in camera roll with PHPhotoLibrary API.
The problem is that sometimes (the probability is around 10%) exception happens in the saving process.
The error message in console is,
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]'
My code is like below:
- (void)saveVideoFileInCameraRoll:(NSString *)videoFilePath
{
NSURL *videoFileUrl = [NSURL fileURLWithPath:videoFilePath];
photoLibrarySaveImageCompletion completion = ^(BOOL success, NSError *error) {
NSLog(@"success=%@, error=%@", (success ? @"YES" : @"NO"), error);
};
NSLog(@"videoFileUrl=%@", videoFileUrl);
[self saveVideoFile:videoFileUrl completion:completion];
}
- (void)saveVideoFile:(NSURL *)fileURL completion:(photoLibrarySaveImageCompletion)completion
{
NSLog(@"fileURL=%@", fileURL);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
NSLog(@"fileURL=%@", fileURL);
// Exception happens on this line as [SIGABRT]
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:fileURL];
if (_assetCollection) {
PHAssetCollectionChangeRequest *assetCollectionChangeRequest =
[PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.assetCollection];
[assetCollectionChangeRequest addAssets:@[ [assetChangeRequest placeholderForCreatedAsset] ]];
}
else {
NSLog(@"### assetCollection is nil ###");
}
}
completionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"success=%@, error=%@", (success ? @"YES" : @"NO"), error);
completion(success, error);
}];
}
I checked similar case:
Save image to photo library using photo framework
The case crashes every time, but my code rarely crashes.
And unlike the case I'm calling
[PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:]
in 'performChanges'
block
Also I confirmed the fileURL of video file in tmp folder by NSLog and it's OK outside and inside of 'performChanges'
block.
fileURL=file:///private/var/mobile/Containers/Data/Application/C87F0F75-E128-4E9F-AE07-6B914939AC5D/tmp/video3.mp4
I would appreciate it if you would let me know the reason or resolution of this issue.
This method can only be called from inside of
, which method is the error log talking about? – DillPHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:fileURL];
– DisenchantchangeRequestForAsset:
from insideperformChanges:
block, but the call was also inside another asynchronous block. Something to consider. – Levity