Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.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 如何编码领域';s列表<&燃气轮机;类型_Swift_Realm - Fatal编程技术网

Swift 如何编码领域';s列表<&燃气轮机;类型

Swift 如何编码领域';s列表<&燃气轮机;类型,swift,realm,Swift,Realm,我正在尝试将我的领域数据库编码为JSON。除了列表编码之外,其他一切都正常工作。所以我的问题是,您将如何编码列表?因为列表不符合可编码neighter可解码协议 现在,我正在这样做: @objcMembers class User: Object, Codable{ dynamic var name: String = "" let dogs = List<Dog>() private enum UserCodingKeys: String, Coding

我正在尝试将我的领域数据库编码为JSON。除了
列表
编码之外,其他一切都正常工作。所以我的问题是,您将如何编码
列表
?因为
列表
不符合可编码neighter可解码协议

现在,我正在这样做:

@objcMembers class User: Object, Codable{
    dynamic var name: String = ""
    let dogs = List<Dog>()


    private enum UserCodingKeys: String, CodingKey {
        case name
        case dogs
    }

    convenience init(name: String) {
        self.init()
        self.name = name
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: UserCodingKeys.self)
        try container.encode(name, forKey: .name)

    }



@objcMembers class Dog: Object, Codable{
    dynamic var name: String = ""
    dynamic var user: User? = nil

    private enum DogCodingKeys: String, CodingKey {
        case name
    }

    convenience init(name: String) {
        self.init()
        name = name
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: DogCodingKeys.self)
        try container.encode(name, forKey: .name)

    }
}

因此,问题是如何对
列表进行编码?

要使具有
列表
类型属性的领域对象模型类符合
可编码
,只需将
列表
转换为
编码(to:)
方法中的
数组
,即可自动编码

extension User: Encodable {
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.username, forKey: .username)
        let dogsArray = Array(self.dogs)
        try container.encode(dogsArray, forKey: .dogs)
    }
}
我使用的测试类(与您问题中的测试类稍有不同,但我手头上已经有了这些测试类,并且无论变量名如何,所讨论的方法都几乎相同):

输出:

{“用户名”:“约翰”,“狗”:[{“id”:2,“姓名”:“国王”},{“id”:3,“姓名”:“孔”}]}


您可以通过使
列表
符合
可编码
来求助于小型黑客:

extension List: Encodable {
    public func encode(to coder: Encoder) throws {
        // by default List is not encodable, throw an exception
        throw NSError(domain: "SomeDomain", code: -1, userInfo: nil)
    }
}

// let's ask it to nicely encode when Element is Encodable
extension List where Element: Encodable {
    public func encode(to coder: Encoder) throws {
        var container = coder.unkeyedContainer()
        try container.encode(contentsOf: self)
    }
}
需要两个扩展,因为不能同时添加协议一致性和
where
子句

还要注意,这种方法不提供编译时检查-例如,如果
Cat
不可编码,则
列表将在运行时引发异常,而不是一个很好的编译时错误

好处是不再需要很多样板代码:

@objcMembers class User: Object, Encodable {
    dynamic var name: String = ""
    let dogs = List<Dog>()

    convenience init(name: String) {
        self.init()
        self.name = name
    }
}

@objcMembers class Dog: Object, Encodable {
    dynamic var name: String = ""
    dynamic var user: User? = nil

    convenience init(name: String) {
        self.init()
        name = name
    }
}
@objcMembers类用户:对象,可编码{
动态变量名称:String=“”
让狗进来
便利初始化(名称:字符串){
self.init()
self.name=名称
}
}
@对象类狗:对象,可编码{
动态变量名称:String=“”
动态变量用户:用户?=nil
便利初始化(名称:字符串){
self.init()
name=name
}
}

这也是可伸缩的,因为添加新类不需要任何编码代码,但有一个缺点,就是在编译时不完全是类型安全的。

可能是重复的。如果需要,您可以用类似的方式实现
可解码的
。您的答案是关于解码而不是编码。我得给我的东西编码,解码很好。问题是我不知道如何对列表进行编码。这正是我想要的。非常感谢你!我不知道为什么我没有得出相同的想法:D它也不应该影响很多性能。
let userJSON = """
{
    "id":1,
    "username":"John",
    "email":"example@ex.com",
    "dogs":[
        {"id":2,"name":"King"},
        {"id":3,"name":"Kong"}
    ]
}
"""

do {
    let decodedUser = try JSONDecoder().decode(User.self, from: userJSON.data(using: .utf8)!)
    let encodedUser = try JSONEncoder().encode(decodedUser)
    print(String(data: encodedUser, encoding: .utf8)!)
} catch {
    print(error)
}
extension List: Encodable {
    public func encode(to coder: Encoder) throws {
        // by default List is not encodable, throw an exception
        throw NSError(domain: "SomeDomain", code: -1, userInfo: nil)
    }
}

// let's ask it to nicely encode when Element is Encodable
extension List where Element: Encodable {
    public func encode(to coder: Encoder) throws {
        var container = coder.unkeyedContainer()
        try container.encode(contentsOf: self)
    }
}
@objcMembers class User: Object, Encodable {
    dynamic var name: String = ""
    let dogs = List<Dog>()

    convenience init(name: String) {
        self.init()
        self.name = name
    }
}

@objcMembers class Dog: Object, Encodable {
    dynamic var name: String = ""
    dynamic var user: User? = nil

    convenience init(name: String) {
        self.init()
        name = name
    }
}