firebase - 如何在 viewdidload 之前从 firebase 获取数据
问题描述
我从 firebase 获取数据时遇到问题。这是我的网络课程。
class Networking {
static var instance = Networking()
var shopArray : [Shop] = []
func getShops() {
Database.database().reference().child("eeb3215fgsfnuvj").child("shops").observe(.value) { snapshot in
let shopsDictionary = snapshot.value as! NSDictionary
for shop in shopsDictionary.allKeys {
let tempShopDictionary = shopsDictionary[shop] as! NSDictionary
self.shopArray.append(Shop(shopID: tempShopDictionary["shop_id"] as! Int, shopName: tempShopDictionary["shop_name"] as! String, shopLat: tempShopDictionary["shop_lat"] as! Double, shopLong: tempShopDictionary["shop_long"] as! Double, shopCategory: tempShopDictionary["shop_category"] as! String, shopLogo: tempShopDictionary["shop_logo"] as! String))
}
print(self.shopArray)
}
print(shopArray) // I cant print data here...
}
正如我所说的推荐行,我可以在 firebase 代码块中打印数据,但不能在我添加评论的行中打印
因此,我无法在视图控制器中看到我的数据。这是我的视图控制器类。
@IBOutlet weak var mapView: GMSMapView!
@IBOutlet weak var menuButton: UIButton!
@IBOutlet weak var sideBar: SideBarView!
@IBOutlet weak var leadingConstraint: NSLayoutConstraint!
var locationManager = CLLocationManager()
var isSideBarOpen : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
self.locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
Networking.instance.getShops()
addMarker()
}
@IBAction func menuButtonTapped(_ sender: UIButton) {
if isSideBarOpen {
leadingConstraint.constant = -200
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
} else {
leadingConstraint.constant = 0
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
isSideBarOpen = !isSideBarOpen
}
func addMarker () {
for marker in Networking.instance.shopArray {
print(marker)
}
// I cant print marker as well
}
在 addMarker 函数中,您将看到我的评论行。在函数 shopArray 中没有任何项目,即使它在 Networking 类中也没有。
有谁能够帮我 ?提前致谢。
解决方案
Firebase 实时数据库 SDK 是异步的,因此当您添加该observe
调用时,您会说:“只要此路径有更新,请调用此代码块”。
你有评论的地方是你添加观察者之后的那一行,而不是观察者运行之后的那一行。当您去添加标记时,您还没有任何数据要添加。您必须这样做,以便在更新addMarker
时触发呼叫。shopArray
您可以将回调传递给getShops()
,或者您可以将观察者移动到您的视图控制器中,它可以addMarker
直接看到该函数。
一旦你让它工作并理解了这个概念,重构以适应你的架构会更容易。查看Doug 的关于为什么 API 是异步的媒体文章以了解更多信息。
推荐阅读
- excel - 复制具有匹配工作表名称的数据
- python - 仅当有任何新可用时才下载 sonarqube 包的 Python 脚本
- spring - 为两个不同的入口点创建 bean
- gitlab - 检索 Jenkins 文件和 Git 存储库
- sql-server - 如何在 ASP.NET Core 中使用 Serilog 禁用自动日志记录
- javascript - 检查文本输入字段是否为空或包含数字
- python - 如何重新排列数据在多列之间拆分的熊猫表
- r - 如何在谷歌 colab R 上使用 gpu?
- reactjs - 反应:备忘录不起作用 - OnClick 按钮导致重新渲染
- wso2 - 连接从 file.properties 注入的两个属性