Bhavik P.
Bhavik P.

Reputation: 915

Downloading Images Asynchronously in Sequence

I am trying to download images but it is crucial that the images I download are in a specific order. I am using the following code to download the image:

func downloadImage(url: NSURL, completionHandler: (response: UIImage) -> ()){
    print("Started downloading \"\(url.URLByDeletingPathExtension!.lastPathComponent!)\".")
    manager.getDataFromUrl(url) { (data, response, error)  in
        dispatch_async(dispatch_get_main_queue()) { () -> Void in
            guard let data = data where error == nil else { return }
            print("Finished downloading \"\(url.URLByDeletingPathExtension!.lastPathComponent!)\".")
            completionHandler(response: UIImage(data: data)!)
        }
    }
}

and I am using this code to call downloadImage

self.downloadImage(NSURL(string: self.url)!, completionHandler: { response in
                            dispatch_async(dispatch_get_main_queue()) {
                                self.images.append(response)
                            }
                        })

The problem is that the images start downloading in the correct order however the response isn't (this is obviously because the size of the images are different and one comes in faster). So what is happening is that all images start downloading, and whichever comes first appends to the images : [UIImage] array. How can I make it so that the images in the images array is in order?

I've also tried to remove the main block when calling downloadImage function

self.downloadImage(NSURL(string: self.url)!, completionHandler: { response in                     
             self.images.append(response)
       })

Upvotes: 3

Views: 760

Answers (2)

Zafar Ahmad
Zafar Ahmad

Reputation: 3219

The simplest method is that you can save every image in Dictionary with their url after downloading. Like var imageData = [String: NSData](). Later you can sort it or use it by keys(url).

Upvotes: 0

MoDJ
MoDJ

Reputation: 4425

You cannot control the download order in the sense that all the requests to the same server will be pipelined no matter what the order you create the URL objects in. Also, some URLs may be cached while others may need to go to the remote server. What you need to do is maintain a mutable array or dictionary that contains the url to actual data mapping, then wait until all the urls have been completely downloaded and then iterate in a known order.

Upvotes: 1

Related Questions