JAYSON 2.4.0

JAYSON 2.4.0

测试已测试
Lang语言 SwiftSwift
授权 MIT
Released最后发布2021 年 6 月
SPM支持 SPM

muukiimuukii 维护。



JAYSON 2.4.0

在解码 JSON 时需要处理失败的根本原因吗?

我们通常将值处理为默认值,如果无法从 JSON 中解码。 (使用默认值恢复)
但这样做可能会引起严重问题并隐藏应用程序中的实际根本原因。
使用默认值恢复不是一个坏选择,但在恢复之前了解 JSON 表示意外的形状或值是很重要的。

let json: JSON

do {
  self.id = try json.next("id").getString()
} catch {
  print(error)
  // We can know why decoding failed from error.
  // Not found "id" or "id" found but it was not `string` or something else.
  // that's why here recover the value to fill `self.id`
  self.id = "unknown"
}

JAYSON 提供了两种访问 JSON 对象的方式。

  1. 简单访问(使用动态成员查找)
let urlString: String? = json[3]?.shot?.images?.hidpi_image?.string
  1. 严格访问(使用动态成员查找)

我们可以知道错误在哪里触发。(使用 JSONError)

let id: String = try json
    .next(0)
    .next(\.id)
    .getString()

JAYSON

Build Status FOSSA Status Version License Platform Carthage compatible

严格且可扩展的 JSON 库。同时也支持 dynamicMemberLookup

要求

Swift 5+ iOS📱, watchOS⌚️, tvOS📺, macOS🖥, Linux

使用

读取JSON

轻松访问

let urlString: String? = json[3]?["shot"]?["images"]?["hidpi_image"]?.string

使用 dynamicMemberLookup

let urlString: String? = json[3]?.shot?.images?.hidpi_image?.string

严格访问 (try-catch)

如果值不存在,则抛出 JSONError
可通过 JSONError 了解失败位置

获取值 (字符串,布尔值,数字)

let id: String = try json
    .next(0)
    .next("id")
    .getString()

使用 dynamicMemberLookup

let id: String = try json
    .next(0)
    .next(\.id)
    .getString()

使用解码器获取值(自定义对象)

使用解码器可以将数据转换成自定义对象。并且可以抛出异常

let imageURL: URL = try json
    .next(0)
    .next("image")
    .next("hidpi_image")
    .get {
        URL.init(string: try $0.getString())!
    }

通用获取器

严格获取器

extension JSON {
    public func getDictionary() throws -> [String : JSON]
    public func getArray() throws -> [JSON]
    public func getNumber() throws -> NSNumber
    public func getInt() throws -> Int
    public func getInt8() throws -> Int8
    public func getInt16() throws -> Int16
    public func getInt32() throws -> Int32
    public func getInt64() throws -> Int64
    public func getUInt() throws -> UInt
    public func getUInt8() throws -> UInt8
    public func getUInt16() throws -> UInt16
    public func getUInt32() throws -> UInt32
    public func getUInt64() throws -> UInt64
    public func getString() throws -> String
    public func getBool() throws -> Bool
    public func getFloat() throws -> Float
    public func getDouble() throws -> Double
}

///
extension JSON {
    public func get<T>(_ s: (JSON) throws -> T) rethrows -> T
}

可选只读属性😁

extension JSON {
    public var dictionary: [String : Any]? { get }
    public var array: [Any]? { get }
    public var string: String? { get }
    public var number: NSNumber? { get }
    public var double: Double? { get }
    public var float: Float? { get }
    public var int: Int? { get }
    public var uInt: UInt? { get }
    public var int8: Int8? { get }
    public var uInt8: UInt8? { get }
    public var int16: Int16? { get }
    public var uInt16: UInt16? { get }
    public var int32: Int32? { get }
    public var uInt32: UInt32? { get }
    public var int64: Int64? { get }
    public var uInt64: UInt64? { get }
    public var bool: Bool? { get }
}

初始化 JSON

let jsonData: Data = ...
let json = try JSON(data: jsonData)
let jsonData: Data
let json: Any = try JSONSerialization.jsonObject(with: data, options: [])
let json = try JSON(any: json)
let userInfo: [AnyHashable: Any]
let json = try JSON(any: json)
let objects: [Any]
let json = try JSON(any: json)

在以下情况中,尝试并不需要。

let object: [String : JSON]
let json = JSON(object)
let object: [JSON]
let json = JSON(object)
let object: [JSONWritableType]
let json = JSON(object)
let object: [String : JSONWritableType]
let json = JSON(object)

获取当前路径(调试信息)

let path = try json
    .next(0)
    .next("image")
    .next("hidpi_image")
    .currentPath()

// path => "[0]["image"]["hidpi_image"]"

JSONError

如果您访问的键不存在,则抛出 JSONError

public enum JSONError: Error {
  case notFoundKey(key: String, json: JSON)
  case notFoundIndex(index: Int, json: JSON)
  case failedToGetString(source: Any, json: JSON)
  case failedToGetBool(source: Any, json: JSON)
  case failedToGetNumber(source: Any, json: JSON)
  case failedToGetArray(source: Any, json: JSON)
  case failedToGetDictionary(source: Any, json: JSON)
  case decodeError(source: Any, json: JSON, decodeError: Error)
  case invalidJSONObject
}

例子

do {
  let urlString: String = try json
    .next("shots")
    .next(0)
    .next("user")
    .next("profile_image")
    .next("foo") // ‼️ throw
    .getString()
} catch {
   print(error)
}

输出 jsonError

notFoundKey("foo",
json
Path: Root->["shots"][0]["user"]["profile_image"]
SourceType: dictionary

Source:
{
    large = "https://...";
    medium = "https://...";
    small = "https://...";
})

返回 JSON 层级

try json
    .next(0)
    .next("image")
    .back() // <---
    .next("image")
    .next("hidpi_image")

导入示例(dribbble API)

let json = try! JSON(data)

struct Shot {
    let id: Int
    let title: String
    let width: Int
    let height: Int
    let hidpiImageURLString: String?
    let normalImageURLString: String
    let teaserImageURLString: String
}

do {
    let shots: [Shot] = try json.getArray().map { json -> Shot in

        let imagesjson = try json.next("images")

        return Shot(
            id: try json.next("id").getInt(),
            title: try json.next("title").getString(),
            width: try json.next("width").getInt(),
            height: try json.next("height").getInt(),
            hidpiImageURLString: try? imagesjson.next("hidpi").getString(),
            normalImageURLString: try imagesjson.next("normal").getString(),
            teaserImageURLString: try imagesjson.next("teaser").getString()
        )
    }
    print(shots)
} catch {
    print(error)
}

写入 JSON

var json = JSON()
json["id"] = 18737649
json["active"] = true
json["name"] = "muukii"

var images = [String:JSON]()
images["large"] = "http://...foo"
images["medium"] = "http://...bar"
images["small"] = "http://...fuzz"

json["images"] = JSON(images)

let data = try json.data(options: .prettyPrinted)

-> 数据

{
  "name" : "muukii",
  "active" : true,
  "id" : 18737649,
  "images" : {
    "large" : "http:\/\/...foo",
    "small" : "http:\/\/...fuzz",
    "medium" : "http:\/\/...bar"
  }
}

JSON可转换示例

var json = JSON()

json["String"] = "String"
json["NSString"] = JSON("NSString" as NSString)
json["NSNumber"] = NSNumber(value: 0)
json["Int"] = 64
json["Int8"] = JSON(8 as Int8)
json["Int16"] = JSON(16 as Int16)
json["Int32"] = JSON(32 as Int32)
json["Int64"] = JSON(64 as Int64)

json["UInt"] = JSON(64 as UInt)
json["UInt8"] = JSON(8 as UInt8)
json["UInt16"] = JSON(16 as UInt16)
json["UInt32"] = JSON(32 as UInt32)
json["UInt64"] = JSON(64 as UInt64)

json["Bool_true"] = true
json["Bool_false"] = false

json["Float"] = JSON(1.0 / 3.0 as Float)
json["Double"] = JSON(1.0 / 3.0 as Double)
json["CGFloat"] = JSON(1.0 / 3.0 as CGFloat)

安装

通过 CocoaPods 可以获取json。要安装,只需将以下行添加到您的Podfile中。

pod "JAYSON"

作者

muukii,[email protected]

许可协议

json 在MIT许可协议下可用。有关更多信息,请参阅LICENSE文件。

FOSSA Status