2015-07-29 1 views
9

Mon application se bloque chaque fois que j'essaie d'enregistrer une image à l'aide d'un cadre photo.Enregistrer l'image dans la photothèque à l'aide du cadre photo

-(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:]' 

Répondre

34

Tout ce que vous avez à faire est de déclencher une requête de création. Comme l'indique l'erreur, vous pouvez accéder à la demande de modification uniquement à l'intérieur du bloc performChanges.

Donc, pour enregistrer l'image que vous feriez quelque chose comme ceci:

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

Si vous avez besoin de faire quelque chose avec l'espace réservé de l'actif nouvellement créé, vous pouvez y accéder à l'intérieur du même performChanges bloc:

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

cela m'a sauvé des heures de travail! – TonyTony

+0

puis comment obtenir l'URL de cette image –

2
  1. supprimer la troisième ligne du code
  2. Vérifiez que la _mChangeRequest est la compilation variable de
  3. __block et exécuter

vous verrez que l'image dans l'application de photos

vous changerez probablement le code comme ceci ...

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

    __block PHAssetChangeRequest *_mChangeRequest = nil; 

    [[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); 
     } 
}]; 
} 
2

Dans Swift 3, je le fais pour enregistrer la vidéo dans la bibliothèque.

 if mediaType.isEqual(to: (kUTTypeMovie as NSString) as String) { 
      if let videoURL = info[UIImagePickerControllerMediaURL] as? URL { 

      PHPhotoLibrary.shared().performChanges({ 
       _ = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL) 
      }, completionHandler: { (success, error) in 
       if success { 
        print("ok") 
        let videoData = NSData(contentsOf: videoURL) 
        // use videoData here if needed... 
        if let posterImage = self.firstFrame(videoURL: videoURL) { 
         self.imageView.image = posterImage 
        } 
        picker.dismiss(animated: true) {() -> Void in 

        } 
       } 
       else { 
        print(error?.localizedDescription) 
       } 
      }) 
     } 
    } 
2

Voici un exemple de code comment vous pouvez écrire/enregistrer l'image à la bibliothèque photo à l'aide UIImageWriteToSavedPhotosAlbum fonction:

- (void)saveImage:(UIImage *)image { 
    UIImageWriteToSavedPhotosAlbum(self.image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); 
} 
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo; 
{ 
    if (!error) { 
     // saved successfully 

     PHFetchOptions *fetchOptions = [PHFetchOptions new]; 
     fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]; 
     PHAsset *asset = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions].firstObject; 
     if (asset != nil) { 
      // here you can use asset of your image 
     } 
    } else { 
     NSLog(@"save image error: %@", error); 
    } 
} 

Ne pas oublier d'ajouter à votre Info.plist une paire clé-valeur Privacy - Camera Usage Description avec description de l'utilisation.