My app downloads a couple of files from a server, using a URLSessionDataTask
. When a downloads finishes successfully (and without any errors), then it should start the next download. If there is any type of error, then the whole thing has to abort and display the error message through the calling function. If it finishes without any errors, then it simply switches back to the calling function.
This function is called after another dataTask
has finished (using a completion handler) but I never switch back to the main thread, so all of this is still running in the same background thread the previous task used.
My code (Swift 5, Xcode 14.2):
private func fileDownload(fileNames fns:[String]) {
if !errorBool {
print("Main thread: \(Thread.isMainThread)")
let group = DispatchGroup()
myloop:
for f in fns {
let url = getURL(f)
group.enter()
//DispatchQueue.global(qos: .background).async {
let task = session.dataTask(with: url) {(data, response, error) in
defer { group.leave() }
print("Starting task!")
if error != nil && data == nil {
self.errorBool = true
break myloop //TODO 1: "Cannot find label 'myloop' in scope", "self." doesn't help
}
if let httpResponse = response as? HTTPURLResponse {
//Do stuff with downloaded data, more error handling that sets the error flag
}
}
task.resume()
//}
//TODO 2: How do I wait here for the task to finish?
//group.wait()
if errorBool {
break myloop
}
}
group.notify(queue: .main) {
print("Done!")
//Displays any errors in a popup (on the main thread) through the calling function
}
}
}
There are two things that I'm experiencing problems with:
- How do I break the loop from within the task if there's an error ("TODO 1")?
- How do I wait at "TODO 2" until the task finishes, so I can break the loop if there are any errors? If I use
group.wait()
there, then the task never starts (deadlock?), even though it should automatically run on a background thread. I tried to switch to yet another background thread for the task (see inactive code above) but that didn't help either.