You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨ViewController解压Zip文件遇Zip.ZipError error 1问题求助

问题分析与解决方案

从你的情况来看,最关键的线索是同一个zip文件在下载完成后立刻解压没问题,但切换到另一个ViewController再解压就报错,而且你已经确认了文件存在、大小正常、权限也没问题,那大概率是这几个原因:

1. 异步下载没真正完成就去解压了

你的下载是异步执行的对吧?当你切换到ViewControllerB的时候,可能你以为文件已经下载完了,但实际上Downloader.load的异步任务还在后台写文件,或者completion回调还没跑完——这时候文件虽然已经出现在documents目录,大小看起来也对,但其实还没完全写入磁盘,Zip框架读的时候就会认为这是个无效的压缩包,也就是你看到的Zip.ZipError error 1(这个错误码通常就是指无效zip文件)。

而在同一个ViewController里,你是在下载的completion回调里执行解压,这时候系统已经保证文件完全写完了,所以一切正常。

怎么解决?

核心就是确保只有下载彻底完成后,ViewControllerB才去解压,可以试试这些方法:

  • 用通知:在下载完成的completion里发个通知,ViewControllerB提前监听这个通知,收到通知再执行解压逻辑。
  • 传闭包:如果是从ViewControllerA跳转到B,跳转的时候给B传个闭包,下载完成后调用这个闭包通知B解压。
  • 状态管理:搞个单例类记录下载状态,B在viewDidAppear里检查状态,确认下载完成再动手解压。

2. 文件被占用了(下载后没释放句柄)

还有个小概率情况:你的Downloader下载完成后,没正确关闭文件写入的句柄,导致文件被系统锁住了,这时候Zip框架读不了文件,就会报错。

怎么排查?

去检查Downloader.load的实现,比如如果用了FileHandle写文件,要确保写完后调用了closeFile();如果用了其他写入方式,也要确认写入流已经正确关闭。

3. 额外确认:两个VC的文件路径是不是完全一样?

虽然你的代码看起来一样,但保险起见,可以在两个VC里都打印一下destinationFileUrl的绝对路径,看看是不是指向同一个文件:

print("当前文件路径:\(destinationFileUrl.path)")

要是路径不一样(虽然这种情况极少,但万一呢),也会导致找不到有效文件。

验证代码示例

在ViewControllerA的下载完成回调里加打印:

Downloader.load(url: remoteURL, to: destinationFileUrl, completion: {
    print("下载完成,文件路径:\(destinationFileUrl.path)")
})

在ViewControllerB的解压前加打印:

let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .allDomainsMask).first!
let destinationFileUrl = documentsUrl.appendingPathComponent("zipFile.zip")
print("准备解压,文件路径:\(destinationFileUrl.path)")
do {
    let file = try Zip.quickUnzipFile(destinationFileUrl)
} catch {
    print("Error: \(error.localizedDescription)")
}

要是两个路径完全一致,就可以排除这个问题了。


内容的提问来源于stack exchange,提问作者Usama Aftab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:54:20