It's much easier if you use Swift Concurrency to achieve what you want:
/// This function runs on the main thread
@MainActor func downloadAndShowError() async {
do {
// Try to download files from the urls
// The function is suspended here, but the main thread is Not blocked.
try await download(urls: [])
} catch {
// Show error if occurred, this will run on the main thread
print("error occurred: \(error.localizedDescription)")
}
}
/// This function asynchronously downloads data for all passed URLs.
func download(urls: [URL]) async throws {
let session = URLSession(configuration: .default)
for url in urls {
// If an error occurs, then it will throw, loop will break and function throws,
// caller must deal with the error.
let (data, response) = try await session.data(from: url)
// Do something with data, response
// You can even throw from here if you don't like the response...
}
}