Swift 对网络和本地API使用相同的类/模型
当我创建网络请求时,我使用新的Swift 4Swift 对网络和本地API使用相同的类/模型,swift,realm,swift4,Swift,Realm,Swift4,当我创建网络请求时,我使用新的Swift 4 let user=try JSONDecoder().decode(UserCodable.self,from:data) 这将我的api模型转变为我可以使用的swift模型。这非常有效: struct User: Codable { let id: Int let username: String let email: String } 这对于网络非常有用,但是我开始使用realm创建本地数据库。对于数据库中的每个表,我必
let user=try JSONDecoder().decode(UserCodable.self,from:data)
这将我的api模型转变为我可以使用的swift模型。这非常有效:
struct User: Codable {
let id: Int
let username: String
let email: String
}
这对于网络非常有用,但是我开始使用realm创建本地数据库。对于数据库中的每个表,我必须创建一个类模型,因此如果我想创建一个Users表,我必须创建一个包含以下字段的领域类:
id
、username
和email
。那么这是否意味着我将不得不使用用于管理用户的类?我觉得有一种不同的方法来做事情领域模型类可以符合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(来自解码器:)
方法
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)!)
let userJSON=“”
{
“id”:1,
“用户名”:“约翰”,
“电子邮件”:example@ex.com",
“狗”:[
{“id”:2,“name”:“King”},
{“id”:3,“name”:“Kong”}
]
}
"""
类狗:对象,可编码{
@objc动态变量id:Int=0
@objc动态变量名称:String=“”
}
类用户:对象,可解码{
@objc动态变量id:Int=0
@objc动态变量用户名:String=“”
@objc动态变量电子邮件:String=“”
让狗进来
私有枚举编码键:字符串,编码键{
案例id、用户名、电子邮件、狗
}
必需的便利初始化(来自解码器:解码器)抛出{
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)
}
}
让我们试试看?JSONDecoder().decode(User.self,from:userJSON.data(使用:.utf8)!)
不知道,谢谢你的回答,我还想知道这是否也适用于领域子类,例如,如果我添加:let dogs=List()
其中dogs是Dog
的子类。那还能用吗?@NaderBesada Realm的列表
不符合Codable
开箱即用,因此您需要采用一种变通方法来让它工作,如Q中所述&A@NaderBesada我还用一个例子更新了我的答案,说明了如何在用户
类中实现这一点。