iOS16/macOS Ventura下SwiftUI PhotosPicker如何获取PHAsset或图片元数据?
解决方案:从PhotosPicker获取PHAsset或照片元数据
首先明确:通过图像数据哈希匹配PHAsset的方案不可行,原因包括:
- 同一图片可能存在多个PHAsset(比如编辑副本、重复导入的版本)
- PhotosPicker返回的图像可能经过压缩或格式转换,哈希值与原资产的原始数据不一致
- 遍历照片库所有资产计算哈希匹配,性能极差且效率低下
以下是两种可靠的实现方式:
方式一:获取PHAsset对象
iOS 16+的PhotosPickerItem提供了itemIdentifier属性,可通过这个本地标识符直接对应到PHAsset:
- 确保已配置照片库访问权限,在
Info.plist中添加NSPhotoLibraryUsageDescription(iOS)或NSPhotoLibraryUsageDescription/NSPhotoLibraryAddUsageDescription(macOS) - 修改代码如下:
import PhotosUI import Photos // 定义选中项的绑定 @State private var selectedPhotosPickerItems: [PhotosPickerItem] = [] var body: some View { PhotosPicker(selection: $selectedPhotosPickerItems, matching: .images) { Text("Select photos") } .onChange(of: selectedPhotosPickerItems) { newItems in // 收集所有本地标识符 let localIdentifiers = newItems.compactMap { $0.itemIdentifier } guard !localIdentifiers.isEmpty else { return } // 请求PHAsset let fetchOptions = PHFetchOptions() let assets = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: fetchOptions) assets.enumerateObjects { asset, _, _ in // 拿到PHAsset后,可获取创建日期、像素尺寸、位置等所有信息 let creationDate = asset.creationDate let pixelWidth = asset.pixelWidth // ... 处理资产数据 } } }
方式二:仅获取照片原始创建日期(无需PHAsset)
如果只需要创建日期等元数据,可直接从PhotosPickerItem加载ImageMetadata类型(该类型遵循Transferable协议):
.onChange(of: selectedPhotosPickerItems) { newItems in for newItem in newItems { Task { if let metadata = try? await newItem.loadTransferable(type: ImageMetadata.self) { // 获取原始创建日期 let creationDate = metadata.creationDate // 还可获取其他元数据,比如相机型号、光圈等 let cameraModel = metadata.exif?[.cameraModel] // ... 处理元数据 } } } }
注意事项
- 使用PHAsset时,需确保用户已授予照片库读取权限,否则
fetchAssets会返回空结果 ImageMetadata包含的元数据取决于照片本身是否携带完整EXIF信息,部分第三方应用拍摄的照片可能缺失部分字段
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

