SwiftyJSON 处理Swift中JSON数据的佼佼者
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的SwiftyJSON 使得在 Swift 中处理 JSON 数据变得很容易。
为什么 Swift 中典型的 JSON 处理不好?
Swift 对类型非常严格。但是,虽然显式类型有助于我们避免错误,但在处理 JSON 和其他本质上隐含类型的领域时,它会变得很痛苦。
以 Twitter API 为例。假设我们想在 Swift 中检索用户的某些推文的“名称”值(根据Twitter 的 API)。代码如下所示:
if let statusesArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], let user = statusesArray[0]["user"] as? [String: Any], let username = user["name"] as? String { // Finally we got the username }即使我们使用可选链,它也会很混乱:
if let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], let username = (JSONObject[0]["user"] as? [String: Any])?["name"] as? String { // Theres our username }对于一些应该很简单的东西而看起来非常混乱。
使用 SwiftyJSON,您所要做的就是:
let json = JSON(data: dataFromNetworking) if let userName = json[0]["user"]["name"].string { //Now you got your value }不要担心可选包装的事情,它会自动为您完成。
let json = JSON(data: dataFromNetworking) let result = json[999999]["wrong_key"]["wrong_name"] if let userName = result.string { //Calm down, take it easy, the ".string" property still produces the correct Optional String type with safety } else { //Print the error print(result.error) }工具要求
iOS 8.0+ | macOS 10.10+ | tvOS 9.0+ | watchOS 2.0+Xcode 8使用
CocoaPods (iOS 8+, OS X 10.9+)
您可以使用CocoaPods来安装,方法SwiftyJSON是将其添加到您的Podfile:
platform :ios, 8.0 use_frameworks! target MyApp do pod SwiftyJSON, ~> 4.0 endCarthage (iOS 8+, OS X 10.9+)
您可以通过将CarthageSwiftyJSON添加到您的Cartfile:
github "SwiftyJSON/SwiftyJSON" ~> 4.0如果您使用 Carthage 构建依赖项,请确保您已添加SwiftyJSON.framework到目标的“链接框架和库”部分,并将它们包含在您的 Carthage 框架复制构建阶段。
Swift 包管理器
您可以通过在文件中添加正确的描述来使用Swift 包管理器进行安装:SwiftyJSONPackage.swift
// swift-tools-version:4.0 import PackageDescription let package = Package( name: "YOUR_PROJECT_NAME", dependencies: [ .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"), ] )然后swift build在你准备好的时候。
用法
初始化
import SwiftyJSON let json = JSON(data: dataFromNetworking)或者
let json = JSON(jsonObject)再或者
if let dataFromString = jsonString.data(using: .utf8, allowLossyConversion: false) { let json = JSON(data: dataFromString) }下标
// Getting a double from a JSON Array let name = json[0].double// Getting an array of string from a JSON Array let arrayNames = json["users"].arrayValue.map {$0["name"].stringValue}// Getting a string from a JSON Dictionary let name = json["name"].stringValue// Getting a string using a path to the element let path: [JSONSubscriptType] = [1,"list",2,"name"] let name = json[path].string // Just the same let name = json[1]["list"][2]["name"].string // Alternatively let name = json[1,"list",2,"name"].string// With a hard way let name = json[].string// With a custom way let keys:[JSONSubscriptType] = [1,"list",2,"name"] let name = json[keys].string错误
SwiftyJSON 4.x
SwiftyJSON 4.x 引入了一个名为 的枚举类型SwiftyJSONError,其中包括unsupportedType, indexOutOfBounds, elementTooDeep, wrongType,notExist和invalidJSON,同时ErrorDomain被
SwiftyJSONError.errorDomain. 注意:这些旧的错误类型在 SwiftyJSON 4.x 中已弃用,并将在未来的版本中删除。SwiftyJSON 3.x
使用下标获取/设置数组或字典中的值
如果 JSON 是:
一个数组,应用程序可能会因“索引越界”而崩溃。一本字典,它会被nil无缘无故地分配给它。不是数组或字典,应用程序可能会因“无法识别的选择器”异常而崩溃。这在 SwiftyJSON 中永远不会发生。
let json = JSON(["name", "age"]) if let name = json[999].string { // Do something you want } else { print(json[999].error!) // "Array[999] is out of bounds" }let json = JSON(["name":"Jack", "age": 25]) if let name = json["address"].string { // Do something you want } else { print(json["address"].error!) // "Dictionary["address"] does not exist" }let json = JSON(12345) if let age = json[0].string { // Do something you want } else { print(json[0]) // "Array[0] failure, It is not an array" print(json[0].error!) // "Array[0] failure, It is not an array" } if let name = json["name"].string { // Do something you want } else { print(json["name"]) // "Dictionary[\"name"] failure, It is not an dictionary" print(json["name"].error!) // "Dictionary[\"name"] failure, It is not an dictionary" }合并
可以将一个 JSON 合并到另一个 JSON。将一个 JSON 合并到另一个 JSON 中会将所有不存在的值添加到仅存在于otherJSON 中的原始 JSON 中。
如果两个 JSON 包含相同键的值,则该值通常会在原始 JSON 中被覆盖,但在两种情况下它提供了一些特殊处理:
如果两个值都是JSON.Type.array在otherJSON 中找到的数组的值,则会附加到原始 JSON 的数组值。如果两个值都是一个,那么JSON.Type.dictionary两个 JSON 值将被合并,封装 JSON 的合并方式相同。在 JSON 中的两个字段具有不同类型的情况下,该值将始终被覆盖。
有两种不同的合并方式:merge修改原始 JSON,而merged在副本上非破坏性地工作。
let original: JSON = [ "first_name": "John", "age": 20, "skills": ["Coding", "Reading"], "address": [ "street": "Front St", "zip": "12345", ] ] let update: JSON = [ "last_name": "Doe", "age": 21, "skills": ["Writing"], "address": [ "zip": "12342", "city": "New York City" ] ] let updated = original.merge(with: update) // [ // "first_name": "John", // "last_name": "Doe", // "age": 21, // "skills": ["Coding", "Reading", "Writing"], // "address": [ // "street": "Front St", // "zip": "12342", // "city": "New York City" // ] // ]字符串表示
有两种选择:
使用默认的 Swift 之一使用可以很好地处理选项并表示nil为的自定义选项"null":let dict = ["1":2, "2":"two", "3": nil] as [String: Any?] let json = JSON(dict) let representation = json.rawString(options: [.castNilToNSNull: true]) // representation is "{\"1\":2,\"2\":\"two\",\"3\":null}", which represents {"1":2,"2":"two","3":null}—END—
开源协议:MIT license
开源地址:
https://github.com/SwiftyJSON/SwiftyJSON我告诉你msdn版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!