JSON Swift 中的复杂数组
JSON Complex Arrays in Swift
有没有办法在 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
我收到一堆错误,例如:
- 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'
Swift 猜不出你的 JSON 数组中有哪些类型。它猜不出你的数据是一个数组,它猜不到第一个数组元素是一个字典,它猜不出键"Name"下的值是一个字典。事实上,您不知道它们是因为您无法控制服务器发送给您的内容。
那么当NSJSON序列化returns一个AnyObject?您需要将其转换为 NSArray*(最好进行一些检查,否则如果它不是 NSArray,您的应用程序将崩溃),检查数组中是否有任何对象,将第一个元素转换为 NSDictionary*(再次检查如果它不是 NSDictionary*) 等,则避免崩溃。
如果您在 Swift 中表示此结构,请对字典和数组使用方括号。并且不要忘记打开选项:
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
}
但假设您确实收到 JSON 作为某些网络请求的结果 URLSession
。然后你可以用 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)
}
或者更好,在 Swift 4 中,我们将使用 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)
}
有没有办法在 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
我收到一堆错误,例如:
- 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'
Swift 猜不出你的 JSON 数组中有哪些类型。它猜不出你的数据是一个数组,它猜不到第一个数组元素是一个字典,它猜不出键"Name"下的值是一个字典。事实上,您不知道它们是因为您无法控制服务器发送给您的内容。
那么当NSJSON序列化returns一个AnyObject?您需要将其转换为 NSArray*(最好进行一些检查,否则如果它不是 NSArray,您的应用程序将崩溃),检查数组中是否有任何对象,将第一个元素转换为 NSDictionary*(再次检查如果它不是 NSDictionary*) 等,则避免崩溃。
如果您在 Swift 中表示此结构,请对字典和数组使用方括号。并且不要忘记打开选项:
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
}
但假设您确实收到 JSON 作为某些网络请求的结果 URLSession
。然后你可以用 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)
}
或者更好,在 Swift 4 中,我们将使用 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)
}