0

I have the following Swift code where I am sending a POST request to a webserver and receiving a value back. The error that I receive is on the second to last line saying "Use of unresolved identifier"

func download_request() -> String {
    let url:NSURL = NSURL(string: "http://url.com/read.php")!
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let paramString = "data=name"
    request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.downloadTaskWithRequest(request) {

        (let location, let response, let error) in

        guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
            print("Error")
            return
        }

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

        guard let _:NSString = urlContents else {
            print("Error")
            return
        }

     }

    task.resume()
    return urlContents
}

How would I fix this error? I think that it means that I cannot use urlContents outside of the let task = session.downloadTaskWithRequest(request) { } but how would I declare the variable so that I can use it outside?

2 Answers 2

2

Try declaring urlContents outside of the session.downloadTaskWithRequest(request) { } block. Like so:

func download_request() -> String? {
    let url:NSURL = NSURL(string: "http://url.com/read.php")!
    let session = NSURLSession.sharedSession()
    var urlContents: NSString?

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let paramString = "data=name"
    request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.downloadTaskWithRequest(request) {

        (let location, let response, let error) in

        guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
            print("Error")
            return
        }

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

        guard let _:NSString = urlContents else {
           print("Error")
           return
        }

     }

    task.resume()
    return (urlContents as! String)
}

Then when you need to use urlContents unwrap it with an if let binding

if let contents = download_request() {
    //Use safely unwrapped contents
}
Sign up to request clarification or add additional context in comments.

10 Comments

This fixed the error, however, I now get a different error when building and running: fatal error: unexpectedly found nil while unwrapping an Optional value
The code fixed that problem but the if statement that lets me us the unwrapped urlContents is not running (as tested by else statement).
Try checking print(contents) inside the if let statement. If this returns nil, then you may want to check you link as it is probably returning nil for content. Also where did you put the if let statement? @DanielZam
I put the if let statement inside of a button press
What are you trying to download? @DanielZam.
|
0

You could make return type optional like below

func download_request() -> String? {
     var urlContents: String?
     ....
     ....
     let task = session.downloadTaskWithRequest(request) {

        (let location, let response, let error) in
        ...
        ...
        ...
        guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
            print("Error")
            return
        }
       urlContents = try! NSString(contentsOfURL: location!, encoding: NSUTF8StringEncoding) as String
        guard let _:NSString = urlContents else {
            print("Error")
            return
        }
    }
    task.resume()
    return urlContents
}

And call the method like

 if let request = download_request() {
     //do anything with your request
 }

Suggesting you to rename your method properly since you are returning the downloaded data not the request.

And this is not the correct way to get your downloaded data back as a return to the method since the completionHandler will be called once the operation is done so urlContents will be nil. Hence create another method which takes String as input and call it within the completionHandler of downloadTaskWithRequest

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.