iOS14では UIImagePickerController
の代わりに PHPickerViewController
を使うことで複数の画像を選択することができます。
複数選択した画像を全部UIImageにして取得したくて、以下のようなコードを書きました。
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { var images = [UIImage]() let semaphoe = DispatchSemaphore(value: 0) results.forEach { item in item.itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in if let img = object as? UIImage { images.append(img) } semaphoe.signal() } } semaphoe.wait() self.handler?(picker, images) }
これだと、以下のようなエラーが出て一部の画像が読み込めない場合があります。
[default] [ERROR] Could not create a bookmark: NSError: Cocoa 257 "ファイルを表示するためのアクセス権がないため、開けませんでした。" }
どうやら loadObject()
を複数同時に呼んではいけないようです。以下のように逐次処理にするとエラーなく読み込むことができます。
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { var images = [UIImage]() results.forEach { item in let semaphoe = DispatchSemaphore(value: 0) item.itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in if let img = object as? UIImage { images.append(img) } semaphoe.signal() } semaphoe.wait() } self.handler?(picker, images) }
これだとメインスレッドをブロックしてしまうので、別スレッドにしてプログレス等を表示してもよいかもしれません。