将观察 .value 转换为 .child 快速添加
Posted
技术标签:
【中文标题】将观察 .value 转换为 .child 快速添加【英文标题】:Convert observe .value to .childAdded in swift 【发布时间】:2017-10-03 16:28:44 【问题描述】:目前,我在将 Firebase 数据库中的数据加载到数组中的这段代码中遇到了一些问题。由于这是在 viewDidLoad 内部,我必须在将数据加载到其中之前清空我的数组food = []
,如果我不这样做,它将复制所有对象,并且第二次加载时我将重复两次,第三次加载三次等等...但是由于多种原因,这不是一个好的解决方法,所以我想要的是它只会使用.childAdded
从数据库中添加新对象但是如果我只是用.childAdded
切换出.value
它会崩溃,我在这条线上得到一个Thread 1: signal SIGABRT
:let dict = user_snap.value as! [String: String?]
。我对 swift 很陌生,不知道如何解决这个问题,非常感谢一些帮助。
let parentRef = Database.database().reference().child("Recipes")
let storage = Storage.storage()
parentRef.observe(.value, with: snapshot in
if ( snapshot.value is NSNull )
// DATA WAS NOT FOUND
print("– – – Data was not found – – –")
else
//Clears array so that it does not load duplicates
food = []
// DATA WAS FOUND
for user_child in (snapshot.children)
let user_snap = user_child as! DataSnapshot
let dict = user_snap.value as! [String: String?]
//Defines variables for labels
let recipeName = dict["Name"] as? String
let recipeDescription = dict["Description"] as? String
let downloadURL = dict["Image"] as? String
let storageRef = storage.reference(forURL: downloadURL!)
storageRef.getData(maxSize: 1 * 1024 * 1024) (data, error) -> Void in
let recipeImage = UIImage(data: data!)
food.append(Element(name: recipeName!, description: recipeDescription!, image: recipeImage!))
self.tableView.reloadData()
)
【问题讨论】:
用这一行更新你的代码以避免崩溃if let dict = user_snap.value as? [String: String?]
。还要检查 user_snap
对象的类型。当您的应用程序崩溃时,我确信它没有字典对象。
@Surjeet 我在
里面放了什么?
注释行“为标签定义变量”之后的代码。我已经在 for 循环中为您提供了第二行的更新版本
@Surjeet ok 将注释后的所有代码添加到括号中,它没有崩溃但是我的 tableView 现在是空的,数组也是。
@Surjeet 换句话说:括号内的代码不会运行,它会跳过它。
【参考方案1】:
let dict = user_snap.value as! [String: String?]
代替
let dict = snapshot.value as! Dictionary<String, String>
也许你可以做空测试:
let dict = snapshot.value as! Dictionary<String, String>
if let recipeName = dict["Name"] as String!, let recipeDescription = dict["Description"] as String!, let downloadURL = dict["Image"] as String!
let storageRef = storage.reference(forURL: downloadURL)
storageRef.getData(maxSize: 1 * 1024 * 1024) (data, error) -> Void in
let recipeImage = UIImage(data: data!)
food.append(Element(name: recipeName, description: recipeDescription, image: recipeImage!, downloadURL: downloadURL))
self.tableView.reloadData()
else
print("Error! Could not decode data")
【讨论】:
是的,你太棒了!谢谢,但是您遗漏了我的一些代码并更改了一些变量名,因此我对其进行了编辑和修复。【参考方案2】:试试这个。它应该工作
for child in snapshot.children.allObjects as! [FIRDataSnapshot]
let dict = child.value as! Dictionary<String, Any>
//.....
【讨论】:
我在let dict = child.value as! Dictionary<String, Any>
上得到Thread 1: signal SIGABRT
,在调试器中显示Could not cast value of type 'NSTaggedPointerString'
以上是关于将观察 .value 转换为 .child 快速添加的主要内容,如果未能解决你的问题,请参考以下文章
使用快速添加的 .Value/.Child 从 Firebase 检索数据时遇到问题
Firebase 使用 .value 观察者获取数据不起作用
将 AppKit/UIKit 中的 Key-Value Observation 转换为 Combine 和 SwiftUI