繁体   English   中英

如何从IOS Swift'Any'类型访问和获取嵌套值?

[英]How to access & get nested values from IOS Swift 'Any' type?

我正在尝试使用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))
        }

我只能访问密钥..我该如何获取嵌套值?

首先,考虑使用Swift代码约定(例如,您的结构以小写字母命名,但您应该以大写字母开头),这将使您的代码更具可读性。

回到您的问题。 您使用数组而不是字典(这段代码: public var data = [Any]() )。 在这里,您尝试打印值:

for  element in PullQuestions.sharedManager.data
{
    print("Elements in data:=>", (element))
}

在此上下文中, elementAny对象,因此您无法访问任何基础属性。 为此,您有两个选择:

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或任何其他类型,它(可能)可能会使您的应用程序崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM