Exception in saving a lot of files with PHPhotoLibrary API - ios

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.

Related

Adding multiple assets to collection with Photo Framework - Objective-C

I have the following code:
-(void) saveFromLocationsArray: (NSArray*) locations{
[self.photoLib performChanges:^{
PHAssetChangeRequest *creationRequest;
NSMutableArray *changesArray = [[NSMutableArray alloc] init];
for(int i=0; i<locations.count; i++){
creationRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:locations[i]];
[changesArray addObject:[creationRequest placeholderForCreatedAsset]];
}
PHAssetCollectionChangeRequest *collectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.objcAppAlbum];
[collectionChangeRequest addAssets:changesArray];
} completionHandler:^(BOOL success, NSError *error) {
if(!success){
NSLog(#"an error has occured while trying to save pic to library: %#", error);
}
else{
NSLog(#"image was added to album ObjcApp");
}
}];
In a nutshell: I have an array of locations (URLS) of images I've just downloaded, and I'm trying to add them all to the iPhone's photo library. i managed to do so for one image (in a different method) but here it crashes on [collectionChangeRequest addAssets:changesArray], my guess is that the argument fo addAssest is invalid... but i can't figure out why.
this is the working code for one image only:
-(void) saveFromLocation: (NSURL*) location{
[self.photoLib performChanges:^{
PHAssetChangeRequest *creationRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:location];
PHAssetCollectionChangeRequest *collectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.objcAppAlbum];
NSArray *arr = [NSArray arrayWithObjects:[creationRequest placeholderForCreatedAsset], nil];
[collectionChangeRequest addAssets:arr];
} completionHandler:^(BOOL success, NSError *error) {
if(!success){
NSLog(#"an error has occured while trying to save pic to library: %#", error);
}
else{
NSLog(#"image was added to album ObjcApp");
}
}];
}
error: 2019-03-05 14:26:26.062368 ObjcProject[1026:371314]
-[__NSCFString path]: unrecognized selector sent to instance 0x1740fa880 2019-03-05 14:26:26.063343 ObjcProject[1026:371314] *
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFString path]:
unrecognized selector sent to instance 0x1740fa880'
* First throw call stack: (0x186d3d1b8 0x18577455c 0x186d44268 0x186d41270 0x186c3a80c 0x19276338c 0x192700ee8 0x19275e8c4
0x19275edfc 0x1914ae4b8 0x191d49c4c 0x19275e510 0x192738be4
0x1914a0ddc 0x1001dd258 0x1001dd218 0x1001eaaec 0x1001e0ce0
0x1001eb088 0x1001ece2c 0x1001ecb78 0x185dcf2a0 0x185dced8c)
libc++abi.dylib: terminating with uncaught exception of type
NSException

iOS Photos Framework: how to revert image asset to original

All the online document and samples showed how to edit/change assets with PHContentEditingInput and PHContentEditingOutput. I didn't find anything about resetting or reverting an image to its original. Anything wrote to renderedContentURL is considered an edit, so that's not what I want. Just share my findings here:
Use revertAssetContentToOriginal
Swift:
PHPhotoLibrary.shared().performChanges({
let request = PHAssetChangeRequest(for:asset)
request.revertAssetContentToOriginal()
}, completionHandler: { success, error in
if !success { print("can't revert asset: \(error)") }
})
Objective C:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *change = [PHAssetChangeRequest changeRequestForAsset:asset];
[change revertAssetContentToOriginal];
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
}];

PHPhotoLibrary: error creating collection list

I am trying to create a collection list in Photos which will have multiple albums.
The code to create the collection list is as follows:
__block NSString * localId;
NSError *createFolderError;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create the folder
PHCollectionListChangeRequest *changeRequest = [PHCollectionListChangeRequest creationRequestForCollectionListWithTitle: #"My Photos"];
localId = [[changeRequest placeholderForCreatedCollectionList] localIdentifier];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (!success) {
DebugLog(#"Creating My Photos Folder Failed... error : %#", error.description);
return;
}
if(localId) {
//Do something
}
}];
But, getting error as follows:
Error Domain=NSCocoaErrorDomain Code=-1 "(null)"
Earlier, it was creating folder even after getting the error, but now, I see folder not getting created under Photos application.
Let me know if I am doing anything wrong.
EDIT
The folder is getting created in the Photos app each time, but was not reflecting. When Photos App was killed and relaunched, I can see the folder. But still, why the error is shown, remains a question.

PhotoKit delete photos,how to change the language of title?

I'm just use the PhotoKit to delete photos, just like this:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets: arrayOfPHAssets];
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished deleting asset. %#", (success ? #"Success." : error));
}];
And the result is:delete image's info
How to change the title's language to Chinese.
I have a try to change iPhone's language and it doesn't matter.Please.

AssetsLibrary framework not working after delete album in iOS 8

I want to save all image's from my app with new album(with my app name). so I have use asserts library in my project. it is working good in ios 7 but not in ios8 and later one.With Mistake when user remove album from photos,assert library unable to create new album again with same name in ios8. Any one has solution for this? Thanks
You can try My below Method for Create Album for iOS 7 and iOS 8
#define PHOTO_ALBUM_NAME #"AlbumName Videos"
#pragma mark - Create Album
-(void)createAlbum{
// PHPhotoLibrary_class will only be non-nil on iOS 8.x.x
Class PHPhotoLibrary_class = NSClassFromString(#"PHPhotoLibrary");
if (PHPhotoLibrary_class) {
// iOS 8..x. . code that has to be called dynamically at runtime and will not link on iOS 7.x.x ...
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:PHOTO_ALBUM_NAME];
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(#"Error creating album: %#", error);
}else{
NSLog(#"Created");
}
}];
}else{
[self.library addAssetsGroupAlbumWithName:PHOTO_ALBUM_NAME resultBlock:^(ALAssetsGroup *group) {
NSLog(#"adding album:'Compressed Videos', success: %s", group.editable ? "YES" : "NO");
if (group.editable == NO) {
}
} failureBlock:^(NSError *error) {
NSLog(#"error adding album");
}];
}}

Resources