使用照片框架将图像保存到照片库
每当我尝试使用照片框架保存图像时,我的应用程序崩溃。
-(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;
- 删除第三行的代码
- validation_mChangeRequest是__blockvariables
- 编译并运行
您将在照片应用程序中看到该图像
你会改变代码可能是这样的…
-(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 Description
与Privacy - Camera Usage Description
。