Holy cow...there MUST be a better way to access formatted in
floorplan_summary: {
bedrooms: {
low: 1,
high: 2,
formatted: "1 - 2 Beds"
}
}
than doing this:
if data["floorplan_summary"]?["bedrooms"] != nil {
let bedrooms = data["floorplan_summary"]?["bedrooms"] as NSDictionary
if bedrooms["formatted"] != nil{
self.beds = bedrooms["formatted"] as String
}
}
I want to just do this:
self.beds = data["floorplan_summary"]?["bedrooms"]?["formatted"] as String
..but at each level the object seems to be cast as AnyObject. Why can the compiler assume this data["floorplan_summary"]?["bedrooms"] but not the above?
How can I simplify this?
Assuming data is NSDictionary, or [String:AnyObject]. You can:
let beds = data["floorplan_summary"]?["bedrooms"]??["formatted"] as? String // -> as String?
^
You need extra ? because data["floorplan_summary"]?["bedrooms"] returns AnyObject??. You have to unwrap it twice.
Why it returns AnyObject??? Because data["floorplan_summary"]? is AnyObject, and AnyObject may or may not have subscript. So, the first ? means, "If it has subscript", and the second means "If subscript returns non nil".
If you are wanting the syntax you described, I'd suggest using SwiftyJSON. It seems pretty popular, and it's all implemented in a single swift file so not hard to add it to your project. It would look something like this.
let floorPlanSummary = JSON(data: yourRawData)
self.beds = floorPlanSummery["bedrooms"]["formatted"].string
You may be able to just invoke data.valueForKeyPath("floorplan_summary.bedrooms.formatted")
来源:https://stackoverflow.com/questions/28465390/accessing-nested-dictionary-from-api-in-swift