0

To greatly simplify the question, say I have a Swift array consisting of three image URLs that I would like to download like so:

let urls:[String] = [
    "http://acme.com/one.jpeg",
    "http://acme.com/two.jpeg",
    "http://acme.com/three.jpeg",
]

for url in urls {
    downloadImage(url)
}

print("all images downloaded.")

What if I would like to download all of the files in parallel? After reading about Grand Central Dispatch (GCD) and async programming in Swift I'm still unsure how to solve that "problem". I do not want to modify the array, all I want to achieve is parallel execution of downloadImage(url) tasks.

Thanks in advance.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Pono
  • 11,298
  • 9
  • 53
  • 70
  • Maybe this can help a little bit https://stackoverflow.com/questions/50042458/multithreading-executing-multiple-tasks-in-parallel-in-swift-ios – Savca Marin Jul 30 '19 at 13:42

1 Answers1

1

I would advice you to use DispatchGroup for it, I don't know how you will download your images but example of code will look like

    private func downloadAll() {

    let urls:[String] = [
        "http://acme.com/one.jpeg",
        "http://acme.com/two.jpeg",
        "http://acme.com/three.jpeg",
    ]
    let group = DispatchGroup()
    for url in urls {
        group.enter()
        downloadImage(url) {
            group.leave()
        }
    }
    group.notify(queue: .main) {
        print("all images downloaded")
    }
}

func downloadImage(_ url: String, @escaping block: () -> ()) {
    // your code to download
    // in completion block call block()
    // it will call block in for loop to leave the group
}

Hope it will help you, to download you can use SDWebImage framework, it is quite easy in usage

Alexandr Kolesnik
  • 1,929
  • 1
  • 17
  • 30
  • Thanks for this. Xcode is whining about `Attribute can only be applied to types, not declarations` with `escaping` param. How can I fix that? – Pono Jul 30 '19 at 14:01
  • you can remove @escaping and error will gone, but you will need to add this attribute when you will implement download code – Alexandr Kolesnik Jul 30 '19 at 14:06
  • The code compiles now just fine. However to the body of `downloadImage` I added `sleep(3)` and `print(url)` before calling the `block` callback. The result is that I see printing in the console every three seconds. If that is truly async I should see all three console outputs after three seconds, right? – Pono Jul 30 '19 at 14:23
  • no, to get three outputs at a time you need to zip responses, after all code executed you will see "all images downloaded", async means that it is no matter when you will get any response, its like three cars on a road with different speed and you don't know who will finish first – Alexandr Kolesnik Jul 30 '19 at 14:26