CleanJSON 1.0.9

CleanJSON 1.0.9

Pircate 维护。



CleanJSON 1.0.9

  • Pircate

CleanJSON

build Version Carthage compatible SPM support License Platform codebeat badge

继承自 JSONDecoder,在标准库源码基础上做了改动,以解决 JSONDecoder 各种解析失败的问题,如键值不存在,值为 null,类型不一致。

只需将 JSONDecoder 替换为 CleanJSONDecoder。

示例

要运行示例项目,请克隆仓库,然后首先从 Example 目录运行 pod install

要求

  • iOS 9.0
  • Swift 5.2

安装

CleanJSON 可通过 CocoaPodsCarthage 使用。要安装它,只需将以下行添加到您的 Podfile 或 Cartfile 中

Podfile

pod 'CleanJSON'

Cartfile

github "Pircate/CleanJSON"

导入

import CleanJSON

使用

常规

let decoder = CleanJSONDecoder()
try decoder.decode(Model.self, from: data)

// 支持直接解析符合 JSON 规范的字典和数组
try decoder.decode(Model.self, from: ["key": value])

枚举

对于枚举类型请遵循 CaseDefaultable 协议,如果解析失败会返回默认 case

注意:枚举使用强类型解析,关联类型和数据类型不一致不会进行类型转换,会解析为默认 case

enum Enum: Int, Codable, CaseDefaultable {
    
    case case1
    case case2
    case case3
    
    static var defaultCase: Enum {
        return .case1
    }
}

自定义解码策略

可以通过 valueNotFoundDecodingStrategy 在值为 null 或类型不匹配的时候自定义解码,默认策略请看这里

struct CustomAdapter: JSONAdapter {
    
    // 由于 Swift 布尔类型不是非 0 即 true,所以默认没有提供类型转换。
    // 如果想实现 Int 转 Bool 可以自定义解码。
    func adapt(_ decoder: CleanDecoder) throws -> Bool {
        // 值为 null
        if decoder.decodeNil() {
            return false
        }
        
        if let intValue = try decoder.decodeIfPresent(Int.self) {
            // 类型不匹配,期望 Bool 类型,实际是 Int 类型
            return intValue != 0
        }
        
        return false
    }
    
    // 为避免精度丢失所以没有提供浮点型转整型
    // 可以通过下面适配器进行类型转换
    func adapt(_ decoder: CleanDecoder) throws -> Int {
        guard let doubleValue = try decoder.decodeIfPresent(Double.self) else { return 0 }
        
        return Int(doubleValue)
    }
    
    // 可选的 URL 类型解析失败的时候返回一个默认 url
    func adaptIfPresent(_ decoder: CleanDecoder) throws -> URL? {
        return URL(string: "https://google.com")
    }
}

decoder.valueNotFoundDecodingStrategy = .custom(CustomAdapter())

可以通过 JSONStringDecodingStrategy 将 JSON 格式的字符串自动转成 Codable 对象或数组

// 包含这些 key 的 JSON 字符串转成对象
decoder.jsonStringDecodingStrategy = .containsKeys([])

// 所有 JSON 字符串都转成对象
decoder.jsonStringDecodingStrategy = .all

keyDecodingStrategy 新增了一个自定义映射器,可以只映射指定 coding path 的 key

decoder.keyDecodingStrategy = .mapper([
    ["snake_case"]: "snakeCase",
    ["nested", "alpha"]: "a"
])

针对 Moya

使用 Moya.Response 自带的 map 方法进行解析,传入 CleanJSONDecoder

provider = MoyaProvider<GitHub>()
provider.request(.zen) { result in
    switch result {
    case let .success(response):
        let decoder = CleanJSONDecoder()
        let model = response.map(Model.self, using: decoder)
    case let .failure(error):
        // this means there was a network failure - either the request
        // wasn't sent (connectivity), or no response was received (server
        // timed out).  If the server responds with a 4xx or 5xx error, that
        // will be sent as a ".success"-ful response.
    }
}

针对 RxMoya

provider = MoyaProvider<GitHub>()

let decoder = CleanJSONDecoder()
provider.rx.request(.userProfile("ashfurrow"))
    .map(Model.self, using: decoder)
    .subscribe { event in
        switch event {
        case let .success(model):
            // do someting
        case let .error(error):
            print(error)
        }
    }

作者

Pircate, [email protected]

许可证

CleanJSON 采用 MIT 许可证。有关更多信息,请参阅 LICENSE 文件。