如何跳过iOS Share Extension准备步骤获取原始大媒体文件?
可以跳过系统的压缩准备步骤,直接获取原始大文件,核心是利用NSItemProvider的loadFileRepresentation(forTypeIdentifier:)方法,替代会触发压缩的默认方法。
实现步骤
- 遍历扩展上下文的
inputItems,提取每个NSExtensionItem的附件数组 - 针对每个
NSItemProvider,先判断其支持的UTI类型(需导入MobileCoreServices框架,图片对应kUTTypeImage,视频对应kUTTypeMovie) - 调用
loadFileRepresentation方法,该方法会直接返回原始文件的临时URL,不会触发系统压缩和准备弹窗 - 在回调中处理获取到的文件URL,建议尽快将文件复制到扩展沙盒或通过App Group共享到主App(临时URL会被系统自动清理)
示例代码
import MobileCoreServices override func viewDidLoad() { super.viewDidLoad() guard let inputItems = extensionContext?.inputItems as? [NSExtensionItem] else { return } for item in inputItems { guard let attachments = item.attachments else { continue } for provider in attachments { // 处理图片 if provider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { provider.loadFileRepresentation(forTypeIdentifier: kUTTypeImage as String) { fileURL, error in guard let fileURL = fileURL else { // 处理错误逻辑 return } // 复制到沙盒保存 self.saveOriginalFile(toSandbox: fileURL) } } // 处理视频 else if provider.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { provider.loadFileRepresentation(forTypeIdentifier: kUTTypeMovie as String) { fileURL, error in guard let fileURL = fileURL else { // 处理错误逻辑 return } // 复制到沙盒保存 self.saveOriginalFile(toSandbox: fileURL) } } } } } private func saveOriginalFile(toSandbox fileURL: URL) { let sandboxDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let destURL = sandboxDir.appendingPathComponent(fileURL.lastPathComponent) do { if FileManager.default.fileExists(atPath: destURL.path) { try FileManager.default.removeItem(at: destURL) } try FileManager.default.copyItem(at: fileURL, to: destURL) // 后续业务逻辑处理 } catch { // 处理复制错误 } }
注意事项
- 需在Share Extension的
Info.plist中配置支持的UTI类型,在NSExtension->NSExtensionAttributes->NSExtensionActivationRule里声明对应媒体类型,否则无法获取附件 - 处理大文件时避免一次性读取整个文件到内存,建议采用流操作或直接基于文件URL处理,防止内存溢出
内容的提问来源于stack exchange,提问作者Sajjad
相关产品推荐
相关产品推荐

