我想在appdelegate中实现performFetchWithCompletionHandler。我想做这样的事情
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
DownloadManager.shared.startDownload(completion: { (done) in
if done{
completionHandler(.newData)
}else{
completionHandler(.noData)
}
})
我不确定如何在DownloadManager
上实现此功能。它的实际实现看起来像
class DownloadManager{
var pagesDownloadCompleted = false
var imagesDownloadCompleted = false
// Function to start the download
func startDownload(date: DataToDownload){
...
downloadPages(pages)
downloadImages(images)
}
}
// Function to download the pages
func downloadPages(pages: Pages){
....
if completed{
pagesDownloadCompleted = true
}
}
// Function to download the images
func downloadImages(images: Images){
....
if completed{
imagesDownloadCompleted = true
}
}
// Function to check if the doanload is done
func downloadCompleted() -> Bool{
return pagesDownloadCompleted == true && imagesDownloadCompleted == true
}
}
}
一种可能的解决方案是开始下载页面,当我完成后,我开始下载图像,当图像完成后,我返回true。但下载图像和页面将不会平行。你看到其他任何解决方案吗?
答案 0 :(得分:0)
应该是这样的,你仍然需要处理失败和数据流,尝试使用dispatch group也是另一种解决方案:
class DownloadManager {
var pagesDownloadCompleted = false
var imagesDownloadCompleted = false
// Function to start the download
func startDownload(date: String, completion: (_ completed: Bool)->()){
downloadPages(pages: page) { (completed) in
if completed {
pagesDownloadCompleted = true
}
self.downloadCompleted(completion: completion)
}
downloadImages(images: image) { (completed) in
if completed {
imagesDownloadCompleted = true
}
self.downloadCompleted(completion: completion)
}
}
// Function to download the pages
func downloadPages(pages: Pages, completion: (_ completed: Bool)->()){
completion(true) //When download finished
}
// Function to download the images
func downloadImages(images: Images, completion: (_ completed: Bool)->()){
completion(true) //When download finished
}
// Function to check if the doanload is done
func downloadCompleted(completion: (_ completed: Bool)->()){
if pagesDownloadCompleted == true && imagesDownloadCompleted == true {
completion(true)
}
}
}
答案 1 :(得分:0)
IMO使用DispatchGroup
可以最好地解决这类问题。每当您开始下载时,请致电enter
,此时呼叫已完成leave
。 group.notify
用于确定何时完成所有下载。
class DownloadManager{
var group = DispatchGroup()
func startDownload(date: DataToDownload) {
downloadPages(pages)
downloadImages(images)
group.notify(queue: DispatchQueue.main) {
// all downloads completed
}
}
// Function to download the pages
func downloadPages(_ pages: Pages){
group.enter()
// do the download, when done, call:
group.leave()
}
// Function to download the images
func downloadImages(_ images: Images){
group.enter()
// do the download, when done, call:
group.leave()
}
}