如何在使用Realm时实现Codable

A.s*_*ALI 8 realm ios alamofire swift4 codable

Hy我正在研究使用Realm和Alamofire的应用程序.我很高兴在我的iOS项目中使用这些库.

但后来我必须发布一个包含多个模型列表的模型列表.所以这是太深的东西,我的意思是List里面的List包含模型,那些模型包含几个模型的列表

为了演示,我们举一个我的模型的例子

@objcMembers public class MyModel : Object{
    dynamic var Id: String = ""
    dynamic var Name: String = ""
    dynamic var Favorites: List<String>? = nil 
    dynamic var Subjects: List<UserSubject>? = nil 
}


@objcMembers public class UserSubject: Object{
    dynamic var Id: String = ""
    dynamic var Name: String = ""
    dynamic var Teachers: List<Publications>? = nil 
}


@objcMembers public class Publications: Object{
    dynamic var Id: String = ""
    dynamic var Name: String = ""
    dynamic var Editors: List<Editors>? = nil 
}
Run Code Online (Sandbox Code Playgroud)

所以你可以看到这些是包含另一个模型列表的列表内的模型.

由于Realm我使用List for list来创建RelationShip.

问题: 但现在当我尝试在Models/Struct上实现Codable时它真的无法识别List属性.

我真的不知道如何解决这个问题?有没有人有任何想法怎么做?

更新: 我使用的是Swift 4.0,基本的sdk是11.2

Oli*_*ver 5

在项目中遇到同样的问题并编写了这些扩展:

import Foundation
import RealmSwift

extension RealmSwift.List: Decodable where Element: Decodable {
    public convenience init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.singleValueContainer()
        let decodedElements = try container.decode([Element].self)
        self.append(objectsIn: decodedElements)
    }
}

extension RealmSwift.List: Encodable where Element: Encodable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(self.map { $0 })
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这些扩展,您可以轻松地使领域对象可编码。像这样

@objcMembers public class MyModel: Object, Codable {
    dynamic var id: String = ""
    dynamic var name: String = ""
    var favorites = List<String>()
    var subjects = List<UserSubject>()
}

@objcMembers public class UserSubject: Object, Codable {
    dynamic var id: String = ""
    dynamic var name: String = ""
    var teachers = List<Publications>()
}


@objcMembers public class Publications: Object, Codable {
    dynamic var id: String = ""
    dynamic var name: String = ""
    var editors = List<Editor>()
}

@objcMembers public class Editor: Object, Codable {

}
Run Code Online (Sandbox Code Playgroud)


小智 2

您可以使用列表的扩展

斯威夫特 4.1

extension List: Decodable  where Element: Decodable {
    public convenience init(from decoder: Decoder) throws {
    // Initialize self here so we can get type(of: self).
    self.init()
    assertTypeIsDecodable(Element.self, in: type(of: self))
    let metaType = (Element.self as Decodable.Type) // swiftlint:disable:this force_cast

    var container = try decoder.unkeyedContainer()
    while !container.isAtEnd {
        let element = try metaType.init(__from: &container)
        self.append(element as! Element) // swiftlint:disable:this force_cast
    }
  }
}

extension List: Encodable where Element: Decodable {
    public func encode(to encoder: Encoder) throws {
       assertTypeIsEncodable(Element.self, in: type(of: self))
       var container = encoder.unkeyedContainer()
       for element in self {
           // superEncoder appends an empty element and wraps an Encoder around it.
           // This is normally appropriate for encoding super, but this is really what we want to do.
           let subencoder = container.superEncoder()
           try (element as! Encodable).encode(to: subencoder) // swiftlint:disable:this force_cast
       }
   }
}
Run Code Online (Sandbox Code Playgroud)