Switch to timer for download task

This commit is contained in:
ronaldheft
2022-08-14 16:10:55 -04:00
parent 1f8a8d1ce5
commit 7cc35e4b96
+28 -26
View File
@@ -22,7 +22,7 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
}() }()
private let progressStatusQueue = DispatchQueue(label: "progress-status-queue", attributes: .concurrent) private let progressStatusQueue = DispatchQueue(label: "progress-status-queue", attributes: .concurrent)
private var downloadItemProgress = [String: DownloadItem]() private var downloadItemProgress = [String: DownloadItem]()
private var isMonitoringProgress = false private var monitoringProgressTimer: Timer?
public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
handleDownloadTaskUpdate(downloadTask: downloadTask) { downloadItem, downloadItemPart in handleDownloadTaskUpdate(downloadTask: downloadTask) { downloadItem, downloadItemPart in
@@ -102,40 +102,42 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
// We want to handle updating the UI in the background and throttled so we don't overload the UI with progress updates // We want to handle updating the UI in the background and throttled so we don't overload the UI with progress updates
private func notifyDownloadProgress() { private func notifyDownloadProgress() {
if !self.isMonitoringProgress { if self.monitoringProgressTimer == nil {
self.isMonitoringProgress = true NSLog("Already monitoring progress, no need to start timer again")
DispatchQueue.global(qos: .userInteractive).async { } else {
NSLog("Starting monitoring download progress...") DispatchQueue.runOnMainQueue {
self.monitoringProgressTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true, block: { t in
NSLog("Starting monitoring download progress...")
// Fetch active downloads in a thread-safe way // Fetch active downloads in a thread-safe way
func fetchActiveDownloads() -> [String: DownloadItem]? { func fetchActiveDownloads() -> [String: DownloadItem]? {
self.progressStatusQueue.sync { self.downloadItemProgress } self.progressStatusQueue.sync {
} let activeDownloads = self.downloadItemProgress
if activeDownloads.isEmpty {
// Remove a completed download item in a thread-safe way NSLog("Finishing monitoring download progress...")
func handleDoneDownloadItem(_ item: DownloadItem) { t.invalidate()
self.progressStatusQueue.async(flags: .barrier) { }
self.downloadItemProgress.removeValue(forKey: item.id!) return activeDownloads
}
} }
Database.shared.removeDownloadItem(item)
self.handleDownloadTaskCompleteFromDownloadItem(item)
}
// While there are active download items, emit status updates // Remove a completed download item in a thread-safe way
while !(fetchActiveDownloads()?.isEmpty ?? false) { func handleDoneDownloadItem(_ item: DownloadItem) {
self.progressStatusQueue.async(flags: .barrier) {
self.downloadItemProgress.removeValue(forKey: item.id!)
}
Database.shared.removeDownloadItem(item)
self.handleDownloadTaskCompleteFromDownloadItem(item)
}
// Emit status for active downloads
if let activeDownloads = fetchActiveDownloads() { if let activeDownloads = fetchActiveDownloads() {
for item in activeDownloads.values { for item in activeDownloads.values {
try? self.notifyListeners("onItemDownloadUpdate", data: item.asDictionary()) try? self.notifyListeners("onItemDownloadUpdate", data: item.asDictionary())
if item.isDoneDownloading() { handleDoneDownloadItem(item) } if item.isDoneDownloading() { handleDoneDownloadItem(item) }
} }
} }
})
// Wait 200ms before reporting status again
Thread.sleep(forTimeInterval: TimeInterval(0.2))
}
NSLog("Finished monitoring download progress...")
self.isMonitoringProgress = false
} }
} }
} }