问题描述
我正在使用一个iOS应用程序,该应用程序需要从服务器下载多个文件(主要是图像)并将其存储在Document Directory中。 我正在将UrlSessionDownloadTask与后台URLSession一起使用Urls下载文件。 当应用程序处于前台时,它工作正常,但是如果我转到后台,又回到前台,则应用程序冻结并在一段时间后崩溃。我尝试了很多事情,但没有任何效果。
func downloadAllImages(retryCount: Int = 0,completion: @escaping((Bool)->Void)){
var success: Bool = true
var count = 0
print("Image Downloading Start")
//SVProgressHUD.setStatus("Downloading Images...")
//CommonClass.showBanner(message: "Image Downloading Start")
for (localName,severPath) in images {
if DataManager.isInternetAvailable(){
self.dispatchGroup.enter()
self.dispatchGroupEnterCount += 1
let path = severPath
count += 1
self.DownloadFile(urlPath: path,localName: localName,itemCount: count)
}else {
success = false
CommonClass.showBanner(message: "No Internet")
}
}
dispatchGroup.notify(queue: .main) {
//retry If some Images Failed to download
completion(success)
}
}
func DownloadFile(urlPath: String,localName: String,itemCount: Int){
guard let url = URL(string: urlPath) else {
dispatchQueue.main.sync {
self.leavedispatchGroup()
}
return
}
let urlRequest = URLRequest(url: url,cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,timeoutInterval: 300)
let downloadTask = session.downloadTask(with: urlRequest)
self.localNameDict[downloadTask.taskIdentifier] = localName
taskArray.append(downloadTask)
downloadTask.resume()
}
}
extension DataManager: URLSessionDownloadDelegate {
func urlSession(_ session: URLSession,downloadTask: URLSessionDownloadTask,didFinishDownloadingTo location: URL) {
do {
let filemanager = FileManager()
let documentsURL = filemanager.urls(for: .documentDirectory,in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(self.localNameDict[downloadTask.taskIdentifier] ?? "img.jpeg")
if filemanager.fileExists(atPath: fileURL.path){
try? filemanager.removeItem(at: fileURL)
}
try filemanager.copyItem(at: location,to: fileURL)
}catch(let error) {
print("ERROR In Storing: \(error.localizedDescription)")
}
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
dispatchQueue.main.async {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,let completionHandler = appDelegate.bgSessionCompletionHandler else {
return
}
appDelegate.bgSessionCompletionHandler = nil
completionHandler()
}
}
func urlSession(_ session: URLSession,task: URLSessionTask,didCompleteWithError error: Error?) {
if let error = error {
print(error.localizedDescription)
}
self.leavedispatchGroup()
}
func leavedispatchGroup(){
if dispatchGroupEnterCount > 0 {
self.dispatchGroupEnterCount -= 1
self.dispatchGroup.leave()
}
}
}
App的运行视频: https://youtu.be/lNkMpZRNhGY
解决方法
extension URLSession {
///Background sessions let you perform uploads and downloads of content in the background while your app isn’t running. You can create a background session configuration by calling the backgroundSessionConfiguration(_:) method on the URLSessionConfiguration class.
static let background = URLSession(
configuration: .background(
withIdentifier: "foo"))
}
您必须使用配置为在后台运行的会话。