Swift Firebase-如何通过嵌入式结构读取此地图?
我正在从Firestore读取数据,以便能够填充到扩展的tableview单元格中。我有一个非常简单的结构:Swift Firebase-如何通过嵌入式结构读取此地图?,swift,firebase,uitableview,google-cloud-firestore,Swift,Firebase,Uitableview,Google Cloud Firestore,我正在从Firestore读取数据,以便能够填充到扩展的tableview单元格中。我有一个非常简单的结构: protocol PlanSerializable { init?(dictionary:[String:Any]) } struct Plan{ var menuItemName: String var menuItemQuantity: Int var menuItemPrice: Double var dictionary: [Strin
protocol PlanSerializable {
init?(dictionary:[String:Any])
}
struct Plan{
var menuItemName: String
var menuItemQuantity: Int
var menuItemPrice: Double
var dictionary: [String: Any] {
return [
"menuItemName": menuItemName,
"menuItemQuantity": menuItemQuantity,
"menuItemPrice": menuItemPrice
]
}
}
extension Plan : PlanSerializable {
init?(dictionary: [String : Any]) {
guard let menuItemName = dictionary["menuItemName"] as? String,
let menuItemQuantity = dictionary["menuItemQuantity"] as? Int,
let menuItemPrice = dictionary["menuItemPrice"] as? Double
else { return nil }
self.init(menuItemName: menuItemName, menuItemQuantity: menuItemQuantity, menuItemPrice: menuItemPrice)
}
}
这是嵌入在这个结构中的:
protocol ComplainSerializable {
init?(dictionary:[String:Any])
}
struct Complain{
var status: Bool
var header: String
var message: String
var timeStamp: Timestamp
var email: String
var planDetails: Plan
var dictionary: [String: Any] {
return [
"status": status,
"E-mail": header,
"Message": message,
"Time_Stamp": timeStamp,
"User_Email": email,
"planDetails": planDetails
]
}
}
extension Complain : ComplainSerializable {
init?(dictionary: [String : Any]) {
guard let status = dictionary["status"] as? Bool,
let header = dictionary["E-mail"] as? String,
let message = dictionary["Message"] as? String,
let timeStamp = dictionary["Time_Stamp"] as? Timestamp,
let email = dictionary["User_Email"] as? String,
let planDetails = dictionary["planDetails"] as? Plan
else { return nil }
self.init(status: status, header: header, message: message, timeStamp: timeStamp, email: email, planDetails: planDetails)
}
}
但是,我无法从Firestore查询任何如下数据:
这是我的查询,尽管我正在读取所有文件:
let db = Firestore.firestore()
var messageArray = [Complain]()
func loadMenu() {
db.collection("Feedback_Message").getDocuments() { documentSnapshot, error in
if let error = error {
print("error:\(error.localizedDescription)")
} else {
self.messageArray = documentSnapshot!.documents.compactMap({Complain(dictionary: $0.data())})
for plan in self.messageArray {
print("\(plan.email)")
}
DispatchQueue.main.async {
self.testTable.reloadData()
}
}
}
}
我做错了什么?
编辑:
根据建议,以下是更新的嵌入式结构:
import Foundation
// MARK: - Complain
struct Complain: Codable {
let eMail, message, timeStamp, userEmail: String
let status: Bool
let planDetails: PlanDetails
enum CodingKeys: String, CodingKey {
case eMail = "E-mail"
case message = "Message"
case timeStamp = "Time_Stamp"
case userEmail = "User_Email"
case status, planDetails
}
}
// MARK: - PlanDetails
struct PlanDetails: Codable {
let menuItemName: String
let menuItemQuantity: Int
let menuItemPrice: Double
}
使用quicktype.io,可以生成结构。从这里开始,您所需要做的就是在响应处理程序中运行这段代码
var compainArray = [Complain]()
func loadMenu() {
db.collection("Feedback_Message").getDocuments() { documentSnapshot, error in
if let error = error {
print("error:\(error.localizedDescription)")
} else {
guard let snapshot = documentSnapshot else {return}
for document in snapshot.documents {
if let jsonData = try? JSONSerialization.data(withJSONObject: document.data()){
if let converted = try? JSONDecoder().decode(Complain.self, from: jsonData){
self.compainArray.append(converted)
}
}
}
DispatchQueue.main.async {
self.testTable.reloadData()
}
}
}
}
它将处理某些变量的循环和映射。如果你对此有任何问题,请告诉我 看看如何使用。将为您生成结构。此外,您不会循环查看计划详细信息,也不会访问其第一个元素,因此响应为空。如果将字典应用于整个快照,我将如何循环查看映射?我现在是否必须循环浏览快照中的每个文档,并在每个循环中循环浏览所有映射?请查看quicktype.io并告诉我您的操作过程?使用Decodables将消除很多麻烦。我按照建议更新了结构。由于没有字典,我将不得不循环浏览快照(这很好),但如何循环浏览映射(我完全被它弄糊涂了)。我生成了结构(它位于原始文章的底部)。AppDelegate中出现错误:“JSON写入(FIRQueryDocumentSnapshot)中的类型无效”。此时我不确定结构或响应处理程序是否有问题。@BVB09我已更新为代码,很抱歉之前不清楚。无需使用JSON序列化从Firestore快照获取数据。快照属性是一个
QuerySnapshot
,文档属性是一个FIRDocumentSnapshot
数组。您所需要做的就是迭代数组并使用内置的get()
方法,该方法专门用于避免使用JSON序列化。前几天我为OP回答了这个问题,但看起来他又回到了老习惯。嗨,bsod,很抱歉你在另一个帖子中提供了正确的答案。我应该澄清一下,结构本身并没有在我用来填充表的主数组中创建映射数组。