如何从iOS Share Extension中访问图片文件?附实现代码咨询
你的实现存在几个关键问题,以下是问题分析和修正方案:
1. 共享URL解析错误
你拿到的share_url值是带file:// scheme的完整URL字符串(比如file:///var/mobile/...),但你用了URL(fileURLWithPath:)来初始化——这个方法仅适用于不带scheme的本地文件路径(比如/var/mobile/...)。正确的做法是用URL(string:)解析完整的file URL。
2. 未释放Security Scoped Resource
调用startAccessingSecurityScopedResource()获取权限后,必须在操作完成(无论成功还是失败)后调用stopAccessingSecurityScopedResource()释放权限,否则会导致系统资源泄漏。
3. 错误处理不完整
- 未处理
startAccessingSecurityScopedResource()返回false(权限获取失败)的情况 - 未处理
shareURL解析失败的情况 - 原代码中
print语句的错误字符串存在多余转义符\\
修正后的完整代码
onOpenURL 处理逻辑
.onOpenURL { url in guard url.scheme == "myURlScheme", let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let shareURLString = components.queryItems?.first(where: { $0.name == "share_url" })?.value, let shareURL = URL(string: shareURLString) else { print("无效的深度链接或共享URL") return } loadFrom(URLAdress: shareURL) }
loadFrom 函数实现
func loadFrom(URLAdress: URL) { DispatchQueue.global().async { var hasAccess = false defer { // 无论操作成功与否,都释放权限 if hasAccess { URLAdress.stopAccessingSecurityScopedResource() } } do { hasAccess = URLAdress.startAccessingSecurityScopedResource() guard hasAccess else { print("无法获取安全范围资源访问权限") return } let imageData = try Data(contentsOf: URLAdress) guard let loadedImage = UIImage(data: imageData) else { print("无法将数据转换为UIImage") return } DispatchQueue.main.async { // 在此处更新UI,例如赋值给@Published变量或直接更新视图 // self.targetImage = loadedImage } } catch { print("读取图片数据错误: \(error)") } } }
额外注意事项
- 确保主App与Share Extension配置了相同的App Group,这是跨组件共享文件权限的前提。
- 如果共享的是照片库资源,也可以考虑在Share Extension中直接读取图片数据,通过App Group容器传递数据,这种方式比传递文件URL更可靠。
内容的提问来源于stack exchange,提问作者Hridoy Chowdhury
相关产品推荐
相关产品推荐

