はじめに
UIImagePickerController
のカメラで撮影してすぐに UIImageWriteToSavedPhotosAlbum(_:_:_:_:)
で保存して PHAsset
を取得したいなって思ってやってみたときの失敗談です.
結論から書くと, UIImagePickerControllerDelegate
の imagePickerController(_:didFinishPickingMediaWithInfo:)
の info の中身をみたり UIImageWriteToSavedPhotosAlbum(_:_:_:_:)
などで引数に渡ってくる値からは PHAsset
を取得することが無理なのではないかと思います.
実際に取得する
Info.plist
に Privacy - Photo Library Additions Usage Description の設定が必要です
final class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let controller = UIImagePickerController() controller.sourceType = .camera controller.allowsEditing = false controller.delegate = self present(controller, animated: true) } } extension ViewController: UIImagePickerControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { defer { picker.dismiss(animated: true) } guard let image = info[.originalImage] as? UIImage else { return } // ここから書いていく } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {} } extension ViewController: UINavigationControllerDelegate {}
とりあえずこんな感じのコードを用意しました.
実際に画像を保存する処理は PhotoKit を扱うことになります.
import Photos ・・・ extension ViewController: UIImagePickerControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { defer { picker.dismiss(animated: true) } guard let image = info[.originalImage] as? UIImage else { return } // ここから書いていく do { var localIdentifier: String? try PHPhotoLibrary.shared().performChangesAndWait { let changeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) localIdentifier = changeRequest.placeholderForCreatedAsset?.localIdentifier } guard let identifier = localIdentifier, let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else { fatalError("取得に失敗しました") return } print(asset) } catch { fatalError(error.localizedDescription) } } }
というような感じになりました.
できるんじゃね?ってやったこと
PHAsset
に含まれる localIdentifier
さえ取得できれば PHAsset
のクラスメソッドである fetchAssets(withLocalIdentifiers:options:)
を呼び出せば取得できると思いました.
一応それっぽい値は imagePickerController(_:didFinishPickingMediaWithInfo:)
の引数 info
から発見できたものの保存のライフサイクルと上記で示したクラスメソッドの実行をタイミング合わせないといけないのでちょっと面倒だなって思って検証自体をやめた.
そもそも辞書に絶対同じ値が入ってくるのは信用できないのでやめました.
最後に
今回は, UIImagePickerController
で取得した画像を PhotoKit を使ってフォトライブラリに保存して PHAsset
を取得するサンプルでしたが,実際には UIImage
であればなんでも同じようなことができます.
雑な記事になりましたが以上です.