Swift中的JSON解析
我们通常使用JSON从Web服务发送和接收数据。 我们可以在Swift应用程序中轻松使用它。 大多数应用程序完全基于JSON 。 如果您的应用程序正在与Web服务API通信,则它将返回对Dictionary(Object)
, Array
, String
, Bool
, Number
响应。 在创建模型类之前,我们需要牢记哪种类型的响应将来自Web服务,基于响应,我们将创建Model
类。 在本主题中,将涵盖从基本到高级的大部分与解析相关的部分。 🚀
最初,对我来说了解JSON解析是一项艰巨的任务。 在那之后,我意识到这对我来说没什么。 它很容易使用。 只需要了解响应类型。 那就是主要的事情。 🙂
在开始代码之前,我们需要通过点击 浏览器 来检查我们的Web Api –
现在我们在Web浏览器中得到了响应 ,让我们在Xcode
进行一些编码 创建用于JSON解析的新项目–
- 将项目的
plist
添加到内部作为源打开
- 将App Transport Security粘贴到项目的
plist
NSAppTransportSecurity
< dict >
NSAllowsArbitraryLoads
</ dict >
- 现在使用URLSession针对网络API发出网络请求
我们通过Web API发出的请求正在处理数据,而Error将成为响应。 我在这里使用JSONSerialization内置的Foundation框架,它将JSON数据转换为Foundation 对象 。
在这一部分中,我使用了JSONPlaceholder中的测试API。
警卫让url = URL (字符串:“ https://jsonplaceholder.typicode.com/todos”), 否则 { return }
让任务 = URLSession .shared。 dataTask (with: url ) { ( data ,response, error )in
守护 let dataResponse = data ,
错误 ==无其他 {
打印 ( 错误 ?.localizedDescription ??“响应错误”)
返回}
做{
// 这里 是received from a network request
dataResponsereceived from a network request
let jsonResponse =试试JSONSerialization .jsonObject(with:
dataResponse ,选项: [] )
print (jsonResponse) // 响应结果
} catch let parsingError {
打印 (“错误”, parsingError )
}
}
任务 .resume ()
- 来自Web API的JSON格式响应如下所示。 现在我们需要从响应中获取价值。 这里我们的响应来自
JSON Array
。
[
{
“ userId”:1
“ id”:1
“ title”:“ delectus aut autem”,
“已完成”:false
},
{
“ userId”:1
“ id”:2
“ title”:“ quis ut nam facilis et officia qui”,
“已完成”:false
}
]
- 现在处理JSON 响应对象
卫队让 jsonArray = jsonResponse为? [[String:Any]] 其他 {
返回
}
print (jsonArray)// 现在获取标题值
卫队让title = jsonArray [ 0 ] [“ title”]为? 字符串else {return} print( title )// delectus aut autem
让我们尝试打印所有标题键 价值观–
目前,我们的JSON响应是
Dictionary
Array
([[String: Any]]
) 。 因此,借助for
loop
我们从Array
每个index
中提取了Dictionary
。 获取Dictionary
后,使用键访问值。
用于jsonArray中的 dic {
卫队让title = dic [“ title”]为? 其他字符串{return}
print( title )//输出
}
现在我们可以创建用于数据处理的User
结构。 作为响应,基于我在此处选择的用于响应管理的模型结构,我们得到了不同类型的值Int
, String
, Boolean
。
struct 用户 {
var userId :Int
var id :Int
var title :字符串
var 完成 :布尔
初始化 (_字典: [字符串:任何] ){
自。 userId = dictionary [“ userId”]如? Int ?? 0
自。 id = dictionary [“ id”]如? Int ?? 0
自。 title = dictionary [“ title”] as? 字符串 ?? ”
自。 完成 =字典[“ completed”]为? 布尔 ?? 假
}
}
使用模型处理JSON响应–
var model = [ User ]()//初始化模型数组
用于 jsonArray {
model .append( User (dic))//现在在Model数组中添加值
}
print( model [0] 。userId )// 1211
酷 😎, 现在您知道有关JOSN解析的信息了吗? 😃
让我们使用 FlatMap更快地 使相同的代码 –
var model = [ User ]()
模型 = jsonArray。 flatMap {(dictionary) in
返回用户 (词典)
}
print( model [0] 。userId )//使更加简单
模型 = jsonArray。 flatMap {返回用户 ($ 0)} // 再过一次
模型 = jsonArray。 flatMap { 用户 ($ 0)} //或
模型 = jsonArray。 flatMap ( User .init)//输出
print( model [0] 。userId )// 1211
是的,让我们做更多的事情。
这是Apple在Swift 4中引入的新协议 ,可以提供可Encodable
和可Decodable
内置功能。 这将使JSON解析更加容易。 它可以将自身转换成外部表示。
可编码模型如下所示。 它用我们可以管理的代码很少,很容易理解。
这是我在这里向您展示的可编码模型样本 。 您需要根据JSON响应创建自己的结构模型。
struct用户:可编码 {
var userId :Int
var id :Int
var title :字符串
var 完成 :布尔
}
提出网络请求后 。 将Web应用程序响应原始data
转换为Array Model.
其余JSON网络请求在此过程中将是相同的。 仅我们需要处理JSONDecoder的网络响应
Data
。 此协议没有重大更改。
做 {
// 这里 是received from a network request
dataResponsereceived from a network request
让解码器 = JSONDecoder ()
让模型 =尝试解码器 .decode([ User ]。self,来自:
dataResponse )//解码JSON响应数据
打印( 型号 )
} catch let parsingError {
print(“ Error”, parsingError )
}
为什么我使用模型[User].self
因为如果您的响应仅在Dictionary
才能得到,则我们将以Array格式获取响应
网络请求的输出-
{
“ userId”:1
“ id”:1
“ title”:“ delectus aut autem”,
“已完成”:false
}
我们需要使用User.self
类的模型类User.self
进行Dictionary
响应–
做 {
// 这里 是received from a network request
dataResponsereceived from a network request
让解码器 = JSONDecoder ()
让模型 =尝试解码器 .decode( 用户 。 自我 ,来自:
dataResponse )//解码JSON响应数据
print( model.userId )// 输出 -1221
} catch let parsingError {
print(“ Error”, parsingError )
}
自定义键名
我们可以使用自定义String键修改可编码键,但它想与您的JSON响应键匹配。 否则,您将收到错误消息–
为可Codable
模型添加自定义键–
struct用户:可编码 {
var userId :Int
var id :Int
var title :字符串
var complete :布尔// 自定义键
枚举 CodingKeys: 字符串 , CodingKey {
案例userId
case id =“ serviceId” //自定义键
case title =“ titleKey” //自定义键
案件完成
}
}
让代码更快速。 我在这里通过模型的扩展进行了初始化过程。
CodingKeys enum
将使用CodingKey protocol
确认。
struct用户:可编码 {
var userId :Int
var id :Int
var title :字符串
var 完成 :布尔
} 扩展用户{
枚举 CodingKeys: 字符串 , CodingKey {
案例userId
案例编号
案例标题
案件完成
}
}
具有可编码协议的复杂JSON解析
现在我们有了复杂的JSON ,其中有Dictionary,
Array
{
“分支”:{
“主题”:5
“学生总数”:110,
“总书数”:150
},
“学科”: [
{
“ subject_id”:301,
“ name”:“ EMT”,
“实用”:false,
“ pratical_days”: [
“星期一”,
“星期五”
]
},
{
“ subject_id”:302,
“ name”:“网络分析”,
“ pratical”:是的,
“ pratical_days”: [
“星期二”,
“星期四”
]
}
]
}
此JSON响应的Struct Model
。 我写了这样的model
–
struct 学生 :可编码{
struct 分支 :可编码{
let 主题 :Int
let total学生 :Int
让totalBooks :Int
私有枚举CodingKeys :字符串,CodingKey {
案例主题
case totalStudents =“ 总计学生 ”
case totalBooks =“ total_books”
}
}
struct 主题 :可编码{
让subject_id :整数
命名 :字符串
让实际 :布尔
let pratical_days :[ 字符串 ]
}
让分支: 分支
让主题:[ 主题 ]
}
在model
above上,我没有什么要变得更复杂的。 我将所有内容保持简单以便于理解。
从JSON响应解析数据
我们的struct
模型在这里Student
在向网络API提出网络请求后,我已经在这里显示了。 我们直接通过Codable模型处理网络响应数据。 这里没有太大的区别。
做{
// 我们从网络请求中获取的 数据
让解码器= JSONDecoder ()
让响应= 尝试解码器。 解码 ( 学生 .self,来自: 数据 )
print( response.subject [ 0 ]。name)// 输出 -EMT
}捕获{打印(错误) }
最后,我们完成了 JSON 解析。 这是处理代码中任何网络响应数据或JSON对象数据的非常简单的过程。 因此,您可以 基于 JSON
响应 数据 处理 UI 。 我们需要根据需求映射响应中的所有必需值。 🎉
现在终于了解了 从Web服务网络请求到 基于响应的 数据 处理的 JSON 解析 。 在这里,我介绍了如何为 JSON 响应 创建模型 ? 用于在 iOS 应用程序中 正确管理JSON响应 。 我认为这是 使用普通 模型 管理任何 JSON 响应的 最简单方法 Struct
和可 Codable
协议。 您可以根据自己的需要,使用自己的逻辑自行管理它。 Codable 协议在Foundation库中具有非常强大的功能。
我个人建议您使用网络 SDK 来在Swift中发出网络请求。 用于在您的应用程序中发出很棒的网络请求。
Alamofire 您可以在应用程序中用于发出网络请求,这是一个HTTP 网络 库,非常有用且易于使用。 如果您想在项目中执行更多高级功能,则由您选择。 👍
现在,您可以借助Quicktype更轻松地创建Model类。 您可以轻松编写Swift代码。 ✌🏻
希望您会喜欢。 😊感谢您的阅读。 🎉
如果您对本教程有任何疑问? 或想了解更多有关它的信息。 推特我: @Anand