我从服务器下载一些文件。下载完成后,我应该解压缩它们,然后我显示本地推送通知以显示结果。为了不阻止UI,我添加了观察器以显示没有活动指示器的自定义进度行,并根据状态更新此行。
我希望给用户一个机会,让这一切都在后台进行。
对于下载,我使用 bg 配置创建 URLSession,如下所示:
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)
}()
并且所有下载都可以正常工作。但是我的解包函数仍然只能在前台工作。如何在后台使用它?
对于开箱,我使用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)
}
}
如果您正在执行一些可能会消耗时间的操作并且您不想杀死它,那么您可以通过在 UIBackground 任务中执行来延长操作时间
{
UIBackgroundTaskIdentifier taskId = 0;
taskId = [application beginBackgroundTaskWithExpirationHandler:^{
taskId = UIBackgroundTaskInvalid;
}];
// Execute long process. This process will have 10 mins even if your app goes in background mode.
}
名为"handler"的块参数是后台任务过期(10分钟(时将发生的情况。这是文档的链接