【问题标题】:How to access & get nested values from IOS Swift 'Any' type?如何从 IOS Swift 'Any' 类型访问和获取嵌套值?
【发布时间】:2019-02-03 08:41:21
【问题描述】:

我正在尝试使用 Struct 从 Firestore 读取 Dictionary[Any] 类型。我可以将值加载到任何类型的变量“数据”字典中。 但是我不能通过它循环访问正常的嵌套字典变量。 我无法打印键值。

以下是我的代码:

    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))
        }

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

【问题讨论】:

  • 不相关但类sharedManager in struct Static in class PullQuestions 是荒谬的,Swift 1 遗留。将行static let instance = PullQuestions() 放入PullQuestions 并删除整个sharedManager 类
  • Vadian,感谢您的指出..我从一个聪明的老人那里得到了这个代码 sn-p..所以他做了他的工作..如果我按照你的建议声明实例,我会怎么样可以在 PullQuestions 的另一个类中使用它吗?
  • 只要PullQuestions.instance。
  • 按照您的建议进行了更改.. 像以前一样工作.. 非常感谢 Vedian..

标签: ios swift dictionary


【解决方案1】:

首先,考虑使用 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,如果您愿意),但我不建议这样做,因为如果元素为 nil 或任何其他类型,它(可能)会使您的应用程序崩溃。

【讨论】:

  • 非常感谢您的回复..我一个月前才开始开发IOS应用..我一定会遵循编码标准..你能告诉我如何从“元素” ?例如,我想从元素中获取变量“问题”..
  • 我可以访问元素中的每个结构.. for element in PullQuestions.sharedManager.data { if let element = element as? PullQuestions.questionid { print("数据中的问题元素:=>", (element.questions)) print("数据中的答案元素:=>", (element.answers)) } else { print("元素不是questionid ") } 如何从问题或答案结构中打印特定变量?
  • element 是questionid 结构的一个实例。因此,您可以像这样使用点符号语法:element.qid 或 element.questions。这同样适用于questions。它是basequestion 实例的数组,因此您也可以使用不符号来访问它的任何属性。这看起来像element.questions[index_of_desired_question].category
  • 像 Charm 一样工作......非常感谢 Yury.. 我的应用程序快完成了 :) 并且学习也很棒......
猜你喜欢
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多