json解析 技巧

利用Codable解析JSON
let json = """
{
"name": "Paul",
"age": 14
}
"""
let data = Data(json.utf8)
如果JSON键值与swift属性名称相同,因为编译器已经处理了关系映射,可以直接解析
struct User: Codable {
var name: String
var age: Int
}
let decoder = JSONDecoder()
do {
let decoded = try decoder.decode(User.self, from: data)
print(decoded[0].name)
} catch {
print("Failed to decode JSON")
}
如果JSON键与Swift属性完全不同,则可以使用CodingKeys枚举来映射它们,例如:
struct User2: Codable {
var username: String
var age: Int
enum CodingKeys: String, CodingKey {
case username = "name"
case age
}
}
do {
let decoded = try decoder.decode(User2.self, from: data)
print(decoded[0].name)
} catch {
print("Failed to decode JSON")
}
JSON嵌套层级的处理,如下JSON:
let json2 = """
{
"latitude": 102.11,
"longitude": 23.01,
"additional":
{
"elevation": 1000
}
}
"""
let data2 = Data(json.utf8)
因为JSON包含不同层级,如何利用Codable将json2用下面这个model解析呢
struct Coordinate: Codable {
var latitude: Double
var longitude: Double
var elevation: Double
}
由于elevation与latitude、longitude不在同一层级
extension Coordinate {
enum CodingKeys: String, CodingKey {
case latitude
case longitude
case additional
}
enum AdditionalKeys: String, CodingKey {
case elevation
}
}
let decoder = JSONDecoder.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
latitude = try values.decode(Double.self, forKey: .latitude)
longitude = try values.decode(Double.self, forKey: .longitude)
利用嵌套方法去读取下一层级的数据
container.nestedContainer(keyedBy: AdditionalKeys.self, forKey: .additional)
let additional = try container.nestedContainer(keyedBy: AdditionalKeys.self, forKey: .additional)
elevation = try additionalInfo.decode(Double.self, forKey: .elevation)
如何解析下面这种JSON
let json5 = """
[
"A string",
[
"A string",
"A string",
"A string",
"A string",
]
]
""".data(using: .utf8)!
利用 unkeyedContainer解析这种无Key的json
struct Model: Decodable {
let str: String
let array: [String]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
str = try container.decode(String.self)
array = try container.decode([String].self)
}
}
let ut = try JSONDecoder.init().decode(Model.self, from: json5)
print(ut)
// 输出
Model(str: "A string", array: ["A string", "A string", "A string", "A string"])
利用SingleValueContainer解析单个值
let json4 = "123".data(using: .utf8)!
struct Number: Codable {
let value: Int
init(value: Int) {
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let v = try container.decode(Int.self)
self.init(value: v)
}
}
let decoder = JSONDecoder()
let d = try decoder.decode(Number.self, from: json4)
print(d) //输出:Number(value: 123)