CatHand Blog

アプリ開発やMac弄り

PHPickerViewControllerで複数選択した場合のエラー

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

これだとメインスレッドをブロックしてしまうので、別スレッドにしてプログレス等を表示してもよいかもしれません。