Zenn
📱

PHPickerViewController で選択した順番通りに PHAsset を取得する方法

2025/02/27に公開
1

こんにちは!アルダグラム でエンジニアをしている渡辺です。

今回は、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 }
    }
}

この関数では:

  1. PHPickerResult から assetIdentifier を抽出
  2. PHAsset.fetchAssets で一括取得
  3. identifier をキーに PHAsset を配列化
  4. PHPickerResult の順番に配列からPHAsset を再構成

この方法なら、選択した順番通りの PHAsset の配列を安全に取得できます!

🎯 まとめ

PHPickerViewController を使った写真選択では、selection = .ordered を使うことでユーザーの選択順を取得できます。ただし、PHAsset の取得時に順番が崩れるので、取得後に再ソートすることで解決します。

質問や改善点があれば、ぜひコメントやフィードバックお待ちしています! 🚀

もっとアルダグラムエンジニア組織を知りたい人、ぜひ下記の情報をチェックしてみてください!

1
アルダグラム Tech Blog

Discussion

ログインするとコメントできます