JSON to Model, Model to JSON
- 基础功能 JSONable + JSONableMacro宏
news:
- 子类继承专用宏
JSONableSubclassMacro
changes:
- JSONable协议拆分为
KeyPathListProvider & JSONEncodeDecode
- KeyPathListProvider将原有的
static var allKeyPathList
改为func allKeyPathList()
- JSONableKeyPathObject去除了泛型,keyPath需要补全Root类型,例如
\.name
改为\XXX.name
issues:
- class继承时,混用父类keyPath和子类keyPath,导致
encodeJsonExcludedKeys
无法正确排除
changes:
ValueTypeKeyPathProvider
名称标记为废弃- macro实现去除
ExtensionMacro
协议实现
news:
- 新增自定义key宏
JSONableCustomKey
,标记于属性前面
changes & fixed:
- 修复了连续定义的属性keyPathList代码生成缺少变量,例如
var a, b, c, d: String?
news:
- 新增Date属性转化宏
JSONableDateMapper
,以支持unix时间戳(秒和毫秒)
通过简单的keyPaths遍历实现property写入
Decoding Json values to Model properties via keyPaths
use swift package manager add this git
import MyJSONable
@JSONableMacro
struct Animal_M: JSONable {
var boolVal: Bool = false
var doubleVal: Double = 0
var intVal: Int = 0
var stringVal: String = ""
var child3: [String: Any] = [:]
}
var animal = Animal2()
let json: [String: Any] = [
"boolVal": true,
"doubleVal": 3.14,
"intVal": 314,
"stringVal": "New Dog",
"child": [
"age2": 100,
"name2": "New Cow"
],
"child3": [
"age2": 22,
"name2": "New 222",
"stringList": [
"a", "b", "c",
],
],
]
animal.decodeFromJson(json: json)
let jsonString = animal.encodeToJsonString()
use @JSONableMacro
macro to auto generate allKeyPathList
function, otherwise, write this manually
must be final class
@JSONableMacro
final class ChildAnimal2: MyJSONable.JSONable {
var age2: Int = 0
var name2: String = ""
var stringList: [String]?
}
if your superclass is JSONable, use macro JSONableSubclassMacro
@JSONableMacro
class Person: JSONable {
var boolVal: Bool?
var doubleVal: Double?
var intVal: Int?
var stringVal: String?
required init() {
}
}
@JSONableSubclassMacro
class Student: Person {
var name: String?
var id: Int = 0
}
enum type from string or int
enum EnumStringAnimal: String, JSONableEnum {
case cat = "cat"
case dog = "dog"
}
enum EnumIntAnimal: Int, JSONableEnum {
case cat = 1
case dog = 2
}
Different key from json
example using key "cccc"
for property var children2
func customKeyPathList() -> [JSONableKeyPathObject] {
return [
.init(name: "cccc", keyPath: \Animal2.children2)
]
}
or simple style:
@JSONableCustomKey("cccc")
var children2: Child?
mapper JsonValue <--> ModelValue
example var birthday: Date?
func customKeyPathList() -> [JSONableKeyPathObject] {
return [
.init(name: "birthday", keyPath: \Animal2.birthday, customGet: { someDate in
return someDate?.timeIntervalSince1970
}, customSet: { someI in
if let interv = someI as? TimeInterval {
return Date(timeIntervalSince1970: interv)
}
return nil
}),
]
}
example: exclude key price
while encodeToJSON
@JSONableMacro
struct Animal_M: JSONable {
var age: Int = 0
var name: String = "Cat"
var price: String = "Value not to JSON"
func encodeJsonExcludedKeys() -> Set<AnyKeyPath> {
return [\Animal_M.price,]
}
}
example: map unixTimeStamp to Date
@JSONableMacro
struct DateTest: JSONable {
@JSONableDateMapper("date1000", mapper: .unixTimeStampMilliSecond)
var date2: Date? // with custom key "date1000"
@JSONableDateMapper("date0", mapper: .unixTimeStampSecond)
var date: Date? // with custom key "date0"
@JSONableDateMapper(mapper: .unixTimeStampSecond)
var date3: Date? // with default key "date3" depends on name
}
for other mapper, you can add extension to JSONableMapper where T == Date
extension JSONableMapper where T == Date {
public static let iso8601 = JSONableMapper<Date> { any in
// return your date
} encode: { date in
// return your value
}
}