Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 对网络和本地API使用相同的类/模型_Swift_Realm_Swift4 - Fatal编程技术网

Swift 对网络和本地API使用相同的类/模型

Swift 对网络和本地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创建本地数据库。对于数据库中的每个表,我必

当我创建网络请求时,我使用新的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创建本地数据库。对于数据库中的每个表,我必须创建一个类模型,因此如果我想创建一个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我还用一个例子更新了我的答案,说明了如何在
用户
类中实现这一点。