🖼️
SwiftUI PhotosPicker で画像の Asset metadata を取得する
ImagePickerViewController -> PHPickerViewController -> PhotosPicker が ios16 から使用可能になり、PHPikcer 以降はユーザーにフォトライブラリへのフルアクセス or 選択した画像のみのアクセスなどのアクセス許可を得なくても、その場で選択した画像のみの情報を取得できるようになった。
ただしこの PhotosPicker を使いつつ、画像メタデータ(Exif等)を取得する方法が見当たらなかったのでメモ。
なお画像の creationDate
については PHAsset 経由でフォトライブラリにアクセスしなければならず、許可無しでの取得はできないが exif や tiff の中に大体は含まれている。
ベースは Apple 公式のデモプロジェクト2つなので、それぞれ Download ボタンからダウンロードして動かしながら試すのがおすすめ。
Base Code
PhotosPicker example:
Load Asset Metadata example:
PHPickerViewController を使った例
Get image asset (metadata)
private func loadTransferable(from imageSelection: PhotosPickerItem) -> Progress {
return imageSelection.loadTransferable(type: Data.self) { result in
DispatchQueue.main.async {
guard imageSelection == self.imageSelection else {
print("Failed to get the selected item.")
return
}
switch result {
case .success(let data):
guard let data, let uiImage = UIImage(data: data) else {
print("Error: Failed to create UIImage from data")
return
}
self.pickedImage = PickedImage(uiImage: uiImage)
guard let cgImageSource = CGImageSourceCreateWithData(data as CFData, nil),
let properties = CGImageSourceCopyPropertiesAtIndex(cgImageSource, 0, nil) else {
print("Error: Failed to load image metadata")
return
}
print(properties)
case .failure(let error):
self.imageState = .failure(error)
}
}
}
}
その他
上記のサンプルのように PHPicker で itemProvider
経由でメタデータを取ることも可能だったが、データの節約(ストレージ最適化)のために iCloud からダウンロードしてこなければならない画像は、モバイル通信やオフライン時に取得失敗してしまう。
ImagePicker だと「iCloud からダウンロード中..」のように表示が出てから pick してくれるのだが、PHPicker ではエラーハンドリングの方法すらわからなかった。
Discussion