0

I need to use data from a JSON web service to update controls in a SWIFT app. I can get the data no problem, but I can't seem to access the UI controls from within the task block and I can't get the JSON to persist out of the block. I've searched around and haven't found the answer. Here's my test code. The current result is that value1Result has a value inside task, but is nil outside. Thanks in advance.

    var jsonResult:NSDictionary!
    var value1Result:String!

    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) { data, response, error in
        var error: NSError?
        jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &error)!
            as! Dictionary<String, AnyObject>
        println(jsonResult)

        if let value1 = jsonResult["value1"] {
            println(value1)
            value1Result = value1 as! String
            }
        }
    task.resume()

    self.textView1.text = value1Result
beachCode
  • 3,202
  • 8
  • 36
  • 69

2 Answers2

2

You can use asynchronous block to update the main UI

dispatch_async(dispatch_get_main_queue()) {
    //Update your UI
}

With your code

let task = NSURLSession.sharedSession().dataTaskWithURL(url!) { data, response, error in
    var error: NSError?
    jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &error)!
        as! Dictionary<String, AnyObject>
    println(jsonResult)

    if let value1 = jsonResult["value1"] {
        println(value1)
            dispatch_async(dispatch_get_main_queue()) {
                //Update your UI
                value1Result = value1 as! String
                self.yourtextview.text = value1 as! String
            }
        }
    }
task.resume()
Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
1

Doing proper network coding is hard. There's a lot of problems with your code both stylistically, in terms of robustness, and actual functionality. That is why networking vs. UI is always layered with a library like AFNetworking. Doing it right yourself is just too much manual labor.

Consider what it takes to check for errors properly and hand off the code properly to the UI thread:

let task = session.dataTaskWithURL(url) {
    [unowned self]
    (data: NSData?, response: NSURLResponse?, netError: NSError?) in            
    if let statusCode = (response as? NSHTTPURLResponse)?.statusCode {
        if statusCode == 200 {
            if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &error) as? Dictionary<String, AnyObject> {
                if let value1 = jsonResult["value1"] as? String {
                    dispatch_async(dispatch_get_main_queue()) {
                        self.textView1.text = value1
                    }
                }
                else {
                    println("JSON format error, key value1 not defined")
                }
            }
            else {
                println("JSON parsing error: \(error.localizedDescription)")      
            }
        else { // status code other than 200
             println("HTTP Error \(statusCode)")
        }
    }
    else { // No HTTP response available at all, couldn't hit server
        println("Network Error: \(netErr!.localizedDescription)")
    }
}

task.resume()
BaseZen
  • 8,650
  • 3
  • 35
  • 47