使用可解码的领域快捷列表

使用可解码的领域快捷列表

问题描述:

我想弄清楚如何使用Swift 4中的新特性来解析领域列表,解码协议。使用可解码的领域快捷列表

这里是一个例子JSON:

[{ 
    "name": "Jack", 
    "lastName": "Sparrow", 
    "number": "1", 
    "address": [ 
     { 
      "city": "New York", 
      "street": "av. test" 
     } 
    ] 
    }, 
    { 
    "name": "Cody", 
    "lastName": "Black", 
    "number": "2" 
    }, 
    { 
    "name": "Name", 
    "lastName": "LastName", 
    "number": "4", 
    "address": [ 
     { 
      "city": "Berlin", 
      "street": "av. test2" 
     }, 
     { 
      "city": "Minsk", 
      "street": "av. test3" 
     } 
    ] 
    }] 

和领域型号:

public final class Person: Object, Decodable { 

    @objc dynamic var name = "" 
    @objc dynamic var lastName = "" 
    var address = List<Place>() 

    override public static func primaryKey() -> String? { 
     return "lastName" 
    } 

    private enum CodingKeys: String, CodingKey { case name, lastName, address} 

    convenience public init(from decoder: Decoder) throws { 
     self.init() 
     let container = try decoder.container(keyedBy: CodingKeys.self) 
     self.name = try container.decode(String.self, forKey: .name) 
     self.lastName = try container.decode(String.self, forKey: .lastName) 
     self.address = try container.decodeIfPresent(List<Place>.self, forKey: .address) ?? List() 
    } 
} 

地点

public final class Place: Object, Decodable { 

    @objc dynamic var city = "" 
    @objc dynamic var street = 0 

    override public static func primaryKey() -> String? { 
     return "street" 
    } 
// We dont need to implement coding keys becouse there is nothing optional and the model is not expanded by extra properties. 
} 

和解析此JSON会的结果:

[Person { 
    name = Jack; 
    lastName = Sparrow; 
    number = 1; 
    address = List<Place> <0x6080002496c0> (

    ); 
}, Person { 
    name = Cody; 
    lastName = Black; 
    number = 2; 
    address = List<Place> <0x6080002496c0> (

    ); 
}, Person { 
    name = Name; 
    lastName = LastName; 
    number = 4; 
    address = List<Place> <0x6080002496c0> (

    ); 

我们可以看到我们的名单总是空的。

self.address = try container.decodeIfPresent(List<Place>.self, forKey: .address) ?? List() 

将永远是nil

而且我扩展由List

extension List: Decodable { 
    public convenience init(from decoder: Decoder) throws { 
     self.init() 
    } 
} 

任何想法可能是错误的?

EDIT

struct LoginJSON: Decodable { 
    let token: String 
    let firstCustomArrayOfObjects: [FirstCustomArrayOfObjects] 
    let secondCustomArrayOfObjects: [SecondCustomArrayOfObjects] 
    let preferences: Preferences 
    let person: [Person] 
} 

每个属性(而不是令牌)是一种类型的Realm Object和最后一个是从上面的一个。

谢谢!

+0

@马特是啊,没错。它是'RealmSwift.List' – Derp

+0

@matt是的,这是一个自定义的'Realm'类型。 [Here](https://realm.io/docs/swift/latest/api/Classes/List.html)的文档 –

+0

@matt我无法将它解析为Realm模型类中的数组,我必须解析它它作为一个Realm对象,能够将其保存到数据库中,而不会在代码中进行冗余; x – Derp

您不能直接从您的JSON转到列表。 JSON中的内容是阵列。因此,这条线将不起作用:

self.address = try container.decodeIfPresent(List<Place>.self, forKey: .address) ?? List() 

你必须通过取得阵列启动:

if let arr = try container.decodeIfPresent(Array<Place>.self, forKey: .address) { 
    // arr is now an array of Place 
    self.address = // make a List from `arr`, however one does that 
} else { 
    self.address = nil 
} 
+0

如何将数组类型转换为列表类型?它不会让我通过“as”。谢谢!很多解决我的问题。 – Derp

+0

我不知道。我对Realm一无所知。你必须阅读Realm文档。我做了我自己的List泛型类型,并给它一种方法来做到这一点,我能够解码你的JSON就好了。 – matt

+0

我已经做了一个解决方案,只是用foreach!再一次,谢谢! – Derp