SwiftUI中PHPicker加载public.jpeg失败,iPhone 13 Pro Max真机报错排查
解决PHPicker真机加载图片出现「Cannot load representation of type public.jpeg」错误
问题根源
实况照片(Live Photo)、RAW格式图片(如DNG)的NSItemProvider无法直接通过loadObject(ofClass: UIImage.self)完成转换——即使canLoadObject返回true,真机系统对这类封装格式的图片处理更严格,直接加载UIImage会触发格式不兼容错误。
解决方案:优先加载数据再按需解码
放弃直接加载UIImage实例,改为通过loadDataRepresentation获取原始数据,再根据图片类型针对性解码:
定义支持的图片类型集合
覆盖常用格式包括RAW、实况照片、HEIC、JPEG等,确保能匹配到用户选择的图片类型。按类型加载数据并解码
- 实况照片:通过
PHLivePhoto解析后提取静态帧 - RAW图片:用
ImageIO框架的CGImageSource解码成CGImage再转UIImage - 普通格式(JPEG/PNG/HEIC):直接用
UIImage(data:)转换
修正后的完整代码
import PhotosUI import ImageIO import Photos func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true) guard let provider = results.first?.itemProvider else { return } // 覆盖主流图片类型,包括RAW和实况照片 let supportedTypes: [UTType] = [.jpeg, .png, .heic, .rawImage, .livePhoto] // 匹配第一个支持的类型 guard let targetType = supportedTypes.first(where: { provider.hasItemConformingToTypeIdentifier($0.identifier) }) else { print("未找到支持的图片类型") return } provider.loadDataRepresentation(forTypeIdentifier: targetType.identifier) { data, error in guard let imageData = data, error == nil else { print("加载图片数据失败: \(error?.localizedDescription ?? "未知错误")") return } DispatchQueue.main.async { var resultImage: UIImage? switch targetType { case .livePhoto: // 解析实况照片并提取第一帧 if let livePhoto = try? PHLivePhoto(data: imageData, options: nil) { resultImage = livePhoto.burstRepresentation().first ?? UIImage() } case .rawImage: // 用ImageIO解码RAW图片 let options = [kCGImageSourceShouldCache: false] as CFDictionary if let imageSource = CGImageSourceCreateWithData(imageData as CFData, options), let cgImage = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { resultImage = UIImage(cgImage: cgImage) } default: // 普通格式直接转UIImage resultImage = UIImage(data: imageData) } if let image = resultImage { // 在这里使用处理好的图片 print("成功加载图片,尺寸:\(image.size)") } else { print("图片解码失败") } } } }
额外注意事项
- 处理RAW图片时,可通过
CGImageSourceCopyPropertiesAtIndex获取图片元数据,根据需求调整解码参数(比如色彩空间、压缩质量) - 实况照片的
burstRepresentation()会返回所有帧,若只需要封面图,也可以用PHLivePhotoView获取当前显示的图片 - 确保项目已导入
Photos、ImageIO框架,避免编译错误
内容的提问来源于stack exchange,提问作者kalafun
相关产品推荐
相关产品推荐

