原文:How to parse JSON using SwiftyJSON - free Swift 5.4 example code and tips
SwiftyJSON 是一个超级简化的 JSON 解析库,它给你的语法比内置的 iOS 库更清晰(是的,甚至比 Codable
中的 JSONEncoder
更清晰),并且是免费的。
你可以从这里下载它 -- 解压你下载的文件,然后在它的 Source 目录中寻找,并将 SwiftyJSON.swift 拖到你的 Xcode 项目中。要使用 SwiftyJSON,你需要把你的 JSON 字符串转换成一个 Data
对象,然后把它送进去进行解析。一旦完成,你只需请求你想要的格式的数据,(这里是最棒的一点)SwiftyJSON 保证会返回一些东西。
如果所有东西都是好的,这个 "东西" 将是你的数据。但是如果你请求了错误的东西(要么是打错了,要么是因为你没有正确理解你的 JSON 结构),或者是 JSON 发生了变化,SwiftyJSON 将只是返回一个默认值。
为了让你开始,这里有一些 JSON 的例子:
swift
let json = "{ \"people\": [{ \"firstName\": \"Paul\", \"lastName\": \"Hudson\", \"isAlive\": true }, { \"firstName\": \"Angela\", \"lastName\": \"Merkel\", \"isAlive\": true }, { \"firstName\": \"George\", \"lastName\": \"Washington\", \"isAlive\": false } ] }"
它包含一个有三个人的数组,每个人都有一个 firstName
,一个 lastName
,和一个 isAlive
的状态。要使用 SwiftyJSON 解析这个数组并打印出所有的名字,下面是代码:
swift
if let data = json.data(using: .utf8) {
if let json = try? JSON(data: data) {
for item in json["people"].**arrayValue** {
print(item["firstName"].**stringValue**)
}
}
}
这里是 arrayValue
和 stringValue
属性在起作用:第一个属性返回 people
中的数组,如果 people
元素不存在,则返回一个空数组,第二个属性返回 people
的 firstName
属性,如果没有设置,则返回一个空字符串。因此,无论发生什么情况,这段代码都会工作,这意味着它很容易编写,运行也很安全。
有时 JSON 有相当深的嵌套字典,但这没关系:SwiftyJSON 可以在一次调用中浏览多个层次,如果任何一个层次失败,你仍然会得到你的默认值。例如,如果你有这样的 JSON:
swift
{
"metadata":{
"responseInfo":{
"status":200,
"developerMessage":"OK",
}
}
}
你可能想在继续之前检查状态代码是否为 200。要做到这一点,只需一次性读取 "metaData
"、"responseInfo
" 和 "status
" 的值,并询问 SwiftyJSON 的 intValue
- 你会得到正确的数字(200)或 0,如果这些值都不存在。就像这样:
swift
if json["metadata"]["responseInfo"]["status"].intValue == 200 {
// we're OK to parse!
}
如何使用 SwiftyJSON 解析 JSON @Mark, 20180117
How to parse JSON with SwiftyJson
使用 JSON 作为客户端和服务器之间的通信媒介是很常见的。然而,Swift 并没有提供一种友好的编码方式来将 JSON 转换为自定义对象。
让我们以下面这个 JSON 为例。
这个例子有 String
、Dictionary
、Int
、Bool
和 Array
类型:
swift
{
"name": "joe",
"birthday" : {
"year": 1990,
"month": 1,
"day": 1
},
"isActive": true,
"contacts": [
{
"type": "email",
"value": "joe@test.com"
},
{
"type": "phone",
"value": "123456"
}
]
}
如果我们需要从上述 JSON 中获取所有的值,我们需要使用 JSONerialization
来转换值:
swift
if let userDict = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] {
if let name = userDict["name"] as? String {
// get name
}
if let birthdayDict = userDict["birthday"] as? [String: Any] {
if let year = birthdayDict["year"] as? Int {
// get the birthday year
}
// get birthday month and day
}
if let isActive = userDict["isActive"] as? Bool {
// get isActive
}
if let contactArr = userDict["contacts"] as? [[String: Any]] {
for contactDict in contactArr {
if let type = contactDict["type"] as? String {
// get contact type
}
if let value = contactDict["value"] as? String {
// get contact type
}
}
}
}
如果 user.json
比较长,比较复杂,那么代码就比较长,读起来就比较困难。那么,我们是否有一个简单的方法来做到这一点?
是的,我们可以使用 SwiftyJSON
,这是一个 Swift 框架,它有助于简化代码,提高可读性)。
github.com/SwiftyJSON/... (支持 CocoaPods 或 Carthage 或 Swift Package Manager)
导入该库后,你可以这样写代码:
swift
import SwiftyJson
let userJson = JSON(data: dataFromNetworking)
if let name = userJson["name"].string {
// get name
}
if let year = userJson["birthday"]["year"].number,
let month = userJson["birthday"]["month"].number,
let day = userJson["birthday"]["day"].number {
// get birthday year, month, day
}
if let isActive = userJson["isActive"].bool {
// get isActive
}
if let contactArr = userJson["contacts"].array {
for contactDict in contactArr {
if let type = contactDict["type"].string {
// get type
}
if let value = contactDict["value"].string {
// get value
}
}
}
使用 SwiftyJSON
后有 3 个主要的改进:
- 使用
.string
.number
.bool
来获取数值(注:这里得到的是可选类型值),而不是使用as? <type>
将 JSON 中默认的Any
类型转换为你想要的类型。 - 它可以直接获取
dictionary
对象的值,birthdayDict ["birthday"]["year"]
- 增加了可读性,并在需要时容易添加 / 删除一个参数
如果你想在使用前检查所有的值,你可以使用 guard let
:
swift
import SwiftyJson
let userJson = JSON(data: dataFromNetworking)
guard let name = userJson["name"].string else { .. }
guard let year = userJson["birthday"]["year"].number else { .. }
guard let month = userJson["birthday"]["month"].number else { .. }
guard let day = userJson["birthday"]["day"].number else { .. }
guard let isActive = userJson["isActive"].bool else { .. }
guard let contactArr = userJson["contacts"].array else { .. }
// use the value
如果你喜欢这个内容,请喜欢这个帖子。 :)
SwiftyJSON 对应的 JSON 转换为对象 @20191022
iOS SwiftyJSON 对应的JSON 转化为 对象 - 腾讯云开发者社区-腾讯云
swiftyJSON与对象Model的转换 - Sprite is learning
SwiftyJSON: How To Parse JSON with Swift
JSONMappable - Simplify JSON mapping into objects with SwiftyJSON