Reputation: 152
I'm reading json from a URL and, again (I had the same issue with ObjectiveC) the values crash my app. I don't have any problems with Strings and Numbers. I can println(value) but when I assign the value into a UILabel, it crashes.
I use this method to read the JSON:
func jsonFromURL(jsonURL: String) -> Dictionary<String, AnyObject> {
var jsonNSURL: NSURL = NSURL(string: jsonURL)
let jsonSource: NSData = NSData(contentsOfURL: jsonNSURL)
var json = NSJSONSerialization.JSONObjectWithData(jsonSource, options:NSJSONReadingOptions.MutableContainers, error: nil) as Dictionary<String, AnyObject>
return json
}
...and this code to assign values into a UILabel inside a custom Cell
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
var regularTextCell:celda = celda(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
var cell:celda = NSBundle.mainBundle().loadNibNamed("celda", owner: self, options: nil)[0] as celda
cell.name.text = myJson["list"]![indexPath.row]!["name"] as String
cell.id.text = "id: " + String(myJson["list"]![indexPath.row]!["id"] as Int)
// THIS line crash because some values of adress are <null>
cell.address.text = myJson["list"]![indexPath.row]!["address"] as String
return cell
}
You can view an example of the JSON at: https://dl.dropboxusercontent.com/u/787784/example.json
Thanks!
Upvotes: 13
Views: 17783
Reputation: 70135
You'll get an exception from syntax like object as String
if object
is not a String
. You can avoid the exception by using object as? String
which may result in a nil
being assigned into your text
.
In your specific case you could use:
cell.address.text = (myJson["list"]![indexPath.row]!["address"] as? String) ?? "default"
where I've replaced your as
with as?
and exploited the nil-coalescing operator ??
.
Upvotes: 17
Reputation: 423
I found this solution in online Swift tutorial. It's very nice solution how to deal with null value in Swift.
This is the concept:
let finalVariable = possiblyNilVariable ?? "Definitely Not Nil Variable"
In tutorial example :
let thumbnailURL = result["artworkUrl60"] as? String ?? ""
Here is the link for tutorial: http://jamesonquave.com/blog/developing-ios-8-apps-using-swift-interaction-with-multiple-views/
Upvotes: 9
Reputation: 1637
If you use:
You'll be able to go like this:
let yourJSON = JSON.fromURL("https://dl.dropboxusercontent.com/u/787784/example.json")
for (i, node) in yourJSON["list"] {
let isnull = node["address"].isNull
println("//[\"list\"][\(i)]:\t\(isnull)")
}
//["list"][0]: false
//["list"][1]: false
//["list"][2]: true
//["list"][3]: false
//["list"][4]: false
//["list"][5]: true
//["list"][6]: false
//["list"][7]: false
//["list"][8]: false
//["list"][9]: false
//["list"][10]: false
//["list"][11]: false
//["list"][12]: true
//["list"][13]: false
//["list"][14]: false
//["list"][15]: false
//["list"][16]: false
//["list"][17]: false
//["list"][18]: false
//["list"][19]: false
No ?
or !
required and it does not crash on nonexistent nodes.
Upvotes: 1
Reputation: 76898
You can change the offending line to:
if let address = myJson["list"]![indexPath.row]!["address"] as? String {
cell.address.text = address
}
else {
cell.address.text = ""
}
The as?
operator will cast the value the same way as
would, but if the casting fails, it will instead assign nil
The if let …
syntax combines this with a check and when the casting fails (and nil is returned) the else block runs instead
Upvotes: 6