2017-09-14 46 views
0

我想弄清楚如何使用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

回答

3

您不能直接從您的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