将[Dink]对象数组转换为json对象以保存到swift中的Firebase DB



目标:我有一个[Drink]数组,希望将它们保存到它们的posId下的Firebase RDBS中。因此Firebase保存的树结构看起来像这样:

-drinks
-----posID-1
--------name
--------description
--------unitPrice
--------tags
-----------tag1
-----------tag2

型号类别Drink

class Drink {
var posId: String?
var name: String?
var description: String?
var tags: [String]?
var unitPrice: String?
init(dictionary: [String: Any]) {

self.posId = dictionary["posId"] as? String
self.name = dictionary["name"] as? String
self.description = dictionary["description"] as? String
self.unitPrice = dictionary["unitPrice"] as? String
self.tags = dictionary["tags"] as? [String]

}//end init
}//end class

[Drink]阵列映射到Dictionary并将输出打印到控制台的功能

func loadDrinks(){
print("drinksOrder count:(drinksOrder.count)")
let drinksOrdered = Dictionary(uniqueKeysWithValues: drinksOrder.map {($0.posId, $0.self)})
print(drinksOrdered)
}//end func

输出:

[可选("0009372"(:VIP饮料,可选("000 9373"(:vipeeps。饮料,可选("0009374"(:vipips。饮料]

问题:如何将Drink对象进一步映射到Dictionary键:保存到Firebase所需的值结构

如果你需要像问题标题所说的那样将其转换为JSON,你可以使用Codable协议(或Decodable & Encodable的typealias。它使模型和JSON之间的转换非常容易。

下面是一个单元测试示例来演示这两种方法。我将它切换到一个结构,只是为了获得免费的init,使其更短,并且不需要Equatable,只是为了在第二个单元测试中进行比较而添加。

import XCTest
struct Drink: Codable, Equatable {
var posId: String?
var name: String?
var description: String?
var tags: [String]?
var unitPrice: String?
}
class CodableDrink: XCTestCase {
func testCreateJSONFromDrink() {
let drink = Drink(posId: "1", name: "Monster", description: "Nasty Energy Drink", tags: ["energy", "caffeine"], unitPrice: "$1.89")
let encoder = JSONEncoder()
let encodedData = try! encoder.encode(drink)
let jsonString = String(data: encodedData, encoding: .utf8)!
XCTAssertEqual(jsonString, """
{"tags":["energy","caffeine"],"unitPrice":"$1.89","name":"Monster","posId":"1","description":"Nasty Energy Drink"}
""")
}
func testCreateDrinkFromJSON() {
let json = """
{"tags":["energy","caffeine"],"unitPrice":"$1.89","name":"Monster","posId":"1","description":"Nasty Energy Drink"}
"""
let decoder = JSONDecoder()
let drink = try! decoder.decode(Drink.self, from: json.data(using: .utf8)!)
XCTAssertEqual(drink, Drink(posId: "1", name: "Monster", description: "Nasty Energy Drink", tags: ["energy", "caffeine"], unitPrice: "$1.89"))
}
}

这篇文档也很有帮助,它展示了如何做额外的事情,比如当你希望你的变量名和json中的密钥不同时进行处理,或者如何手动编码和解码,而不是使用自动行为。

最新更新