Swift 如何编码领域';s列表<&燃气轮机;类型
我正在尝试将我的领域数据库编码为JSON。除了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
列表
编码之外,其他一切都正常工作。所以我的问题是,您将如何编码列表
?因为列表
不符合可编码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
}
}