当我创建网络请求时,我使用新的Swift 4
let user = try JSONDecoder().decode(UserCodable.self, from: data)
这将我的api模型变成了一个我可以使用的快速模型。这非常有效:
struct User: Codable {
let id: Int
let username: String
let email: String
}
这非常适合网络,但我开始使用realm来创建本地数据库。对于数据库中的每个表,我必须创建一个类模型,因此如果我想创建一个Users表,我必须创建一个包含以下字段的域类:id
,username
和{{1} }。那么这是否意味着我将要用于管理用户的类?我觉得有不同的做事方式
答案 0 :(得分:1)
Realm模型类可以符合Codable
,因此不需要两种不同的类型。
您只需要将User
转换为某个类,让它继承自Object
,让Realm
知道它是一个Realm模型类并标记所有属性@objc dynamic
使它们成为托管属性。
class User: Object, Codable {
@objc dynamic var id:Int = 0
@objc dynamic var username:String = ""
@objc dynamic var email:String = ""
}
List
不符合Decodable
开箱即用,所以要创建一个类Decodable
即使它有多对多的关系,你也需要实现一个自定义init(from decoder:)
方法。
let userJSON = """
{
"id":1,
"username":"John",
"email":"example@ex.com",
"dogs":[
{"id":2,"name":"King"},
{"id":3,"name":"Kong"}
]
}
"""
class Dog: Object,Codable {
@objc dynamic var id:Int = 0
@objc dynamic var name:String = ""
}
class User: Object, Decodable {
@objc dynamic var id:Int = 0
@objc dynamic var username:String = ""
@objc dynamic var email:String = ""
let dogs = List<Dog>()
private enum CodingKeys: String, CodingKey {
case id, username, email, dogs
}
required convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
username = try container.decode(String.self, forKey: .username)
email = try container.decode(String.self, forKey: .email)
let dogsArray = try container.decode([Dog].self, forKey: .dogs)
dogs.append(objectsIn: dogsArray)
}
}
let decodedUser = try? JSONDecoder().decode(User.self, from: userJSON.data(using: .utf8)!)