如何使用 SwiftyJSON 解析 JSON

原文: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**)
        }
    }
}

这里是 arrayValuestringValue 属性在起作用:第一个属性返回 people 中的数组,如果 people 元素不存在,则返回一个空数组,第二个属性返回 peoplefirstName 属性,如果没有设置,则返回一个空字符串。因此,无论发生什么情况,这段代码都会工作,这意味着它很容易编写,运行也很安全。

有时 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 为例。

这个例子有 StringDictionaryIntBoolArray 类型:

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 个主要的改进:

  1. 使用.string .number .bool 来获取数值(注:这里得到的是可选类型值),而不是使用 as? <type> 将 JSON 中默认的 Any 类型转换为你想要的类型。
  2. 它可以直接获取 dictionary 对象的值,birthdayDict ["birthday"]["year"]
  3. 增加了可读性,并在需要时容易添加 / 删除一个参数

如果你想在使用前检查所有的值,你可以使用 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

相关推荐
djk88881 小时前
.net6.0(.net Core)读取 appsettings.json 配置文件
json·.net·.netcore
一条晒干的咸魚6 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
今天啥也没干1 天前
使用 Sparkle 实现 macOS 应用自定义更新弹窗
前端·javascript·swift
黎明晓月1 天前
PostgreSQL提取JSON格式的数据(包含提取list指定索引数据)
postgresql·json·list
yngsqq1 天前
037集——JoinEntities连接多段线polyline和圆弧arc(CAD—C#二次开发入门)
开发语言·c#·swift
_黎明1 天前
【Swift】字符串和字符
开发语言·ios·swift
心死翼未伤2 天前
python从入门到精通:pyspark实战分析
开发语言·数据结构·python·spark·json
Mephisto.java2 天前
【大数据学习 | flume】flume Sink Processors与拦截器Interceptor
大数据·sql·oracle·sqlite·json·flume
ac-er88882 天前
ThinkPHP中使用ajax接收json数据的方法
前端·ajax·json·php
RickeyBoy2 天前
基于 Swift 从零到一开发贪吃蛇游戏(四)
swift