为什么我正在开发使用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
}
因此您可以看到列表中的这些模型包含另一个模型列表。
由于领域,我将List用于创建RelationShip的列表。
问题:,但是现在当我尝试在Models / Struct上实现Codable时,它真的无法识别List属性。
我真的不知道该如何解决这个问题?有人知道怎么做吗?
更新: 我正在使用Swift 4.0,基本sdk是11.2
答案 0 :(得分:1)
您可以为列表使用扩展名
Swift 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
}
}
}
答案 1 :(得分:1)
尝试一下:
extension List: Decodable where Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
var container = try decoder.unkeyedContainer()
while !container.isAtEnd {
let element = try container.decode(Element.self)
self.append(element)
}
}
}
extension List: Encodable where Element: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
for element in self {
try element.encode(to: container.superEncoder())
}
}
}
答案 2 :(得分:1)
我建议您使用Unrealm。
它是一个功能强大的库,使您可以将Swift本机类型(结构,枚举,数组,字典)保存到Realm数据库中。因此,您不必再担心列表和Codable兼容性。
答案 3 :(得分:0)
在项目中遇到了相同的问题,并编写了以下扩展名:
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 })
}
}
有了这些扩展,您可以轻松地使Realm Object Codable成为可编码对象。像这样
@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 {
}