PjotrC
PjotrC

Reputation: 331

Swift: How to download synchronously?

I am using following code, to download some files:

    let url = NSURL(string:"https://www.example.org/")!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
        if error != nil {
            NSLog("%@", "Error: \(error)");
            return
        }

        NSLog("Loaded %i bytes", data!.length)
    }
    task.resume()

I want to process some of the files and quit my application after downloading. Therefore I need to know, when the download process is finished. The best would be, if there is a way to do this synchronously (no problem, if UI is blocked - it is just a spash screen with a progressbar). But as far as I understood this topic after some research, this is not possible in Swift any more...

I did wrap this code in a function, therefore I can't just add some code after the NSLog statement. What I need to know is: When did the last file finish downloading? How can I retrive this information?

EDIT: This code did work for me (but be aware, its deprecated!):

    // download file synchonously ////////////////////////////////////////////////////
    func downloadSync(fromURL: String, toPath: String) {
        let request = NSURLRequest(URL: NSURL(string: fromURL)!)
        var response: NSURLResponse?
        do {
            let data = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)
            data.writeToFile(toPath, atomically: true)
        } catch {
            print("Error while trying to download following file: " + fromURL)
        }
    }

Upvotes: 0

Views: 4071

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59506

After you invoke task.resume(), the download starts.

When the download does complete (or an error is received) the code inside the { } following dataTaskWithURL is called. That's a closure and it's called asynchronously.

let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
    // This code is executed asynchronously after data has been received
}
task.resume()

Inside the closure you receive 3 params:

  1. data: the NSData you requested
  2. response: the whole NSURLResponse
  3. error: an NSError object

These 3 values are optional, so could be nil.

E.g. error could be populated and data could be nil.

The synchronous way [DEPRECATED in iOS 9]

This approach has been deprecated in iOS 9 and you should NOT use it, however here's the code

var response: NSURLResponse?
var error: NSError?
let urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)

Upvotes: 2

Related Questions