使用 Decodable 的领域 swift 列表

Realm swift list using Decodable

我正在尝试弄清楚如何使用 Swift 4,可解码协议中的新功能解析 Realm 列表。

这是一个例子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()
    }
}

有什么问题吗?

编辑

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

每个属性(而不是token)都是Realm Object的一种,最后一个是上面的

谢谢!

您不能直接从 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
}