PHPickerResult#assetIdentifierがnilになる

iOS 14から使えるようになったPHPickerViewControllerを使うと撮影した写真や動画を選択するUIを提供してくれて便利です!・・・なのですがPHPickerResult#assetIdentifierがnilになるせいで、PHAsset#fetchAssetsで詳細情報を取れずハマりました😫

理由はPHPickerConfigurationにphotoLibraryを指定しなかったことが原因でした。

let photoLibrary = PHPhotoLibrary.shared()
var config = PHPickerConfiguration(photoLibrary: photoLibrary)
// これが駄目!photoLibraryを渡さないと駄目!
// var config = PHPickerConfiguration()
config.filter = .videos
config.selectionLimit = 1
config.preferredAssetRepresentationMode = .current
phPicker = PHPickerViewController(configuration: config)

こうすると、PHPickerViewControllerDelegateのdidFinishPickingで受け取るPHPickerResultにassetIdentifierが入ってきます。これをPHAsset#fetchAssetsに渡すと画像のサイズや動画の再生時間を取得できます。ただし、ユーザーに読み取り許可を取っていない場合はPHAsset#fetchAssets呼び出し時にアラートが表示されます。この時fetchAssetsはユーザーのアラートの操作を待たずして戻り値を返し、それのfirstObjectはnilになるようなので注意です。

func picker(_ picker: PHPickerViewController, 
            didFinishPicking results: [PHPickerResult]) {
    guard let result = results.first else { return }
    if let assetId = result.assetIdentifier,
       let asset = PHAsset.fetchAssets(
              withLocalIdentifiers: [assetId], options: nil).firstObject {
        print("size \(asset.pixelWidth)x\(asset.pixelHeight)")
        print("duration \(asset.duration)")           
    }