简体   繁体   中英

Execute swift nsurlsession Tasks in serial order

I don't know how to execute multiple NSUrlSession tasks one by one. When first task finishes start second task, when second task finishes start third task etc

For example I want to download multiple files from a web service.

I want them to begin downloading one by one.

For example files: 1.png , 2.png , 3.png

I want them to be downloaded in the same order I wrote them.

How can I do that with NSUrlSession?

A couple of things:

  1. Traditional iOS solution is to wrap the network request task in an asynchronous Operation subclass (eg, such as outlined in point 3 of this answer ; see this answer for another permutation of that base AsynchronousOperation ). Just set the queue's maxConcurrentOperationCount to 1 and you have serial/sequential download of images.

  2. But you really don't want to do that because you pay huge performance penalty by downloading images sequentially. The only time you should perform network requests sequentially is if you absolutely need the response of one request in the preparation of the next request (eg a “login request” retrieves a token and a subsequent request that uses the token for authentication purposes).

    But when dealing with a series of images, though, it's going to be much faster to download the images concurrently. Store them in a dictionary (or whatever) as they come in:

     var imageDictionary: [URL: UIImage] = [:] 

    Then:

     imageDictionary[url] = image 

    Then, when you want the images in order of your original array of URLs, you just lookup the image associated with a URL, for example:

     let sortedImages = urls.compactMap { imageDictionary[$0] } 
  3. Alternatively, you might completely rethink the notion of downloading a series of images up-front. For example, if these are image view's in a table view, you might just use a third party library, such as Kingfisher , and use its UIImageView method setImage(with:) :

     let url = URL(string: "https://example.com/image.png") imageView.kf.setImage(with: url) 

    This gets you completely out of the business of fetching images and managing caches, low memory warnings, etc. This just-in-time pattern can result in more performant user interfaces. And even if you really want to download them in advance (a bit of an edge case, so make sure you really need to do that), libraries like Kingfisher can manage that too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM