我正在尝试使用Struct从Firestore读取为Dictionary [Any]类型。我可以使用Any类型将值加载到变量“数据”字典中。 但是,我无法通过它循环访问普通的嵌套Dictionary变量。 我无法获取键,无法打印值。
以下是我的代码:
class PullQuestions {
//shared instance variable
**public var data = [Any]()**
private var qdb = Firestore.firestore()
public struct questionid
{
let qid : String
var questions : [basequestion]
var answers: [baseans]
}
public struct basequestion {
let category : String
let question : String
}
public struct baseans {
let answer : String
}
class var sharedManager: PullQuestions {
struct Static {
static let instance = PullQuestions()
}
return Static.instance
}
static func getData(completion: @escaping (_ result: [Any]) -> Void) {
let rootCollection = PullQuestions.sharedManager.qdb.collection("questions")
//var data = [Any]()
rootCollection.order(by: "upvote", descending: false).getDocuments(completion: {
(querySnapshot, error) in
if error != nil {
print("Error when getting data \(String(describing: error?.localizedDescription))")
} else {
guard let topSnapshot = querySnapshot?.documents else { return }
// var questiondoc = [basequestion]()
for questioncollection in topSnapshot {
rootCollection.document(questioncollection.documentID).collection("answers").getDocuments(completion: {
(snapshot, err) in
guard let snapshot = snapshot?.documents else { return }
var answers = [baseans]()
for document in snapshot { //There should be only one Document for each answer collection
//Read thru all fields
for i in 0..<document.data().count
{
let newAns = baseans(answer: answer)
print("Answer Docs=>", (answer))
answers.append(newAns)
}
}
let qid = questioncollection.documentID
let category = questioncollection.data()["category"] as! String
let question = questioncollection.data()["question"] as! String
let newQuestions = basequestion(category: category ,question: question)
let newQuestionDict = questionid(qid: qid, questions: [newQuestions], answers: answers)
PullQuestions.sharedManager.data.append(newQuestionDict)
//Return data on completion
completion(PullQuestions.sharedManager.data)
})
}
}
})
}
}
我可以这样打印
print("Count =>", (PullQuestions.sharedManager.data.count))
// print(PullQuestions.sharedManager.data.first ?? "Nil")
print(PullQuestions.sharedManager.data[0])
for element in PullQuestions.sharedManager.data
{
print("Elements in data:=>", (element))
}
我只能访问密钥。我该如何获取嵌套值?
答案 0 :(得分:0)
首先,考虑使用Swift代码约定(例如,您的结构体以小写字母命名,但您应该以大写字母开头),这将使您的代码更具可读性。
回到您的问题。您使用数组而不是字典(这段代码:public var data = [Any]()
)。在这里,您尝试打印值:
for element in PullQuestions.sharedManager.data
{
print("Elements in data:=>", (element))
}
在这种情况下,element
是Any
对象,因此您不能访问任何基础属性。为此,您有两个选择:
1。您应该在声明中指定数组对象的类型,如下所示:
public var data = [questionid]()
或者您可以使用它:
public var data: [questionid] = []
这两个是相等的,请使用您喜欢的一个。
2。。如果出于某种原因不想在声明中指定类型,可以将其强制转换为循环。像这样:
for element in PullQuestions.sharedManager.data
{
if let element = element as? quetionid {
print("Elements in data:=>", (element))
// you can also print element.qid, element.questions, element.answers
} else {
print("Element is not questionid")
}
}
您当然可以使用强制施力:
let element = element as! questionid
并避免使用if let
语法(如果愿意,也可以避免使用guard let
),但是我不建议这样做,因为如果element为nil或任何其他类型,它(可能)会使您的应用程序崩溃。