一、问题
- 对于运用
HandyJson
或Codable
来解析的数据转成Realm
实例时失利!!! - 转成
Realm
实例时HandyJson
自定义映射无效!!!
二、解决方案
1. HandyJson
问题1:
let JsonString = """
{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"},{"id":16,"name":"Animation"},{"id":35,"name":"Comedy"},{"id":80,"name":"Crime"},{"id":99,"name":"Documentary"}]}
"""
class Genres: Object, HandyJSON {
@objc dynamic var id: String = ""
@objc dynamic var name: String?
override class func primaryKey() -> String? {
"id"
}
override required init() {
super.init()
}
}
let list: [Genres] = ([Genres].deserialize(from: JsonString, designatedPath: "genres") ?? []).compactMap { $0 }
list.forEach { print($0.id, $0.name) }
这儿Realm
对象的特点不可运用@Persisted
标示,应该运用@objc dynamic
标示为OC
的动态类型。运用HandyJson
有个便捷之处是解析时能够直接将id
从Int
转成String
。
问题2:
这儿有两种解决思路,直接上代码:
let JsonString = """
{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"},{"id":16,"name":"Animation"},{"id":35,"title":"Comedy"},{"id":80,"title":"Crime"},{"id":99,"title":"Documentary"}]}
"""
class Genres: Object, HandyJSON {
@objc dynamic var id: String = ""
@objc dynamic var name: String?
private var title: String?
override class func primaryKey() -> String? {
"id"
}
override required init() {
super.init()
}
/// 转换完成后赋值
func didFinishMapping() {
name = [name, title].compactMap { $0 }.first
}
}
let list: [Genres] = ([Genres].deserialize(from: JsonString, designatedPath: "genres") ?? []).compactMap { $0 }
list.forEach { print($0.id, $0.name) }
这种方法是在HandyJson
的didFinishMapping
中直接给特点赋值。再看另一种方法:
let JsonString = """
{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"},{"id":16,"name":"Animation"},{"id":35,"title":"Comedy"},{"id":80,"title":"Crime"},{"id":99,"title":"Documentary"}]}
"""
class Genres: Object, HandyJSON {
@objc dynamic var id: String = ""
@objc dynamic var name: String?
@objc private var title: String? {
willSet {
name = newValue
}
}
override class func ignoredProperties() -> [String] {
["title"]
}
override class func primaryKey() -> String? {
"id"
}
override required init() {
super.init()
}
}
let list: [Genres] = ([Genres].deserialize(from: JsonString, designatedPath: "genres") ?? []).compactMap { $0 }
list.forEach { print($0.id, $0.name) }
这儿需求留意title
特点前面加了@objc
润饰表示这是OC
特点,这样HandyJson
在对title
赋值时willSet
将被调起,咱们能够在willSet
中对name
进行赋值。假如不希望title
特点也存储到Realm
中,能够在Realm
的ignoredProperties
方法中标示。
执行代码后能够验证成果:
从Realm
的表结构能够看出,只要id
和name
,title
并不存在,其次name
的值也是完好的,这也符合咱们的预期。
2. Codable
let JsonString = """
{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"},{"id":16,"name":"Animation"},{"id":35,"name":"Comedy"},{"id":80,"name":"Crime"},{"id":99,"name":"Documentary"}]}
"""
class GenresModel: Object, Codable {
@Persisted(primaryKey: true) var id: Int
@Persisted var name: String?
override required init() {
super.init()
}
}
let list = ([GenresModel].decodeJSON(from: JsonString, designatedPath: "genres") ?? []).compactMap { $0 }
list.forEach { print($0.id, $0.name) }
这儿Realm
对象的特点能够运用@Persisted
标示。运用Codable
解析时需求留意匹配数据类型,不能够直接将id
从Int
转成String
,当然你也能够写映射方法来完成。