通过自定义的 Decoder 配合 Property wrapper 实现优雅 JSON Codable
目前 Swift 编译器存在缺陷, 当 Property wraper 使用 @escaping @autoclosure 闭包作为初始化参数时会编译出错, 9月份的 Swift Development Snapshot 已经修复这个问题, 但 Xcode 12.2 尚未包含该 patcher https://bugs.swift.org/browse/SR-13606 等到 Xcode 更新修复后我会发布本次 2.0 版本到 CocoaPods 和 Swift Package Manager
移除了基于 SourceKitten 生成代码的实现方式
, 改为编译时
加自定义的 Decoder
的方式实现, 不再需要额外配置编译脚本和引入生成文件
和原生 Codable 一样支持任意访问权限的类型
由于使用了编译器生成的init(from:)
, 所以无法支持willStartMapping()
, 只保留didFinishMapping()
调用
无法支持自动合成非 RawRepresentable 的 Enum
无法自动合成默认 CodingKeys, 如果是用 WCDB.swift 需要手写一遍了, 同时@Happy.uncoding
不再支持第三方(包括Foundation.JSONDecoder), 如果需要 “使用第三方 Codable 且使用 uncoding 的功能”, 则需要自己实现 CodingKeys 而不是使用@Happy.uncoding
由于依赖于系统生成的 CodingKeys, 为了防止岐意, @Happy.codingKeys
改名为@Happy.alterCodingKeys
代表替代coding keys, 并且始终优先解析 CodingKeys 中定义的字段避免基于 Codable 的第三方库出错(例如 WCDB.swift)
未来会进一步分离开放自定义的 Decoder 以方便接入其他数据类型的 Decoder (例如 XML, Protocol Buffers 等等)
新增了新的 Property wrapper 替代原本 JSON Codable 的参数配置, 例如 @Happy.dateStrategy
由于 decode 的时候需要 encode 一次作为默认值是用, 所以移除了 HappyEncodable, HappyCodable 需要同时实现 Decodable 和 Encodable, 为了防止使用运行时变量时 encode 的值不符合实际情况(例如 var date = Date()
), 所有@Happy.propertyWrapper 都会使用 @autoclosure 的方式记录默认值, 如果有临时需要可以使用@Happy.dynamicDefault
标示
而这些, 你全都可以用HappyCodable解决
完成后如下
target 'HappyCodableDemo' do
pod 'HappyCodable'
end
把 HappyCodable
应用到你的struct/class/enum, 比如:
import HappyCodable
struct Person: HappyCodable {
var name: String = "abc"
@Happy.alterCodingKeys("🆔")
var id: String = "abc"
@Happy.alterCodingKeys("secret_number", "age")
var age: Int = 18
@Happy.uncoding
var secret_number: String = "3.1415"
}
我之前项目是用 HandyJSON 的, 但由于 HandyJSON 是基于操作 Swift 底层数据结构实现的, 已经好几次 Swift 版本迭代后, 由于数据结构的改变 HandyJSON 都会出问题, 由于我不想手动解析模型, 促使了我写这个库, 配上足够多的测试用例总比手动安全一些
可能有人会说更新 HandyJSON 不就好了, 但是你既不能确保以后 Swift 不会更新底层数据结构后, 直接导致HandyJSON 死亡, 也不能确保你所开发的 APP 突然被迫停止开发后, 你的用户更新系统就不能用了对吧
为了迁移到 HappyCodable, HappyCodable 的 API 很大程度参考了 HandyJSON
可以, 但还是得手动实现 CodingKeys
待补充...
link |
Stars: 43 |
Last commit: 2 weeks ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics