如何在非控制器类中用ZIPFoundation跟踪并打印解压进度
解决ZIPFoundation解压进度跟踪问题(非控制器类)
要在非控制器类里用Foundation的Progress跟踪ZIPFoundation的解压进度,核心是正确初始化Progress实例并通过KVO监听进度变化,以下是修改后的完整实现:
关键步骤说明
- 初始化Progress实例:不能传
nil,需要创建Progress对象传入unzipItem方法,ZIPFoundation会自动更新该对象的进度数据 - 添加KVO监听:监听
Progress的fractionCompleted属性,该属性会随解压进度实时更新 - 处理进度回调:在KVO回调方法中计算进度百分比并打印
- 清理监听:在类销毁时移除KVO监听,避免内存泄漏
修改后的完整代码
import Foundation import ZIPFoundation class MyClass: NSObject { private var unzipProgress: Progress? func unzipFile(from: URL, to: URL) -> Bool { let fileManager = FileManager() print("Unzipping...") do { // 初始化Progress实例 unzipProgress = Progress(totalUnitCount: 0) // 给fractionCompleted属性添加KVO监听 unzipProgress?.addObserver(self, forKeyPath: #keyPath(Progress.fractionCompleted), options: [.new], context: nil) try fileManager.unzipItem(at: from, to: to, progress: unzipProgress) print("Extraction success from \(from.path) to \(to.path)") } catch { print("Extraction of ZIP archive failed with error:\(error)") return false } return true } // KVO回调方法,处理进度更新 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == #keyPath(Progress.fractionCompleted), let progress = object as? Progress, let newFraction = change?[.newKey] as? Double else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } // 计算百分比并打印到控制台 let percentage = Int(newFraction * 100) print("Unzip progress: \(percentage)%") } // 类销毁时移除KVO监听 deinit { unzipProgress?.removeObserver(self, forKeyPath: #keyPath(Progress.fractionCompleted)) } }
补充说明
- 类必须继承
NSObject才能使用KVO机制 Progress的totalUnitCount会由ZIPFoundation自动根据压缩包内容设置,无需手动赋值- 如果需要在解压完成后立即停止监听,也可以在解压成功的代码块里主动调用
removeObserver方法
内容的提问来源于stack exchange,提问作者AleXiuS
相关产品推荐
相关产品推荐

