You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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获取原始数据,再根据图片类型针对性解码:

  1. 定义支持的图片类型集合
    覆盖常用格式包括RAW、实况照片、HEIC、JPEG等,确保能匹配到用户选择的图片类型。

  2. 按类型加载数据并解码

  • 实况照片:通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:36:18