PHPickerViewController で選択した順番通りに PHAsset を取得する方法
こんにちは!アルダグラム でエンジニアをしている渡辺です。
今回は、iOS アプリ開発で写真や動画を扱う際によく使う PHPickerViewController
を使って、ユーザーが選択した順番通りに PHAsset
を取得する方法について紹介します。私自身、開発中に少しつまずいたポイントもあるので、同じ問題に直面した方の参考になれば嬉しいです!
📸 KANNA アプリのアップロード機能
私たちが開発しているアプリ KANNA では、複数の写真や動画を選択し、選択した順番通りにアップロード する機能があります。この機能を実装する際、写真選択後の順序保持が思ったよりも厄介だったので、その解決策を共有します。
🛠 PHPickerViewController の選択順序
PHPickerViewController
には、写真選択時の挙動を制御するための PHPickerConfiguration
があります。その中に Selection
という便利な Enum
があり、これを使うと選択順序を制御できます。
var configuration = PHPickerConfiguration()
configuration.selection = .ordered
この設定を使うと、選択した順番通りに PHPickerResult
の配列が返されます。
🚩 PHAsset の取得で順番が崩れる問題
ただし、PHPickerResult
から assetIdentifier
を使って PHAsset
を取得すると、問題が発生します。
let identifiers = results.compactMap { $0.assetIdentifier }
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
上記のコードでは、PHFetchResult<PHAsset>
の取得順序が選択順と一致しません。これは PHFetchResult
が順序保証されないためです。その結果、せっかく PHPickerResult
で選択順が保持されていたのに、PHAsset
を取得した段階で順序が崩れてしまいます。
✅ 解決策:PHAsset を再ソート
この問題を解決するには、PHPickerResult
の選択順と取得した PHAsset
を突き合わせて再ソートすればOKです。
func getOrderedAssets(from results: [PHPickerResult]) -> [PHAsset] {
let identifiers = results.compactMap { $0.assetIdentifier }
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
// identifier -> PHAsset の配列を作成
var assetList: [PHAsset] = []
fetchResult.enumerateObjects { asset, _, _ in
assetList.append(asset)
}
// PHPickerResult の順番に PHAsset を再構成
return identifiers.compactMap { identifier in
assetList.first { $0.localIdentifier == identifier }
}
}
この関数では:
PHPickerResult
からassetIdentifier
を抽出PHAsset.fetchAssets
で一括取得identifier
をキーにPHAsset
を配列化PHPickerResult
の順番に配列からPHAsset
を再構成
この方法なら、選択した順番通りの PHAsset
の配列を安全に取得できます!
🎯 まとめ
PHPickerViewController
を使った写真選択では、selection = .ordered
を使うことでユーザーの選択順を取得できます。ただし、PHAsset
の取得時に順番が崩れるので、取得後に再ソートすることで解決します。
質問や改善点があれば、ぜひコメントやフィードバックお待ちしています! 🚀
もっとアルダグラムエンジニア組織を知りたい人、ぜひ下記の情報をチェックしてみてください!

株式会社アルダグラムのTech Blogです。 世界中のノンデスクワーク業界における現場の生産性アップを実現する現場DXサービス「KANNA」を開発しています。 採用情報はこちら: herp.careers/v1/aldagram0508/
Discussion