Issues with sharedSession.downloadTaskWithURL in Swift 2

I'm having am issue when trying to download a file via URL in Xcode Beta 5 and Swift 2 running iOS9


Would really appreciate any help as I am going crazy trying to find out what it doesn't like about the code in swift2 ? The documentation says the method signature has not changed. I click on the code suggestion to get the completion handlers then it gives me errors. I took the code back into Swift 1.2 in Xcode 6.4 and it ran straight away 😕


This code runs fine in iOS 8.4 Xcode 6.4


let messageURL = NSURL(string: "http:/
        let sharedSession = NSURLSession.sharedSession()
        let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!,
            completionHandler: {
                (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
   
                var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
   
                println("response : \(response)")
                println(urlContents)
   
        })
        downloadTask.resume()


I get a response and urlContents printed.


The same code for iOS9 gives me a compile error complaining about the method signature of the downloadTaskWithURL function


        let messageURL = NSURL(string: "http:/
        let sharedSession = NSURLSession.sharedSession()
        let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!,
            completionHandler: {
                (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
     
                var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
     
                print("response : \(response)")
                print(urlContents)
     
        })
        downloadTask.resume()


The compile error is shown below:


https://drive.google.com/file/d/0B7a9zgAH2mBfeHM0TjE5MF91RzA/view?usp=sharing

http://i.imgur.com/AW9ge7R.png

Successful code in iOS8.4:

http://i.imgur.com/P17JROM.png

Accepted Answer

The problem is that your completion blocks parameters are all implicitly unwrapped optionals whereas the latest Swift compiler expects them to be simply optionals (the latter makes more sense because you can reasonable expect them to be nil).

So, the following code will compile in Xcode 7.0b5.

let messageURL = NSURL(string: "https://www.apple.com")
let sharedSession = NSURLSession.sharedSession() 
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!, 
    completionHandler: { 
        (location: NSURL?, response: NSURLResponse?, error: NSError?) -> Void in 

        let urlContents = try! NSString(contentsOfURL: location!, encoding: NSUTF8StringEncoding) 

        print("response : \(response)") 
        print(urlContents) 

}) 
downloadTask.resume()

I had to make four changes:

  • the above-mentioned change to the completion block parameters in line 5

  • adopting Swift 2 error handling in line 7

  • switching from

    var
    to
    let
    , also in line 7
  • force unwrapping

    location
    , still in line 7

Of course this code is still not correct because, if the download fails,

location
will be nil and you’ll hit a runtime check trying to read the file. You need to check for an error and handle that appropriately.

ps Did you run the Swift 2 converter over your project? It takes care of all except the last of my four changes.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you Quinn!


Appreciate the fast reply and the explanation. I'm new to Swift and came in to the language with 2.0. I tried the code in Xocde 8.4 as a test - wasn't aware of the converter but I am now :-)

Issues with sharedSession.downloadTaskWithURL in Swift 2
 
 
Q