Yes, Task is right, that's the bridge between sync and async worlds.
No idea how long does it take in your case (and given your "as I don't know how many files there are and what their size is" you don't know that either), but if the single file download takes a second and there are 10 of them you may end up having a user to wait, say 5 seconds before the error occurs in the fifth file and download stops, instead of not waiting at all.
That was just a quick and dirty example code. You may of course reshuffle it and make the callback to fire immediately with the individual file data, and doing this (up to) N times, followed by the final callback callout that says either "finished" (in which case all files are good) or "error" (in which case all files that are already created should be deleted). Whether you do the file download in parallel or sequential is unrelated to how you manage the resulting file data (e.g. you may have a sequential implementation that writes to memory first, and you may have a parallel implementation that writes to files immediately without storing individual file data in memory).
Edit: BTW, if you are going to write to the file system anyway why do you use dataTask and not downloadTask to begin with? There are certain advantages to the latter, in particular with just a couple additional steps you can download files in background (even when your app is not running!)
This is not entirely true... you control the queue that's used for the callback. It could be some background queue with:
URLSession.shared
URLSession(configuration: .default)
Or it could be a queue of your own choice, including the main queue (which runs on the main thread):
URLSession(configuration: .default, delegate: nil, delegateQueue: queue) // a given queue
URLSession(configuration: .default, delegate: nil, delegateQueue: .main) // main queue
BTW, if your callback code jumps to the main queue the first thing:
session.dataTask { data, response, error in
DispatchQueue.main.async { // or, equally `otherQueue.async`
// actual code
}
}
you can avoid having that explicit queue dance by specifying the relevant queue in the session initialiser.
I believe you may end up on some system background queue/thread after "await data" even when you specify the queue explicitly as per above, but will leave this for others to comment upon.