13

写真フレームワークを使用して画像を保存しようとすると、毎回アプリがクラッシュします。

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

4 に答える 4

42

作成リクエストをトリガーするだけです。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;
于 2015-07-29T07:36:43.710 に答える
4

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)
            }
        })
    }
}
于 2016-11-01T11:25:07.027 に答える
2
  1. コードの 3 行目を削除する
  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);
        }
    }];
}
于 2015-07-29T07:25:54.113 に答える