2015-07-29 28 views
9

Ứng dụng của tôi gặp sự cố mỗi khi tôi cố lưu hình ảnh bằng khung ảnh.Lưu hình ảnh vào thư viện ảnh bằng khung ảnh

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

Trả lời

34

Tất cả những gì bạn cần làm là kích hoạt yêu cầu tạo. Khi lỗi nói, bạn chỉ có thể truy cập yêu cầu thay đổi bên trong khối performChanges.

Vì vậy, để lưu hình ảnh bạn sẽ làm một cái gì đó như thế này:

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

Trong trường hợp bạn cần phải làm điều gì đó với placeholder của tài sản mới được tạo ra, bạn có thể truy cập nó bên trong cùng performChanges khối:

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

số giờ làm việc đã lưu này! – TonyTony

+0

và sau đó là cách lấy url của hình ảnh đó –

2
  1. xóa dòng thứ ba của mã
  2. Xác minh rằng các _mChangeRequest là __block biến
  3. biên dịch và chạy

bạn sẽ thấy hình ảnh đó trong ứng dụng ảnh

bạn sẽ thay đổi mã có thể như thế này ...

-(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

Trong Swift 3 Tôi thực hiện việc này để lưu video vào thư viện.

 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

Dưới đây là một ví dụ về mã như thế nào bạn có thể viết/lưu hình ảnh vào Thư viện ảnh sử dụng UIImageWriteToSavedPhotosAlbum chức năng:

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

Đừng quên thêm vào Info.plist bạn một cặp khóa-giá trị Privacy - Camera Usage Description với mô tả về cách sử dụng.

Các vấn đề liên quan