2017-09-14 4 views
0

Ich versuche herauszufinden, wie ich Pars Realm Liste mit neuen Funktion in Swift 4, Decodable Protokoll Liste könnte.Realm Swift Liste mit Decodable

ist hier ein Beispiel 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" 
     } 
    ] 
    }] 

Und Realm-Modelle:

Person

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() 
    } 
} 

Platz

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. 
} 

Und das Ergebnis dieses JSON Parsen wäre:

[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> (

    ); 

Da wir unsere Liste sehen können, sind immer leer.

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

wird immer eine nil sein.

Auch ich bin erstreckt List von:

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

Irgendwelche Ideen, was könnte falsch sein?

EDIT

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

Jede Eigenschaft (anstelle von Token) ist ein Typ von Realm Object und die letzte ist die, von oben.

Danke!

+0

@ Matt Ja, genau. es ist 'RealmSwift.List' – Derp

+0

@matt ja, das ist ein benutzerdefinierter' Realm' Typ. [Here] (https://realm.io/docs/swift/latest/api/Classes/List.html) 's ist die Dokumentation –

+0

@matt Ich kann es nicht als Array in der Realm-Modellklasse analysieren, ich muss analysieren es als Realm-Objekt in der Lage zu sein, es in db zu speichern, ohne Redundanzen im Code zu machen; x – Derp

Antwort

3

Sie können nicht direkt von Ihrem JSON zu einer Liste wechseln. Was ist in der JSON ist ein Array. So wird diese Zeile nicht:

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

Sie haben durch Abrufen des Arrays zu starten:

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

Wie würden Sie den Array-Typ in List-Typ konvertieren? Es wird nicht gehen lassen über 'as'. Vielen Dank! Viel zur Lösung meines Problems. – Derp

+0

Ich habe keine Ahnung. Ich weiß nichts von Realm. Sie müssen die Realm-Dokumente lesen. Ich habe meinen eigenen generischen Listentyp erstellt und ihm eine Möglichkeit gegeben, dies zu tun, und ich konnte deinen JSON gut dekodieren. – matt

+0

Ich habe eine Lösung gefunden, einfach mit foreach! Noch einmal, danke! – Derp