【问题标题】:Using same class/model for networking and local apis对网络和本地 API 使用相同的类/模型
【发布时间】:2017-12-13 01:52:38
【问题描述】:

当我创建网络请求时,我使用新的 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
}

这对于网络来说非常有用,但是我开始使用领域来创建本地数据库。对于数据库中的每个表,我必须创建一个类模型,所以如果我想创建一个用户表,我必须创建一个包含以下字段的领域类:idusernameemail。那么这是否意味着我将不得不使用用于管理用户的类?我觉得有一种不同的做事方式

【问题讨论】:

    标签: swift realm swift4


    【解决方案1】:

    领域模型类可以符合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)!)
    

    【讨论】:

    • 不知道,感谢您的回答,我还想知道这是否也适用于领域子类化,例如,如果我添加:let dogs = List&lt;Dog&gt;() 其中狗是Dog 的子类。那还能用吗?
    • @NaderBesada Realm 的 List 不符合 Codable 开箱即用,因此您需要采用解决方法来使其工作,如 this 问答中所述跨度>
    • @NaderBesada 我还更新了我的答案,举了一个例子,说明如何在你的User 课堂上实现这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2014-12-05
    • 2021-07-26
    • 2017-05-26
    相关资源
    最近更新 更多