beachCode
beachCode

Reputation: 3510

using JSON data in SWIFT UI controls

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

Upvotes: 0

Views: 839

Answers (2)

BaseZen
BaseZen

Reputation: 8718

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()

Upvotes: 1

Ashish Kakkad
Ashish Kakkad

Reputation: 23882

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()

Upvotes: 2

Related Questions