iosobjective-cios8photokitphasset

Save image to photo library using photo framework


My app crashes every time when I try to save image using photo framework.

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

      _mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];

      [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{

      _mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];

      } completionHandler:^(BOOL success, NSError *error) {

          if (success) {

              PHObjectPlaceholder *assetPlaceholder = _mChangeRequest.placeholderForCreatedAsset;
          }
          else {

             NSLog(@"write error : %@",error);
          }
    }];
}

crash : NSInternalInconsistencyException', reason: 'This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]'

Solution

  • All you need to do is trigger a creation request. As the error says, you can access the change request only inside the performChanges block.

    So to save the image you would do something like this:

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
    } completionHandler:^(BOOL success, NSError *error) {
        if (success) {
             NSLog(@"Success");
        }
        else {
            NSLog(@"write error : %@",error);
        }
    }];
    

    In case you need to do something with the placeholder of the newly created asset, you can access it inside the same performChanges block:

    PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
    PHObjectPlaceholder *assetPlaceholder = changeRequest.placeholderForCreatedAsset;