Reputation: 3510
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
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
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