Firebase只加载一次数据,并使用完成处理程序关闭 [英] Firebase only load data once and close using completion handler

查看:239
本文介绍了Firebase只加载一次数据,并使用完成处理程序关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定使用Firebase作为我正在制作的应用程序的后端。有一件事我意识到,一旦我填充了表视图的数据,Firebase的网络连接就不会关闭。



有没有办法可以关闭连接不会耗尽我的用户数据?在我的代码中,我得到的数据,我本地存储,所以它仍然在那里。

 类HomeTableViewController:UITableViewController {

// firebase refrences
var restaurantArray = [Restaurant]()

var dataBaseRef:FIRDatabaseReference! {
return FIRDatabase.database()。reference()
}

////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ///////
覆盖func viewDidLoad(){
super.viewDidLoad()
title =Home
navigationItem.leftBarButtonItem = UIBarButtonItem(image:#imageLiteral资源名称:menuIcon),style:.plain,target:self,action:#selector(SSASideMenu.presentLeftMenuViewController))
navigationItem.leftBarButtonItem?.setBackButtonBackgroundImage(#imageLiteral(resourceName:backButton)。正常,barMetrics:.default)

tableView.backgroundView = UIImageView(image:UIImage(named:Background))
}

覆盖func viewWillAppear(_ Bool){
super.viewWillAppear(true)
fetchRestaurants()
}

////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////
func fetchRestaurants(){
dataBaseRef.child(AthensRestaurants / Restaurants)。observe(.value,with :{(snapshot)in
var results = [Restaurant]()

在snapshot.children中的资源{
let res = Restaurant(snapshot:res as!



self.restaurantArray = results.sorted(by:{(u1,u2) - > Bool in
u1.name< u2.name
))
self.tableView.reloadData()
self.dataBaseRef.removeAllObservers()
}){(error)in
打印(error.localizedDescription)
}
}
// MARK: - 表格视图数据源
// MARK: - 表格视图数据源

重写func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int) - > Int {
// #warning不完整的实现,返回行数
return restaurantArray.count
}


覆盖func tableView(_ tableView: UITableView,cellForRowAt indexPath:IndexPath) - > UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:restaurantsCell,for:indexPath)as! RestaurantsTableViewCell

//配置单元...

cell.configureCell(res:restaurantArray [indexPath.row])
cell.backgroundColor = UIColor.clear
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.borderWidth = 1.5
return cell
}

//将数据传输到新页面
func showRestaurantViewControllerWith(_ res:Restaurant){
let storyBoard = UIStoryboard(name:Main,bundle:nil)
let destinationVC = storyBoard.instantiateViewController(withIdentifier: RestaurantDetails)为! RestaurantDetailViewController
destinationVC.resTransfer = res
self.navigationController?.pushViewController(destinationVC,animated:true)
}

覆盖func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath){
self.showRestaurantViewControllerWith(self.restaurantArray [indexPath.row])
}













  dataBaseRef.child(AthensRestaurants /餐厅)。observe(.value 

您开始观察你的数据库中的 Restaurants 节点,你的代码块会立即用当前值运行,然后每当值改变时,就直接运行。 Firebase数据库客户端将保持与服务器的开放连接。



如果您不需要更新值,您可以注册您的观察员:

  dataBaseRef.child(AthensRestaurants / Restaurants)。 observeSingleEvent(of:.value 

请参阅读取数据一次
$ b 将确保您只获得初始值,不会等待更新,但是可能需要很长时间才能关闭连接。



要明确地管理打开/你可以调用 goOffline() / goOnline(),参见 Firebase参考文档 goOffline()


I decided to use Firebase as the backend for an app I am making. One thing I realized is that the network connection to Firebase does not close once my data for the table view is populated.

Is there a way I can close the connection so it doesn't drain my users data? In my code where I get the data, I store it locally so it would still be there.

    class HomeTableViewController: UITableViewController{

    //firebase refrences
    var restaurantArray = [Restaurant]()

    var dataBaseRef: FIRDatabaseReference! {
        return FIRDatabase.database().reference()
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Home"
        navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "menuIcon"), style: .plain, target: self, action: #selector(SSASideMenu.presentLeftMenuViewController))
        navigationItem.leftBarButtonItem?.setBackButtonBackgroundImage(#imageLiteral(resourceName: "backButton"), for: .normal , barMetrics: .default)

        tableView.backgroundView = UIImageView(image: UIImage(named: "Background"))
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        fetchRestaurants()
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    func fetchRestaurants(){
       dataBaseRef.child("AthensRestaurants/Restaurants").observe(.value, with: { (snapshot) in
            var results = [Restaurant]()

            for res in snapshot.children{
                let res = Restaurant(snapshot: res as! FIRDataSnapshot)
                results.append(res)
            }

            self.restaurantArray = results.sorted(by: { (u1, u2) -> Bool in
                u1.name < u2.name
            })
            self.tableView.reloadData()
            self.dataBaseRef.removeAllObservers()
    }) { (error) in
    print(error.localizedDescription)
    }
}
      // MARK: - Table view data source
      // MARK: - Table view data source

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return restaurantArray.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "restaurantsCell", for: indexPath) as! RestaurantsTableViewCell

        // Configure the cell...

        cell.configureCell(res: restaurantArray[indexPath.row])
        cell.backgroundColor = UIColor.clear
        cell.contentView.layer.borderColor = UIColor.clear.cgColor
        cell.contentView.layer.borderWidth = 1.5
        return cell
    }

    //transfers data to new page
    func showRestaurantViewControllerWith(_ res: Restaurant) {
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let destinationVC = storyBoard.instantiateViewController(withIdentifier: "RestaurantDetails") as! RestaurantDetailViewController
        destinationVC.resTransfer = res
        self.navigationController?.pushViewController(destinationVC, animated: true)
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.showRestaurantViewControllerWith(self.restaurantArray[indexPath.row])
    }











}

解决方案

When you call:

dataBaseRef.child("AthensRestaurants/Restaurants").observe(.value

You start observing the value of the Restaurants node in your database. Your code block will run straight away with the current value and then whenever the value changes. For this reason, the Firebase Database client will keep an open connection to the server.

If you don't need updated values, you can register your observer with:

dataBaseRef.child("AthensRestaurants/Restaurants"). observeSingleEvent(of: .value

See read data once in the Firebase documentation.

That will ensure you only get the initial value and don't wait for updates. But it might still take a long time to close the connection.

To explicitly manage the opening/closing of the connection yourself, you can call goOffline()/goOnline(). See the Firebase reference documentation for goOffline().

这篇关于Firebase只加载一次数据,并使用完成处理程序关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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