swift - `RLMArray` 不符合协议(protocol) 'Encodable'

标签 swift realm swift4 codable

我想做:

  • 使用 JSONDecoder(),我将 json 转换为 Realm 对象。
  • 我将此对象保存到 Realm 数据库中。

问题:

  • RLMArray 不应用 Codable 协议(protocol)。
  • 我可以遵守 Decodable 协议(protocol),但 Codable 我不能。

错误消息:

  • “Person”类型不符合“Encodable”协议(protocol)

代码:

public class Hobby: Object, Codable {
    @objc dynamic var  title: String?
    @objc dynamic var  category: String?
}
public class Person: Object, Codable { // Error: Type 'Person' does not conform to protocol 'Encodable'
    @objc dynamic var  name: String?
    @objc dynamic var  hobbies: RLMArray<Hobby>?

    required convenience public init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        hobbies = try container.decode(RLMArray<Hobby>?.self, forKey: .hobbies)
    }
}
func sample() {
    let person = try? JSONDecoder().decode(Person.self, from: "{\"name\" : \"aaa\",\"hobbies\" : [{\"title\" : \"fishing\",\"category\" : \"outdoor\"},{\"title\" : \"reading\",\"type\" : \"indoor\"}]}".data(using: .utf8)!)
    print(person)
    let realm = try! Realm()
    try! realm.write {
        realm.add(person!)
    }
}

你有什么想法吗?

swift 4 RealmSwift

最佳答案

Codable 与 Decodable + Encodable 完全相同。如果您想符合 Codable,您将需要实现编码函数,对于您的 Person 对象来说,它是:

enum CodingKeys: String, CodingKey {
        case name
        case hobbies
// or: case hobbies = "customHobbiesKey" if you want to encode to a different key
}

func encode(to encoder: Encoder) throws {
    do {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(hobbies, forKey: .hobbies)
    } catch {
        print(error)
    }
}

将其添加到您的 Person 类中,然后为您的 Hobby 类实现相同的内容。

因为我不确定您是否想要编码:如果您需要做的只是从 Json 创建 Realm 对象,我只需将“Codable”替换为“Decodable”协议(protocol)即可。

编辑:我注意到问题与 RLMArray 有关。我不确定 codable 如何与 RLMArray 一起使用,但如果它不起作用,您可以尝试将声明替换为

let hobbies = List<Hobby>()

然后在 init() 中将“爱好”行替换为:

let tempHobbyList: [Hobby] = try container.decode([Hobby].self, forKey: .hobbies)
self.hobbies.append(objectsIn: tempHobbyList)

这就是我如何让我的列表与realmObjects一起使用codable

关于swift - `RLMArray` 不符合协议(protocol) 'Encodable',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47691841/

相关文章:

objective-c - 如何检索 Cocoa API 的 Swift "header"文件?

swift - 用于获取 PassthroughSubject 发布者值的单元测试

android - 我如何在不丢失任何数据的情况下迁移 Realm - Kotlin

ios - swift : Why localization sometime need to add observer to get it work but sometime don't

swift - 从随机排列的数组中设置按钮的标题 - Swift

objective-c - 将一个常量变量从 Objective-C 暴露给 Swift

ios - 通过Swift滚动隐藏/取消隐藏UISearchBar

android - 使用 Android 在 Realm 中存储空值

ios - Realm 不正确的线程访问崩溃

swift - 更改 tableView 中单元格的 editingStyle 背景颜色和标签