Я делаю скачивание некоторых файлов с сервера. После завершения загрузки я должен распаковать их, и после этого я показываю локальное уведомление pu sh о результатах шоу. Чтобы не блокировать пользовательский интерфейс, я добавил наблюдателей для показа пользовательской строки прогресса без индикатора активности, и обновление этой строки зависит от состояния.
Я хочу дать пользователю возможность сделать все это в фоновом режиме.
Для загрузка Я создаю URLSession с конфигурацией bg следующим образом:
private lazy var urlSession: URLSession = {
let config = URLSessionConfiguration.background(withIdentifier: "MySession")
config.isDiscretionary = true
config.sessionSendsLaunchEvents = true
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
И все отлично работает для загрузки. Но моя распаковка веселья c по-прежнему работает только на переднем плане. Как я могу использовать это в фоновом режиме?
Для распаковки я использую lib ZIPFoundation. И код ниже:
public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
downloadService.update(state: .unpacking, for: downloadTask)
do {
let documentsDir = try self.fileManager.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false
)
let newLocation = documentsDir.appendingPathComponent(location.lastPathComponent)
try fileManager.moveItem(at: location, to: newLocation)
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else { return }
do {
let path = try self.fileManager.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false
)
.appendingPathComponent("store")
try self.fileManager.unzipItem(at: newLocation, to: path, progress: downloadTask.progress)
try self.fileManager.removeItem(at: newLocation)
DispatchQueue.main.async {
self.notificationCenter.add(.languageIsDownloaded)
self.downloadService.update(state: .finished, for: downloadTask)
}
} catch {
DispatchQueue.main.async {
self.errorHandler.handle(error)
self.downloadService.update(state: .failed, for: downloadTask)
}
}
}
} catch {
errorHandler.handle(error)
downloadService.update(state: .failed, for: downloadTask)
}
}