如何通过自定义Transferable类型从PhotosPickerItem加载LivePhoto
问题分析与解决
问题原因
你自定义的LivephotoTrasferable仅实现了FileRepresentation,该表示仅适配文件拖拽场景;而PhotosPickerItem提供LivePhoto时,系统默认通过内置逻辑将其转换为PHLivePhoto实例,而非直接暴露文件URL,因此无法匹配到你的FileRepresentation导入逻辑,导致加载失败。
解决方案
给LivephotoTrasferable添加ItemProviderRepresentation,利用系统NSItemProvider能力直接加载LivePhoto对应的文件URL,同时保留原有的FileRepresentation用于拖拽场景,实现统一管理导入、导出及拖拽逻辑的需求。
修改后的完整代码
struct ContentView: View { @State private var selection: PhotosPickerItem? var body: some View { VStack { PhotosPicker(selection: $selection) { Text("Import image") } .buttonStyle(.borderedProminent) .onChange(of: selection) { oldValue, newValue in if let item = newValue { loadTransferable(item) selection = nil } } } .padding() } func loadTransferable(_ item: PhotosPickerItem) { Task { let livephoto = try? await item.loadTransferable(type: PHLivePhoto.self) let livephoto2 = try? await item.loadTransferable(type: LivephotoTrasferable.self) print(livephoto != nil, livephoto2 != nil) // 现在输出 true, true } } } struct LivephotoTrasferable: Transferable { static var transferRepresentation: some TransferRepresentation { // 适配PhotosPicker加载:从ItemProvider获取LivePhoto的文件URL ItemProviderRepresentation { itemProvider in guard itemProvider.hasItemConformingToTypeIdentifier(UTType.livePhoto.identifier) else { throw TransferError.unsupportedType } let fileURL = try await itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.livePhoto.identifier) { tempURL, error in if let error = error { throw error } return tempURL } return Self(url: fileURL) } // 保留原逻辑:处理拖拽场景的文件导入导出 FileRepresentation(contentType: .livePhoto) { item in SentTransferredFile(item.url) } importing: { file in print("livephoto!") return Self.init(url: file.file) } } var url: URL enum TransferError: Error { case unsupportedType } }
补充说明
ItemProviderRepresentation直接与系统NSItemProvider交互,能够处理PhotosPickerItem提供的LivePhoto资源,通过loadFileRepresentation获取到LivePhoto对应的包文件URL。- 原有的
FileRepresentation依然可以处理拖拽场景下的文件逻辑,完全满足你统一管理的需求。 - 修改后测试,
livephoto2将不再为nil,打印结果会变为true, true。
内容的提问来源于stack exchange,提问作者Chocoford
相关产品推荐
相关产品推荐

