【问题标题】:Save image to photo library using photo framework使用照片框架将图像保存到照片库
【发布时间】:2015-10-20 00:23:40
【问题描述】:

每次我尝试使用照片框架保存图像时,我的应用都会崩溃。

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

【问题讨论】:

    标签: ios objective-c ios8 photokit phasset


    【解决方案1】:
    1. 删除第三行代码
    2. 验证 _mChangeRequest 是 __block 变量
    3. 编译运行

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

    您可能会像这样更改代码...

    - (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info {
        __block PHAssetChangeRequest *_mChangeRequest = nil;
        [[PHPhotoLibrary sharedPhotoLibrary]
                performChanges:^{
                    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
                    _mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
                }, completionHandler :^(BOOL success, NSError *error) {
            if (success) {
                PHObjectPlaceholder *assetPlaceholder = _mChangeRequest.placeholderForCreatedAsset;
            } else {
                NSLog(@"write error : %@", error);
            }
        }];
    }
    

    【讨论】:

      【解决方案2】:

      在 Swift 3 中,我这样做是为了将视频保存到库中。

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

      【讨论】:

      • 哇,谢谢!这种语法对我来说太奇怪了。为什么需要in 关键字?还有功能块内部定义的参数。
      【解决方案3】:

      以下是如何使用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 以及使用说明。

      【讨论】:

      • UIImageWriteToSavedPhotosAlbum 不是 PhotoKit 的一部分...
      【解决方案4】:

      您需要做的就是触发创建请求。正如错误所说,您只能在 performChanges 块内访问更改请求。

      因此,要保存图像,您可以执行以下操作:

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

      如果您需要对新创建资产的占位符进行操作,您可以在同一 performChanges 块内访问它:

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

      【讨论】:

      • 然后如何获取该图片的url
      猜你喜欢
      • 1970-01-01
      • 2014-11-28
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 2018-10-03
      相关资源
      最近更新 更多