Swift 中的 JSON 反序列化

发布时间:2023-08-23 16:00

图片来自:https://unsplash.com/photos/f...
本文作者:无帆

业界常用的几种方案

手动解码方案,如 Unbox(DEPRECATED)

Swift 早期普遍采用的方案,类似的还有 ObjectMapper

该方案需要使用者手动编写解码逻辑,使用成本比较高;目前已被 Swift 官方推出的 Codable 取代

示例:

struct User {
    let name: String
    let age: Int
}

extension User: Unboxable {
    init(unboxer: Unboxer) throws {
        self.name = try unboxer.unbox(key: "name")
        self.age = try unboxer.unbox(key: "age")
    }
}

阿里开源的 HandyJSON

HandyJSON 目前依赖于从 Swift Runtime 源码中推断的内存规则,直接对内存进行操作。

在使用方面,不需要繁杂的定义,不需要继承自 NSObject,声明实现了协议即可

示例:

class Model: HandyJSON {
    var userId: String = ""
    var nickname: String = ""
    
    required init() {}
}

let jsonObject: [String: Any] = [
    "userId": "1234",
    "nickname": "lilei",
] 

let model = Model.deserialize(from: object)

但是存在兼容和安全方面的问题,由于强依赖内存布局规则,Swift 大版本升级时可能会有稳定性问题。同时由于要在运行时通过反射解析数据结构,会对性能有一定影响

基于 Sourcery 的元编程方案

Sourcery 是一款 Swift 代码生成器,使用 SourceKitten 解析 Swift 源码,根据 Stencil 模版生成最终代码

可定制能力非常强,基本可以满足我们所有的需求

示例:

定义了 AutoCodable 协议,并且让需要被解析的数据类型遵循该协议

protocol AutoCodable: Codable {}

class Model: AutoCodable {
    // sourcery: key = "userID"
    var userId: String = ""
    var nickname: String = ""
    
    required init(from decoder: Decoder) throws {
        try autoDecodeModel(from: decoder)
    }
}

之后通过 Sourcery 生成代码,这个过程 Sourcery 会扫描所有代码,对实现了 AutoCodable 协议的类/结构体自动生成解析代码

// AutoCodable.generated.swift
// MARK: - Model Codable
extension Model {
    enum CodingKeys: String, CodingKey {
        case userId = "userID"
        case nickname
    }

    // sourcery:inline:Model.AutoCodable
    public func autoDecodeModel(from decoder: Decoder) throws {
        // ...
    }
}

如上所示,还可以通过代码注释(注解)来实现键值映射等自定义功能,但是需要对使用者有较强的规范要求。其次在组件化过程中需要对每个组件进行侵入/改造,内部团队可以通过工具链解决,作为跨团队通用方案可能不是太合适

Swift build-in API Codable

Swift 4.0 之后官方推出的 JSON 序列化方案,可以理解为 Unbox+Sourcery 的组合,编译器会根据数据结构定义,自动生成编解码逻辑,开发者使用特定的 Decoder/Encoder 对数据进行转化处理。

Codable 作为 Swift 官方推出的方案,使用者可以无成本的接入。不过在具体实践过程中,碰到了一些问题

  • Key 值映射不友好,例如以下情况:

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号