在Swift 3中使用Firebase访问嵌套数据

时间:2016-12-27 06:05:51

标签: ios swift firebase firebase-realtime-database nsdictionary

在Swift 3中从Firebase加载嵌套数据时遇到问题。

经过6个小时的挣扎和阅读我能找到的任何东西,我仍然没有解决方案。我的数据库如下所示:

firebase data

数据是一堆问题,每个问题都有一个或多个答案。我可以获得基本的问题数据,但无法访问答案数据。

在下面的代码中,您可以看到我如何获取基本问题数据。当我拿到问题时,我被困在如何访问我手头的答案集中。我试图避免另一个数据库查找来获取答案,因为我在获取问题时得到它们。我在代码中显示了我厌倦了什么以及它是如何失败的(编译或运行时)。无法了解如何获取我手头的数据以获取答案

以下是调试的打印结果。您可以看到,在两次尝试中我成功获取了密钥(我需要)并且我成功获得了一个看起来像字典的值,但我无法将其用作字典。

------------------
Attempt #1
------------------
answer (-KZwfXU9inu4ozSjVBwS, {
    isCorrect = 1;
    text = "sample text data";
})
------------------
key .... -KZwfXU9inu4ozSjVBwS
------------------
value ....{
    isCorrect = 1;
    text = "sample text data";
}
------------------

------------------
Attempt #2
------------------
key .... -KZwfXU9inu4ozSjVBwS
------------------
value ....{
    isCorrect = 1;
    text = "sample text data";
}
------------------

代码......

    // point at the database
    let refDB  = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
    // point at Questions
    let questionsRef = refDB.child("questions")
    // filter questions to where the TopicRef is equal to the one provided
     questionsRef.queryOrdered(byChild: "topicRef").queryEqual(toValue: topicRef).observeSingleEvent(of: .value, with:  { (snapshot) in

        if snapshot.value is NSNull {
            print("load questions - none found")
        } else {
            for child in snapshot.children {

                let snap = child as! FIRDataSnapshot //each child is a snapshot

                if snap.value != nil {
                    let key = snap.key

                    // Skip if fail to get the dictionary
                    guard let dict = snap.value as! [String: Any]? else {
                        print("bad snapshot in load questions")
                        continue
                    }

                    // Get the basic question information
                    var text = ""
                    var imageURL = ""
                    var answers = [Answer]()

                    // make sure that we don't choke on missing data in question

                    // GET text
                    if let textx = dict["text"] as! String? {
                        text = textx
                    } else {
                        print("missing name in question \(key)")
                    }

                    // GET image URL
                    if let imageURLx = dict["url"] as! String? {
                        imageURL = imageURLx
                    } else {
                        print("no image URL in question \(key)")
                    }


                    // load the aswers
                       if let answerDict = dict["answers"] as!  NSDictionary? {
                        // Attempt #1
                        for answer in answerDict {
                            print("------------------")
                            print("Attempt #1")
                            print("------------------")
                            print("answer \(answer)")
                            let akey = answer.key
                            let avalue = answer.value
                            print("------------------")
                            print("key .... \(akey)")
                            print("------------------")
                            print("value ....\(avalue)")
                            print("------------------")

                            // Attempt 1A
                            /*  Try cast answer to Dictionary. FAILS
                                This fails to compile with "can not down cast from NSDictionary.Iterator.Element
                                to more optional type [String,: Any]"

                             if let newDict = answer as! [String: Any]? {

                             }
                            */

                            // Attempt 1B - tired to see if i could approach avalue as JSON - FAILS
                            /* This compiles - but crashes at runtime "Could not cast value of type '__NSDictionaryM' to 'NSData'"
                            do {
                                let JSON = try JSONSerialization.jsonObject( with: avalue as! Data, options:JSONSerialization.ReadingOptions(rawValue: 0))
                                print("JSON .... \(JSON)")
                            } catch let JSONError as NSError {
                                print("error")
                            } 
                            */

                            // Attempt 1C
                            // avalue looks like a dictionaty so try to use t like one
                            //  fails to compile - "type Any has no subscript members"
                            /*
                            let answerText = avalue["text"]
                            */


                            // Attempt 1D
                            /*  Since avalue looks like a Dictionary try to make it a Dictionary. FAILS
                             This fails to compile with "can not down cast from Any
                             to more optional type [String,: Any]"

                             if let newDict = avalue as! [String: Any]? {

                             }*/

                        }

                        print(" ")
                        // Attempt #2
                        for (key, value) in answerDict {

                            print("------------------")
                            print("Attempt #2")
                            print("------------------")
                            print("key .... \(key)")
                            print("------------------")
                            print("value ....\(value)")
                            print("------------------")

                            // This also fails to compile - cant downcast form Any to [String, Any]
                            /*
                            if let newDict = value as! [String: Any]? {

                            } */

                            // I likewise can not cast 'value' to anything at all.. The next bit below fails to compile with "cannot downcase from Any to more optional type NSDictionary
                            // Try to make the 'value' in to its own NSDictionay as it looks like a Dictionary
                            /*
                            if let newNSDictionary = value as! NSDictionary? {

                            }
                            */

                        }

                    }

                } else {
                    print("bad snap in trying to load questions")
                }

            }
        }
    })

我还尝试将原始dict["answers"]转换为其他内容(除了NSDictionary),但都无法在运行时编译或崩溃。 dict [" answers"]可能是一堆答案所以我需要迭代。迭代有效,但我只能获得关键和价值。我无法得到价值的内部 - 在每次迭代看起来像一个字典。在运行时,崩溃告诉我'值' for dict["answers"]想要转换为NSDictionary。我已经完成了这个,但现在当我迭代每次迭代的值时,类型为Any。我无法施展价值'迭代到我可以用来获取每个答案的数据的任何东西。

if let answerDict = dict["answers"] as!  NSDictionary? {

感谢任何指针使用我手头的值数据(在值中),并且可以在打印中看到,但无法以编程方式访问键/值对。

0 个答案:

没有答案