我查看了Firebase上的文档以及Stack Overflow和YouTube教程,但是如果通过Firebase获取,我可以了解如何获取数据。
我是Firebase的新手,也是我将项目从Parse切换到Firebase的过程。
示例:我在Firebase中有一个如下所示的数据:
我可以抓住Swift中的所有主题:
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
}
})
当我遍历for循环时,我打印的内容如下:
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;
};
}
我的问题是,如何获取数据:
我需要钥匙(KYCqk2_AVkUd8s9cKiu) 我需要描述和名称 我需要一个标签数组
- 所有局部变量?
基本上,我只想阅读所有Topics
并在本地内存中有一个Topics
数组。
我可以负责构建Class主题的数组,但我已经尝试了几种方法来获取数据而没有运气。必须有一种简单的方法来解析结果,但我还没有找到示例或文档。
非常感谢某些文档或教程的帮助或指针。
=================================
您好我改变了代码以尝试匹配提供的示例。代码现在如下所示 我放入一个循环计数器,看看发生了什么以及为什么会崩溃。
未定义FDataSnapshot,因此我使用了FIRDataSnapshot。
以下是现在崩溃的代码的新尝试。在下面我展示我的更改,使其不崩溃 - 以及关于安全地处理标签子节点的问题。谢谢你的指针。我现在有一些有用的东西。
// 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
}
}
})
我定义了零断点 - 但是代码在此断点处停止(当我确定没有定义零断点时)
libswiftCore.dylib`_swift_bridgeNonVerbatimFromObjectiveC:
0x1144a4270 <+0>: pushq %rbp
0x1144a4271 <+1>: movq %rsp, %rbp
0x1144a4274 <+4>: pushq %r15
...在这里打破三次,然后应用程序在此行崩溃 让dict = snap.value为! [String:String] 消息“线程1:EXC_BAD_INSTRUCTION(代码= EXEC_1386_INVOP,subside = 0x0)
我不确定为什么代码有断点以及为什么崩溃。可能在命中标签时崩溃,因为标签是子节点并且不适合[String,String]
我在日志中打印出来然后去热潮!!!
child ------ loop 1
Snap (-KYI2MszjC9pK_4oIvKu) {
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description = "Match states with their capitals";
name = "State Caiptals";
tags = {
0 = Geography;
1 = USA;
};
}
=====
如果我更改线条使用'Any'....那么它可以正常工作
let dict = snap.value as! [String: Any]
新的工作代码......
// 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")
}
}
}
})
我从其他回复发送的doc链接中找出了主题密钥。感谢。
我不确定我是否正确获取了标记值。它实际上只是一个字典而且我试图以这种方式进行转换,但运行时崩溃并希望将标签转换为NSArray ....所以我在代码中执行了它并且它有效但不确定这是否安全,因为这不是定义为数组,即使它作为数组返回。
答案 0 :(得分:5)
这真的是关于字典的。
给出一个示例节点
people_foods
-Yinasdjasjd
name: "Leroy"
food: "Pizza"
-Yk9j9s9soks
name: "Pete"
food: "Wings"
此代码将数据作为快照获取并对其进行迭代以打印此人及其食物。
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)")
}
}
})
每个孩子的父节点名称也可以通过child.key找到。
典型的设计模式是利用类数组(或dicts或结构等)作为tableView的dataSource。您将遍历子项并为每个子项创建一个类,并将其附加到tableView。完成后,使用tableView.reloadData更新UI。
同样重要的是要记住Firebase是异步的,因此不要尝试在Observe闭包之外访问或使用该数组,直到其中的代码完成。
答案 1 :(得分:1)
FIRDataSnapshot's value property将快照的内容作为标准Foundation类型返回。
答案 2 :(得分:0)
您可以使用我的SnapshotParser轻松完成。
您需要以下代码才能获得快速表示:
func main(){
let topics=SnapshotParser().parseAsList(snap: Snapshot, type: Topic.self)
for topic in topics{
//do something with your object
}
}
class Topic: ParsableSnapshot {
var id:String?=nil
var createdBy:String?=nil
var description:String?=nil
var name:String?=nil
var tags:[Int:String]?=nil
required init(){}
func bindProperties(binder: SnapshotParser.Binder) {
binder.bindField(name: "id", field: &id)
binder.bindField(name: "createdBy", field: &createdBy)
binder.bindField(name: "description", field: &description)
binder.bindField(name: "name", field: &name)
binder.bindDictionary(name: "tags", dict: &tags)
}
}