Как смоделировать свойство словаря Swift для объекта Realm? - PullRequest
0 голосов
/ 04 апреля 2020

Как мне смоделировать свойство словаря для объекта Realm, чтобы при кодировании в JSON я мог получить это:

{
    "firstName": "John",
    "lastName": "Doe",
    "favoriteThings": {
        "car": "Audi R8",
        "fruit": "strawberries",
        "tree": "Oak"
    }
}

Я попытался создать новый объект FavoriteThings с ключами и значением свойства, которые я видел в других местах ...

public class Person: Object {
    @objc dynamic var firstName = ""
    @objc dynamic var lastName = ""
    var favoriteThings = List<FavoriteThings>()
}

Но List, естественно, дает мне массив, когда я кодирую его в JSON. Я не хочу массив. Я использую Swift Codable.

{
    "firstName": "John",
    "lastName": "Doe",
    "favoriteThings": [
    {
      "key": "fruit",
      "value": "strawberries"
    },
    {
      "key": "tree",
      "value": "Oak"
    }
    ],
}

Любые указатели оценены!

Гонсало

1 Ответ

0 голосов
/ 04 апреля 2020

Как вы знаете, списки по умолчанию кодируются в массивы json. Итак, чтобы закодировать список в словарь, вам нужно будет реализовать собственный метод кодирования, чтобы сделать именно это.

public class FavoriteThings: Object {
    @objc dynamic var key = ""
    @objc dynamic var value = ""

    convenience init(key: String, value: String) {
        self.init()
        self.key = key
        self.value = value
    }
}

public class Person: Object, Encodable {

    enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
        case favoriteThings
    }

    @objc dynamic var firstName = ""
    @objc dynamic var lastName = ""
    let favoriteThings = List<FavoriteThings>()

    convenience init(firstName: String, lastName: String, favoriteThings: [FavoriteThings]) {
        self.init()
        self.firstName = firstName
        self.lastName = lastName
        self.favoriteThings.append(objectsIn: favoriteThings)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(firstName, forKey: .firstName)
        try container.encode(lastName, forKey: .lastName)

        var favThings: [String: String] = [:]
        for thing in favoriteThings {
            favThings[thing.key] = thing.value
        }

        try container.encode(favThings, forKey: .favoriteThings)
    }
}

И использование будет таким:

func testEncode() {
    let john = Person(
        firstName: "John",
        lastName: "Doe",
        favoriteThings: [
            .init(key: "car", value: "Audi R8"),
            .init(key: "fruit", value: "strawberries"),
            .init(key: "tree", value: "Oak"),
    ])

    let encoder = JSONEncoder()
    let data = try! encoder.encode(john)
    if let string = String(data: data, encoding: .utf8) {
        print(string)
    }
}

Какие отпечатки:

{"firstName":"John","favoriteThings":{"car":"Audi R8","fruit":"strawberries","tree":"Oak"},"lastName":"Doe"}

...