Swift中将NSUrl转为本地路径URL的问题解决(Electron分享扩展)
解决Swift分享扩展中获取本地文件URL并写入共享容器的问题
核心错误原因
你遇到的Value of type 'NSSecureCoding' has no member 'path'错误,是因为loadItem回调的第一个参数类型是NSSecureCoding?,不是直接的URL/NSURL,必须先做向下类型转换才能访问path属性。
另外原代码还有隐性问题:loadItem是异步方法,你在循环后直接写入文件时,异步回调还没执行,urlsString会是空的,根本写不进内容。
修正后的完整代码
override func didSelectPost() { let inputItem = self.extensionContext!.inputItems[0] as! NSExtensionItem guard let attachments = inputItem.attachments else { self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) return } var urlsString = "" let dispatchGroup = DispatchGroup() // 用调度组处理异步任务 for attachment in attachments { if attachment.hasItemConformingToTypeIdentifier("public.file-url") { dispatchGroup.enter() // 进入组 attachment.loadItem(forTypeIdentifier: "public.file-url", options: nil) { (item, error) in defer { dispatchGroup.leave() } // 离开组,不管成功失败 guard let url = item as? URL, error == nil else { print("加载URL失败:\(error?.localizedDescription ?? "未知错误")") return } // 获取本地路径并拼接到字符串,可根据需求调整格式 urlsString += "\(url.path)\n" } } } // 等待所有异步任务完成后写入文件 dispatchGroup.notify(queue: .main) { let fileManager = FileManager.default guard let groupContainerURL = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "share.group") else { print("无法访问应用组容器") self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) return } let fileURL = groupContainerURL.appendingPathComponent("sharedUrls.txt") do { try urlsString.write(to: fileURL, atomically: true, encoding: .utf8) print("文件写入成功") } catch { print("写入文件错误:\(error)") } self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } }
关键修正点
- 类型转换:将回调中的
item向下转型为URL(Swift中URL和NSURL是桥接类型,直接用URL即可),之后就能正常访问path属性。 - 异步处理:使用
DispatchGroup跟踪所有异步加载任务,确保所有URL加载完成后再执行文件写入操作,避免写入空内容。 - 安全解包:添加
guard语句处理可选值和错误情况,避免强制解包导致崩溃。 - 调用时机:将
completeRequest放在dispatchGroup.notify的闭包内,确保所有操作完成后再结束扩展。
内容的提问来源于stack exchange,提问作者guli5057
相关产品推荐
相关产品推荐

