在本章中,你将学会如何引用并解析JSON数据。

JSON,是JavaScript目标表示法的简称,是客户机和服务器应用程序中用于数据交换的一种常见数据格式。咱们App客户端发送网络请求,服务端就会回来JSON文本,供App客户端进行解析,解析完成后客户端再把对应数据展现到页面上。

SwiftUI极简教程33:JSON数据的使用

咱们学习下JSON数据及其解码办法的相关内容。

项目创立

首要,创立一个新的Playground文件,命名为SwiftUIJSON

SwiftUI极简教程33:JSON数据的使用

变量声明

咱们创立一个简略的json数据。

let json = """
{
"name": "Ricardo",
"country": "China",
"city": "Guangzhou"
}
"""

然后,咱们界说下需求的参数称号,咱们需求新建一个personalInformation个人信息的结构体来界说json数据里的参数。

struct personalInformation: Codable {
var name: String
var country: String
var city: String
}

这儿,咱们运用的personalInformation个人信息结构体需求遵从Codable可编码协议,并且personalInformation个人信息结构体中界说的变量需求与JSON的键逐个匹配。

实例化

接下来,咱们解析下json数据。

let decoder = JSONDecoder()
if let jsonData = json.data(using: .utf8) {
do {
let message = try decoder.decode(personalInformation.self, from: jsonData)
print(message)
} catch {
print(error)
}
}

咱们实例化JSONDecoder的一个实例,然后将JSON字符串转换为personalInformation的目标。

运行下代码,咱们能够看到,咱们取得并展示了json内的数据。

SwiftUI极简教程33:JSON数据的使用

参数映射

在咱们从服务器取得JSON数据时,可能会出现咱们实例化的参数和JSON数据的参数不匹配的状况。

示例:在JSON数据中,咱们把city城市换成cityName城市称号。

这时候,咱们就需求映射字段称号,而不需求每次都更改咱们界说的字段。

enum CodingKeys: String, CodingKey {
case name
case country
case city = "cityName"
}

咱们在personalInformation个人信息结构体增加了一个枚举,然后运用case转换参数进行映射。

SwiftUI极简教程33:JSON数据的使用

目标嵌套

咱们再考虑一种状况,如果JSON数据中存在嵌套联系,比如咱们新增一个参数location方位,在location方位里放country国家参数。

let json = """
{
"name": "Ricardo",
"location": {
"country": "China",
},
"cityName": "Guangzhou"
}
"""

这个例子很常见,咱们能够把省、市、区放在地址里,这种目标中嵌套目标,咱们处理也需求建立映射联系。

首要咱们需求在CodingKeys中设置切换。

enum CodingKeys: String, CodingKey {
    case name
    case country = "location"
    case city = "cityName"
}

同时咱们还需求界说了一个枚举LocationKeys,它的参数是被location方位嵌套的country国家参数。

由于咱们不能直接映射,那咱们需求在Codable协议的初始化器中来解码得到咱们想要的值。

enum LocationKeys: String, CodingKey {
    case country
}

然后是实现办法。

init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
let location = try values.nestedContainer(keyedBy: LocationKeys.self, forKey: .country)
country = try location.decode(String.self, forKey: .country)
city = try values.decode(String.self, forKey: .city)
}

咱们在init函数办法中,调用decodercontainer容器解码器办法来获取CodingKeys枚举的数据,CodingKeys枚举里有name姓名。

而由于country国家参数在location方位的容器中,就需求通过调用LocationKeys枚举的nestedContainer办法进一步解码城市的值。

以上便是嵌套目标解码JSON数据的办法。

SwiftUI极简教程33:JSON数据的使用

数据数组

在上面咱们了解的都是根据1行数据的解析,如果咱们JSON数据是由多行数据组成的数组,咱们又该如何解析呢?

let json = """
{
"messages":[
{
"name": "Ricardo",
"location": {
"country": "China",
},
"cityName": "Guangzhou"
},{
"name": "Ricardo",
"location": {
"country": "China",
},
"cityName": "Guangzhou"
}]
}
"""

咱们的JSON有一个messages数组,里边有2个数据行。

要想解析这个messages数组,咱们也是需求创立一个遵从Codable可编码协议的结构体,这儿命名为MessageArrays

struct MessageArrays: Codable {
var messages: [personalInformation]
}

咱们用messages来接纳personalInformation个人信息结构体的数据。

然后在解析这块,咱们就不能直接解析personalInformation的数据了,咱们改为解析MessageArrays数组的数据。

同时,咱们用for循环输出下数据看看效果:

let decoder = JSONDecoder()
if let jsonData = json.data(using: .utf8) {
do {
let messageArrays = try decoder.decode(MessageArrays.self, from: jsonData)
for message in messageArrays.messages {
print(message)
}
} catch {
print(error)
}
}

SwiftUI极简教程33:JSON数据的使用

祝贺你,咱们完成了JSON数据的全部学习!

完好代码

import SwiftUI
//json数据准备
let json = """
{
"messages":[
{
"name": "Ricardo",
"location": {
"country": "China",
},
"cityName": "Guangzhou"
},{
"name": "Ricardo",
"location": {
"country": "China",
},
"cityName": "Guangzhou"
}]
}
"""
//界说数组
struct MessageArrays: Codable {
var messages: [personalInformation]
}
//界说模型
struct personalInformation: Codable {
var name: String
var country: String
var city: String
  //界说参数枚举
enum CodingKeys: String, CodingKey {
case name
case country = "location"
case city = "cityName"
}
  //数组枚举
enum LocationKeys: String, CodingKey {
case country
}
  //实例化
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
let location = try values.nestedContainer(keyedBy: LocationKeys.self, forKey: .country)
country = try location.decode(String.self, forKey: .country)
city = try values.decode(String.self, forKey: .city)
}
}
//解析数据
let decoder = JSONDecoder()
if let jsonData = json.data(using: .utf8) {
do {
let messageArrays = try decoder.decode(MessageArrays.self, from: jsonData)
for message in messageArrays.messages {
print(message)
}
} catch {
print(error)
}
}

快来动手试试吧!

如果本专栏对你有协助,不妨点赞、评论、重视~