使用URLSession下载文件出现CFNetworkDownload临时文件无法打开的问题求助
嘿,我来帮你理清这个问题:
关于
CFNetworkDownload_xxx.tmp文件的说明 这个带CFNetworkDownload_前缀的.tmp文件是URLSession下载任务默认生成的临时存储文件。当URLSession完成下载后,它会先把下载内容存到系统缓存目录的临时文件里,这就是你看到的这个文件。它是临时文件,系统不会长期保留,而且因为没有匹配的文件扩展名(比如你的PDF应该带.pdf后缀),UIDocumentInteractionController识别不出它的文件类型,自然无法打开。
解决步骤
1. 下载完成后迁移临时文件到指定目录并赋予正确扩展名
你目前的代码尝试复制文件到Documents目录,但存在变量名错误、控制器实例化错误等问题,修改后的完整流程如下:
首先修正下载完成的回调逻辑:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { debugPrint("Download finished: \(location)") debugPrint("download task : \(downloadTask)") // 调用文件处理方法,注意不要直接new一个ViewController,要用当前控制器实例 self.processDownloadedFile(from: location) } // 新增文件处理方法 private func processDownloadedFile(from tempURL: URL) { // 获取应用的Documents目录路径 guard let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { print("无法获取Documents目录") return } // 目标文件路径:指定正确的文件名和扩展名 let targetFilename = "swift.pdf" let targetURL = docDir.appendingPathComponent(targetFilename) // 先删除已存在的同名文件,避免复制失败 if FileManager.default.fileExists(atPath: targetURL.path) { do { try FileManager.default.removeItem(at: targetURL) } catch { print("删除旧文件失败:\(error.localizedDescription)") return } } // 复制临时文件到目标路径 do { try FileManager.default.copyItem(at: tempURL, to: targetURL) print("文件已保存至:\(targetURL)") // 用正确的URL打开文件 self.openFile(with: targetURL) } catch { print("复制文件失败:\(error.localizedDescription)") } } // 打开文件的方法 private func openFile(with fileURL: URL) { let docController = UIDocumentInteractionController(url: fileURL) docController.delegate = self // 必须设置代理,否则菜单可能无法正常弹出 if !docController.presentOpenInMenu(from: openButton.bounds, in: view, animated: true) { print("你没有安装可以处理PDF文件的应用。") } }
2. 关键注意事项
- 不要直接实例化ViewController:你原来代码里用
ViewController().documentInteraction(...)会创建一个全新的控制器实例,而不是当前显示的那个,导致按钮、视图等元素不存在,弹出菜单必然失败。一定要在当前控制器内处理逻辑。 - 设置UIDocumentInteractionController代理:让你的控制器遵守
UIDocumentInteractionControllerDelegate协议,并实现必要的代理方法(比如返回当前控制器作为预览容器):
class YourViewController: UIViewController, UIDocumentInteractionControllerDelegate { // ... 你的其他代码 ... func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { return self } }
- 检查变量拼写:你原来的代码里
locat是拼写错误,应该是location,这类小错误会导致文件复制失败。
3. 原方法失效的核心原因
你直接用临时文件的URL去打开,而这个文件:
- 存放在系统缓存目录,权限受限,应用后续访问可能被拒绝;
- 没有正确的文件扩展名,系统无法识别文件类型,
UIDocumentInteractionController不知道该调用什么应用打开; - 临时文件会被系统自动清理,后续再访问就会找不到。
内容的提问来源于stack exchange,提问作者Visal Sambo
相关产品推荐
相关产品推荐

