我下载了一个文件并想要解压缩它。我的代码工作正常。但有一个问题。我接到
didFinishDownloadingTo
的电话后立即开始解压文件。这是正确的行为吗?在开始解压之前我需要做任何额外的检查吗?例如,该文件是否存在于目录中?或者已经准备好解压了吗?是否有可能下载成功后解压前出现无法解压文件的问题?
视图控制器:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let url = URL(string: "0.zip")!
let downloadManager = DownloadManager()
downloadManager.identifier = indexPath.row+1
downloadManager.collectionId = 0
downloadManager.folderPath = "\(indexPath.row+1)"
let downloadTaskLocal = downloadManager.activate().downloadTask(with: url)
downloadTaskLocal.resume()
downloadManager.onSuccess = { [weak self] row in
guard let self = self else { return }
DispatchQueue.main.async {
self.items[row - 1].state = .completed
self.reloadItem(indexPath: .init(row: row - 1, section: 0))
if self.items[row - 1].state == .completed {
var zip = []
zip.append(row - 1)
}
if fileManager.fileExists(atPath: destination.path){
let sourceURL = URL(fileURLWithPath: "\(destination.path)/1.zip")
let destinationURL = URL(fileURLWithPath: destination.path)
let unzipProgress = Progress()
let observation = unzipProgress.observe(\.fractionCompleted) { progress, _ in
print("Extraction progress: ", progress.fractionCompleted)
if progress.fractionCompleted == 1.0 {
self.items[row - 1].state = .unzipped
self.reloadItem(indexPath: .init(row: row - 1, section: 0))
}
}
do { try fileManager.unzipItem(at: sourceURL, to: destinationURL, progress: unzipProgress) }
catch { print("error") }
observation.invalidate()
} else { print("error") }
}
}
}
下载管理器:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){
let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String)
let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String)
if let idx = downloadQueue[someNumb!]?.index(of: some1!) {
downloadQueue[someNumb!]?.remove(at: idx)
print("remove:\(downloadQueue)")
}
let fileName = downloadTask.originalRequest?.url?.lastPathComponent
let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentDirectoryPath:String = path[0]
let fileManager = FileManager()
var destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appending("/\(folderPath)"))
do {
try fileManager.createDirectory(at: destinationURLForFile, withIntermediateDirectories: true, attributes: nil)
destinationURLForFile.appendPathComponent(String(describing: fileName!))
try fileManager.moveItem(at: location, to: destinationURLForFile)
onSuccess?(identifier)
} catch (let error) {
print(error)
}
}
根据@HangarRash 的建议,我添加了以下更改:
DispatchQueue.global().async {
do { try fileManager.unzipItem(at: sourceURL, to: destinationURL, progress: unzipProgress) }
catch { print("error") }
}
完整代码:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let url = URL(string: "1.zip")!
let downloadManager = DownloadManager()
downloadManager.identifier = indexPath.row+1
downloadManager.collectionId = 0
downloadManager.folderPath = "\(indexPath.row+1)"
let downloadTaskLocal = downloadManager.activate().downloadTask(with: url)
downloadTaskLocal.resume()
downloadManager.onSuccess = { [weak self] row in
guard let self = self else { return }
DispatchQueue.main.async {
self.items[row - 1].state = .completed
self.reloadItem(indexPath: .init(row: row - 1, section: 0))
if fileManager.fileExists(atPath: destination.path){
let sourceURL = URL(fileURLWithPath: "\(destination.path)/1.zip")
let destinationURL = URL(fileURLWithPath: destination.path)
let unzipProgress = Progress()
let observation = unzipProgress.observe(\.fractionCompleted) { progress, _ in
print("Extraction progress: ", progress.fractionCompleted)
if progress.fractionCompleted == 1.0 {
self.items[row - 1].state = .unzipped
self.reloadItem(indexPath: .init(row: row - 1, section: 0))
}
}
DispatchQueue.global().async {
do { try fileManager.unzipItem(at: sourceURL, to: destinationURL, progress: unzipProgress) }
catch { print("error") }
}
observation.invalidate()
} else { print("error") }
}
}
}