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
2

2 Answers 2

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()
Sign up to request clarification or add additional context in comments.

4 Comments

Ashish, could you be more specific? I tried adding the textview update line inside your example and it doesn't change the fact that value1Result is nil. Thanks
@user3026206 updated the answer. I don't know what is value1Result so, I have added the value1 as! String in text view directly.
Awesome. Got it. Thanks buddy!
@user3026206 Welcome anytime :)
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()

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.