使用照片框架将图像保存到照片库

每当我尝试使用照片框架保存图像时,我的应用程序崩溃。

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

所有你需要做的是触发一个创build请求。 如错误所述,只能在performChanges块内访问更改请求。

所以要保存图像,你应该这样做:

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

如果您需要使用新创build资源的占位符执行某些操作,则可以在同一个performChanges块中对其进行访问:

 PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]]; PHObjectPlaceholder *assetPlaceholder = changeRequest.placeholderForCreatedAsset; 
  1. 删除第三行的代码
  2. validation_mChangeRequest是__blockvariables
  3. 编译并运行

您将在照片应用程序中看到该图像

你会改变代码可能是这样的…

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

在Swift 3中,我这样做是为了将video保存到图书馆。

  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) } }) } } 

下面是一个代码示例,您可以使用UIImageWriteToSavedPhotosAlbum函数将图像写入/保存到照片库:

 - (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); } } 

不要忘记添加到您的Info.plist键值对Privacy - Camera Usage DescriptionPrivacy - Camera Usage Description