iosswiftasynchronousrequestdispatch

Can't use variable outside of scope method in Swift (dataTaskWithRequest)


@IBOutlet var nameLabel : UILabel!
var finalString: String = "test"

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func helloWorldAction(nameTextField: UITextField) {


    //fetch data from server
    let request = NSMutableURLRequest(URL: NSURL(string: "http://192.168.1.11")!)
    request.HTTPMethod = "POST"
    let postString = "user=test&pass=test3"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        //error handeling
        if error != nil {
            println("error=\(error)")
            return
        }

        let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
        self.finalString = String(responseString!)
        println("\(self.finalString)");
    }
    task.resume()

    //print finalString
    println("finalString = \(finalString)")

}

}

I am trying to do two things, and I will tell you what isn't working with both.

First, not seen in this code, I was trying to assign a UILabel.text a value, that didn't work at all. I couldn't do it within the function and neither could I do it outside. This brings me to problem number two. When finalString is printed inside the function it outputs the proper value.

However, when its printed outside the function it prints the value it was first assigned. Please tell me how to assign the UILabel.text a value properly and how to use the output outside of the scope of the questions. Thanks in advance.


Solution

  • import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var nameLabel: UITextField!
        // you have to add a completion block to your asyncronous request
        func fireRequest(link: String, completion: (Data?) -> Void) {
            if let requestUrl = URL(string: link) {
                var request = URLRequest(URL: requestUrl)
                request.httpMethod = "POST"
                let postString = "user=test&pass=test3"
                request.httpBody = Data(postString.utf8)
                URLSession.shared.dataTask(with: request) { data, response, error in
                    guard let data else {
                        print("error:", error ?? "nil")
                        completion(nil)
                        return
                    }
                    completion(data)
                }.resume()
            }
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            print("Fired request:", + Date().description(with: .current)) 
            fireRequest("http://192.168.1.11") { data in
                DispatchQueue.main.async {
                    print("Finished request")
                    if let data,  // unwrap your data
                        let myResponseStr = String(data: data, encoding: .utf8) {      
                        self.nameLabel.text = myResponseStr
                        print("response:", myResponseStr)
                    }
                }
            }
        }
    }