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 

我收到一堆错误,例如:

  1. Cannot convert the expression's type Array to ArrayLiteralConvertible
  2. Consecutive elements must be separated by a semi-colon
  3. 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)
}