Reputation: 7443
IS there a way to achieve this in Swift?
var z = [ //Error 1
{
"Name":{ //Error 2
"First":"Tika",
"Last":"Pahadi"
},
"City":"Berlin",
"Country":"Germany"
}
]
var c:String = z[0]["Name"]["First"] as String //Error 3
I get a bunch of errors like:
- Cannot convert the expression's type Array to ArrayLiteralConvertible
- Consecutive elements must be separated by a semi-colon
- Type 'Int' doesnot conform to protocol 'StringLiteralConvertible'
Upvotes: 0
Views: 2143
Reputation: 437381
If you're representing this structure in Swift, use square brackets for the dictionaries, as well as for the arrays. And don't forget to unwrap optionals:
let z = [
[
"Name":[
"First":"Tika",
"Last":"Pahadi"
],
"City":"Berlin",
"Country":"Germany"
]
]
if let name = z[0]["Name"] as? [String: String], let firstName = name["First"] {
// use firstName here
}
But let's say you really received that JSON as a result of some network request with URLSession
. You could then parse that with JSONSerialization
:
do {
if let object = try JSONSerialization.jsonObject(with: data) as? [[String: Any]],
let name = object[0]["Name"] as? [String: String],
let firstName = name["First"] {
print(firstName)
}
} catch {
print(error)
}
Or better, in Swift 4, we'd use JSONDecoder
:
struct Name: Codable {
let first: String
let last: String
enum CodingKeys: String, CodingKey { // mapping between JSON key names and our properties is needed if they're not the same (in this case, the capitalization is different)
case first = "First"
case last = "Last"
}
}
struct Person: Codable {
let name: Name
let city: String
let country: String
enum CodingKeys: String, CodingKey { // ditto
case name = "Name"
case city = "City"
case country = "Country"
}
}
do {
let people = try JSONDecoder().decode([Person].self, from: data) // parse array of `Person` objects
print(people)
} catch {
print(error)
}
Upvotes: 3
Reputation: 52530
Swift can't guess what types there are in your JSON array. It can't guess that your data is an array, it can't guess that the first array element is a dictionary, and it can't guess that the value under the key "Name" is a dictionary. And indeed, you don't know that they are because you can't control what the server sends you.
So when NSJSONSerialization returns an AnyObject? you need to cast it to an NSArray* (and better do some checking or your app will crash if it's not an NSArray), check if there are any objects in the array, cast the first element to an NSDictionary* (again with checking to avoid a crash if it's not an NSDictionary*) and so on.
Upvotes: 1