你尝试过使用 JSONSerialization.jsonObject(with:options:)
吗?
var jsonString = "{" +
"\"Language\": {" +
"\"Field\":[" +
"{" +
"\"Number\":\"976\"," +
"\"Name\":\"Test\"" +
"}," +
"{" +
"\"Number\":\"977\"," +
"\"Name\":\"Test\"" +
"}" +
"]" +
"}" +
"}"
var data = jsonString.data(using: .utf8)!
let json = try? JSONSerialization.jsonObject(with: data)
有时候,Swift会产生一些非常奇怪的语法。
if let number = json?["Language"]??["Field"]??[0]?["Number"] as? String {
print(number)
}
JSON对象层次结构中的所有内容最终都被包装为可选项(即AnyObject?
)。 Array<T>
下标返回非可选项T
。对于这个被包装在可选项中的JSON,数组下标返回Optional<AnyObject>
。然而,Dictionary<K,V>
下标返回一个Optional<V>
。对于这个JSON,下标返回非常奇怪的Optional<Optional<AnyObject>>
(即AnyObject??
)。
json
是一个Optional<AnyObject>
。
json?["Language"]
返回一个Optional<Optional<AnyObject>>
。
json?["Language"]??["Field"]
返回一个Optional<Optional<AnyObject>>
。
json?["Language"]??["Field"]??[0]
返回一个Optional<AnyObject>
。
json?["Language"]??["Field"]??[0]?["Number"]
返回一个Optional<Optional<AnyObject>>
。
json?["Language"]??["Field"]??[0]?["Number"] as? String
返回一个Optional<String>
。
Optional<String>
然后被if let
语法用来生成一个String
。
最后注意:遍历字段数组的方式如下。
for field in json?["Language"]??["Field"] as? [AnyObject] ?? [] {
if let number = field["Number"] as? String {
print(number)
}
}
Swift 4 更新
Swift 4 让这一切变得更加容易处理。我们将再次从测试数据开始(使用"""
可以让此过程更轻松愉悦)。
let data = """
{
"Language": {
"Field":[
{
"Number":"976",
"Name":"Test"
},
{
"Number":"977",
"Name":"Test"
}
]
}
}
""".data(using: .utf8)!
接下来,我们可以定义与您的JSON中使用的对象相关的类。
struct Object: Decodable {
let language: Language
enum CodingKeys: String, CodingKey { case language="Language" }
}
struct Language: Decodable {
let fields: [Field]
enum CodingKeys: String, CodingKey { case fields="Field" }
}
struct Field: Decodable {
let number: String
let name: String
enum CodingKeys: String, CodingKey { case number="Number"; case name="Name" }
}
CodingKeys
枚举用于将结构体属性映射到 JSON 对象成员字符串。这种映射是由
Decodable
自动完成的。
现在解析 JSON 很简单。
let object = try! JSONDecoder().decode(Object.self, from: data)
print(object.language.fields[0].name)
for field in object.language.fields {
print(field.number)
}
{...}
开头和结尾。 - Jeffery Thomas