Firebase Swift 3 Xcode 8 - 遍历观察结果 [英] Firebase Swift 3 Xcode 8 - iterate through observe results

查看:112
本文介绍了Firebase Swift 3 Xcode 8 - 遍历观察结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经浏览了Firebase上的文档以及Stack Overflow和YouTube教程,但是如果通过Firebase获取数据,我可以了解如何获取数据。

我是Firebase的新手,正在将我的项目从Parse切换到Firebase。


$ b 示例:我在Firebase中有一个如下所示的数据:





我可以在Swift中抓住所有主题:

  let refDB = FIRDatabase.database ().reference(fromURL:firebaseDB_URL)
let topicsRef = refDB.child(topics)
// FIRDataSnapshot。
topicsRef.observe(.value,其中:$快照在
中为child.children中的孩子{
print(child ------)
print(child )
//获取位数我该如何分配每一个

$ b $)
$ / code>

在遍历for循环时,我打印如下所示的内容:

  child ------ 
Snap(-KYCqk2_AVkUd8s9cKit){
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description =用他们的首都匹配状态;
name =State Caiptals;
tags = {
0 =地理;
1 =美国;
};
}

child ------
Snap(-KYCqk2_AVkUd8s9cKiu){
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description =命名Atom的部分;
name =Antom的部分;
tags = {
0 = Physics;
1 = Atom;
2 =电子;
};
}

我的问题是,如何获取数据:



我需要密钥(KYCqk2_AVkUd8s9cKiu)
我需要描述和名称
我需要一个标签数组

- 全部在局部变量中?



基本上,我只想读入所有 Topics 和在本地内存中有一个 Topics 的数组。



我可以关心构建Class主题的数组,我已经尝试了几种方法来获取数据,没有运气。必须有一个简单的方法来解析结果,但我还没有找到一个例子或文档。

希望得到一些帮助或指向某些文档或教程。 p>

=================================



更新代码



您好,我更改了代码以尝试匹配样本。代码现在看起来像
下面我把一个循环计数器,看看发生了什么,为什么崩溃。


FDataSnapshot未定义,因此我使用了FIRDataSnapshot。



这是现在崩溃的代码的新尝试。在下面,我展示了我的更改,使其不会崩溃 - 以及有关安全地处理标签子节点的问题。感谢指针。

  //这是获取所有主题的一种方法
let refDB = FIRDatabase .database()。reference(fromURL:firebaseDB_URL)
let topicsRef = refDB.child(topics)
// FIRDataSnapshot。
topicsRef.observe(.value,with:{snapshot in
$ b $ if snapshot.value is NSNull {
print(not found)
} else {$

print()
print(b $ b var loopCount = 1 //计算循环以查看可能如何循环
以获得child中的快照。 )
print(child ------ loop \(loopCount))
print(child)

let snap = child as!FIRDataSnapshot // each child是一个快照
let dict = snap.value as![String:String] //这个值是一个字典
let name = dict [name]!
let description = dict [description]!
let createdBy = dict [createdBy]!
print(bits ------)
print(name .... \\ \\(name))
print(description .... \(description))
print(createdBy .... \(createdBy))
loopCount + = 1

}
}
})

我定义了零个断点 - 但是这个断点停止了代码(当我有零断点定义的时候)

  libswiftCore.dylib`_swift_bridgeNonVerbatimFromObjectiveC:
0x1144a4270< + 0> ;: pushq%rbp
0x1144a4271< + 1> ;: movq%rsp,%rbp
0x1144a4274< + 4>:pushq %r15

...这里打破了三次,然后应用程序崩溃在这一行
让dict = snap.value为! [字符串:字符串]
与消息线程1:EXC_BAD_INSTRUCTION(code = EXEC_1386_INVOP,subside = 0x0)

我不知道为什么代码有断点为什么它崩溃呢?也许碰撞时点击标签,因为标签是子节点,不适合[字符串,字符串]

我打印在日志,然后去繁荣! !

  child ------ loop 1 
Snap(-KYI2MszjC9pK_4oIvKu){
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
描述=匹配状态与他们的首都;
名称=状态caiptals;
标签= {
0 =地理;
1 =美国;
};
}

=====



如果我把这行改为使用'Any'....那么它就可以使用

pre $ let dict = snap.value as![String:Any]

新的工作代码....

  //这是获取所有主题的一种方法
let refDB = FIRDatabase.database()。 nce(fromURL:firebaseDB_URL)
let topicsRef = refDB.child(topics)
// FIRDataSnapshot。
topicsRef.observe(.value,with:{snapshot in
$ b $ if snapshot.value is NSNull {
print(not found)
} else {$

print()
print(b $ b var loopCount = 1 //计算循环以查看可能如何循环
以获得child中的快照。 )
print(child ------ loop \(loopCount))

let snap = child as!FIRDataSnapshot //每个孩子都是快照

if snap.value!= nil {
print(key ... \(snap.key))
let dict = snap.value as![String:Any] / / value是一个字典
let name = dict [name] as!String
let description = dict [description] as!String
let createdBy = dict [createdBy ] as!String
let tags = dict [tags] as!NSArray

/ *认为我可以循环标签为!字典,但不起作用。编译但运行时崩溃。
var tagsArray = [String]()
if tags!= nil&& tags.count> 0 {
(key,value)in tags {
tagsArray.append(value)
}
} * /

//测试我们得到的...
print(bits ------)
print(name .... \(name))
print(description .... \(description))
print(createdBy .... \(createdBy))
print(tags ... \(tags)... count \(tags.count))
loopCount + = 1
} else {
print(bad snap)
}

}
$ b b))

我从doc链接中找出主题关键字通过其他的回应。谢谢。



我不确定我是否正确获取标记值。这实际上只是一个字典,我试图这样的方式,但运行时崩溃,并希望将标签投给NSArray ....所以我在代码中做到了这一点,它的工作原理,但不知道如果这是安全的,因为这不是定义为一个数组,即使它作为一个数组返回。

解决方案

给出一个示例节点

  people_foods 
-Yinasdjasjd
名称:Leroy
食物:Pizza
-Yk9j9s9soks
名称:Pete
食物:翅膀



<这个代码获取数据作为快照,并迭代它来打印人和他们的食物。

  let ref = self .myRootRef.child(byAppendingPath:people_foods)! 
$ b ref.observe(.value,其中:$快照
$ b $如果(snapshot!.value是NSNull){
print(not found)
$ else {

(快照?.children)中的孩子!{

let snap = child as!FDataSnapshot //每个孩子都是快照

让dict = snap.value as![String:String] //这个值是一个字典

let name = dict [name]
let food = dict (食物)

print(\(name)loves \(food))
}

}
})

每个孩子的父节点名也可以通过child.key找到。



一个典型的设计模式是利用一系列的类(或字典或结构等)作为tableView的数据源。你可以遍历这些子类并为每个子类创建一个类并将其附加到tableView。完成后,tableView.reloadData更新用户界面。



记住Firebase是异步的,所以不要尝试访问或使用Observe以外的数组直到其中的代码完成。


I have looked through the docs on Firebase and through Stack Overflow and YouTube tutorials, but I can find out how to get at the data if fetch through Firebase.

I am new to Firebase and an in the process of switching my project from Parse to Firebase.

Example: I have a data in Firebase that looks like this:

I can grab all of the topics in Swift doing this:

 let refDB  = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
    let topicsRef = refDB.child("topics")
    // FIRDataSnapshot.
    topicsRef.observe(.value, with: { snapshot in
        for child in snapshot.children {
            print("child ------")
            print(child)
            // Get the bits  HOW DO I PARSE EACH SET

        }
    })

When I iterate through the for-loop, I print things that look like this:

child ------
Snap (-KYCqk2_AVkUd8s9cKit) {
    createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
    description = "Match states with their capitals";
    name = "State Caiptals";
    tags =     {
        0 = Geography;
        1 = USA;
    };
}

child ------
Snap (-KYCqk2_AVkUd8s9cKiu) {
    createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
    description = "Name the parts of an Atom";
    name = "Parts of an Antom";
    tags =     {
        0 = Physics;
        1 = Atom;
        2 = Electron;
    };
}

My problem is, how do I get at the data:

I need the key (KYCqk2_AVkUd8s9cKiu) I need the description and name I need an array of tags

-- all in local variables?

Basically, I just want to read in all the Topics and have an array of Topics in local memory.

I can take care of building the array of Class topic, but I have tried several approaches to getting at the data with no luck. There must be an easy way to parse the result, but I have not found an example or documentation.

Would appreciate some help or pointer to some doc or tutorial.

=================================

Updated Code

Hi I changed code to try to match sample provided. Code now looks like below I put in a loop counter to see what is happening and why crashing.

FDataSnapshot is not defined so I used FIRDataSnapshot.

Here is new attempt at code that now crashes. Further below I show my changes to make it not crash - and a question about handing the tags subnode safely. Thanks for the pointer. I now have something that works.

// HERE is a way to get all the Topics
let refDB  = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
let topicsRef = refDB.child("topics")
// FIRDataSnapshot.
topicsRef.observe(.value, with: { snapshot in

    if snapshot.value is NSNull {
        print("not found")
    } else {
        var loopCount = 1  //  count loops to see how may time trying to loop
        for child in snapshot.children {

            print("            ")
            print("            ")
            print("child ------ loop \(loopCount)")
            print(child)

            let snap = child as! FIRDataSnapshot //each child is a snapshot
            let dict = snap.value as! [String: String] // the value is a dictionary
            let name = dict["name"]!
            let description = dict["description"]!
            let createdBy = dict["createdBy"]!
            print("the bits ------")
            print("name .... \(name)")
            print("description .... \(description)")
            print("createdBy .... \(createdBy)")
            loopCount += 1

        }
    }
})

I have zero breakpoints defined -- however the code stops on this breakpoint (when i have zero breakpoints defined for sure)

libswiftCore.dylib`_swift_bridgeNonVerbatimFromObjectiveC:
    0x1144a4270 <+0>:   pushq  %rbp
    0x1144a4271 <+1>:   movq   %rsp, %rbp
    0x1144a4274 <+4>:   pushq  %r15

... breaks here three times and then the app crashes on this line let dict = snap.value as! [String: String] with message "Thread 1: EXC_BAD_INSTRUCTION (code=EXEC_1386_INVOP, subside=0x0)

I am not sure why the code has breakpoint and why it crashes. Maybe crashed when hits tags because tags is sub node and does not fit [String, String]

I print this in the log and then go boom!!!

child ------ loop 1
Snap (-KYI2MszjC9pK_4oIvKu) {
    createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
    description = "Match states with their capitals";
    name = "State Caiptals";
    tags =     {
        0 = Geography;
        1 = USA;
    };
}

=====

If I change the line to use 'Any' .... then it works

let dict = snap.value as! [String: Any]

new working code ....

// HERE is a way to get all the Topics
let refDB  = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
let topicsRef = refDB.child("topics")
// FIRDataSnapshot.
topicsRef.observe(.value, with: { snapshot in

    if snapshot.value is NSNull {
        print("not found")
    } else {
        var loopCount = 1  //  count loops to see how may time trying to loop
        for child in snapshot.children {

            print("            ")
            print("            ")
            print("child ------ loop \(loopCount)")

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

            if snap.value != nil {
                print("key ... \(snap.key)")
                let dict = snap.value as! [String: Any] // the value is a dictionary
                let name = dict["name"] as! String
                let description = dict["description"] as! String
                let createdBy = dict["createdBy"] as! String
                let tags = dict["tags"] as! NSArray  

                /* Thought I could loop tags as! Dictionary but that does not work. Compiles but runtime crashes.
                var tagsArray = [String]()
                if tags != nil && tags.count > 0 {
                    for (key, value) in tags {
                        tagsArray.append(value)
                    }
                } */

                // Test to see what we got ...
                print("the bits ------")
                print("name .... \(name)")
                print("description .... \(description)")
                print("createdBy .... \(createdBy)")
                print("tags ... \(tags)  ... count \(tags.count)")
                loopCount += 1
            } else {
                print("bad snap")
            }

        }
    }
})

I figured out the topic key from the doc link sent by other response. Thanks.

I am not sure I am getting the tag values correctly. It is really just a Dictionary and I tried to cast it that way but runtime crashes and wants to cast tags to an NSArray .... so I did that in the code and it works but not sure if that is safe since this is not defined as an array even though it is coming back as an array.

解决方案

It's all about dictionaries really.

Given an example node

people_foods
  -Yinasdjasjd
     name: "Leroy"
     food: "Pizza"
  -Yk9j9s9soks
     name: "Pete"
     food: "Wings"

This code gets the data as a snapshot and iterates over it to print the person and their food.

    let ref = self.myRootRef.child(byAppendingPath: "people_foods")!

    ref.observe(.value, with: { snapshot in

        if ( snapshot!.value is NSNull ) {
            print("not found")
        } else {

            for child in (snapshot?.children)! {

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

                let dict = snap.value as! [String: String] // the value is a dict

                let name = dict["name"]
                let food = dict["food"]

                print("\(name) loves \(food)")
            }

        }
    })

The parent node name(s) of each child can be found with child.key as well.

A typical design pattern is to leverage an array of classes (or dicts or structs etc) as the dataSource for a tableView. You would iterate over the children and creates a class for each one and append that to the tableView. When complete, tableView.reloadData to update the UI.

It's also important to remember that Firebase is asynchronous so don't try to access or work with that array outside the Observe closure until the code in it completes.

这篇关于Firebase Swift 3 Xcode 8 - 遍历观察结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆