首页 > 解决方案 > 如何在 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 类中也没有。

有谁能够帮我 ?提前致谢。

标签: firebasefirebase-realtime-databaseswift4

解决方案


Firebase 实时数据库 SDK 是异步的,因此当您添加该observe调用时,您会说:“只要此路径有更新,请调用此代码块”。

你有评论的地方是你添加观察者之后的那一行,而不是观察者运行之后的那一行。当您去添加标记时,您还没有任何数据要添加。您必须这样做,以便在更新addMarker时触发呼叫。shopArray您可以将回调传递给getShops(),或者您可以将观察者移动到您的视图控制器中,它可以addMarker直接看到该函数。

一旦你让它工作并理解了这个概念,重构以适应你的架构会更容易。查看Doug 的关于为什么 API 是异步的媒体文章以了解更多信息。


推荐阅读