简体   繁体   English

Swift 2 Firebase TableView

[英]Swift 2 Firebase TableView

I am a newbie to swift and firebase, I am trying to populate my tabelview with firebase data. 我是swift和firebase的新手,我试图用firebase数据填充tabelview。 When I run the program, nothing shows up in tableview. 当我运行该程序时,表视图中没有任何显示。 Any help would be gladly appreciated. 任何帮助将不胜感激。 This is what I got do far, tried to read the documents, but its not helping. 这是我到目前为止所做的,试图阅读文档,但没有帮助。

import UIKit
import Firebase
import FirebaseUI


class ChurchTableViewController: UITableViewController {


let firebase = Firebase(url:"https://.....com/")

var items = [NSDictionary]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
     //self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

override func viewDidAppear(animated: Bool) {

    //MARK: Load data from firebsr
    firebase.observeEventType(.Value, withBlock: { snapshot in
        print(snapshot.value)
        }, withCancelBlock: { error in
            print(error.description)
    })

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let dict = items[indexPath.row]
    cell.textLabel?.text = dict["ChurchName"] as? String

    return cell
}

You've created the observer for when some value changes in your Firebase DB, but in your closure you need to add the new items and of course reload your UITableView to synchronize the data in your app, see the following code to see a sample of how to do it with a sample data type too: 您已经为Firebase数据库中的某些值更改创建了观察器,但是在关闭时,您需要添加新项,当然还需要重新加载UITableView以同步应用程序中的数据,请参见以下代码以查看示例如何使用样本数据类型也是如此:

var items = [GroceryItem]()

override func viewDidAppear(animated: Bool) {
     super.viewDidAppear(animated)

     firebase.observeEventType(.Value, withBlock: { snapshot in
        var newItems = [GroceryItem]()

        for item in snapshot.children {
          let itemType = GroceryItem(snapshot: item as! FDataSnapshot)
          newItems.append(itemType)
        }

        // update your item with the new ones retrieved
        self.items = newItems

        // reload the data
       self.tableView.reloadData()
    })
}

In the below struct you can see a sample of how you can create your data type from the data returned from Firebase 在下面的结构中,您可以查看如何从Firebase返回的数据创建数据类型的示例

GroceryItem 杂货项目

struct GroceryItem {

   let key: String!
   let name: String!
   let addedByUser: String!
   let ref: Firebase?
   var completed: Bool!

   // Initialize from arbitrary data
   init(name: String, addedByUser: String, completed: Bool, key: String = "") {
     self.key = key
     self.name = name
     self.addedByUser = addedByUser
     self.completed = completed
     self.ref = nil
   }

   init(snapshot: FDataSnapshot) {
     key = snapshot.key
     name = snapshot.value["name"] as! String
     addedByUser = snapshot.value["addedByUser"] as! String
     completed = snapshot.value["completed"] as! Bool
     ref = snapshot.ref
   }
}

For a deeper knowledge about how to use Firebase you can read this very good tutorial: 有关如何使用Firebase的更深入的知识,您可以阅读以下非常好的教程:

I hope this help you. 希望对您有所帮助。

Check that you have set your Tableview's delegate and datasource properly, to do this, go to interface builder, cmd + right click on your tableview and drag over to the yellow heading icon in interface builder. 检查是否已经正确设置了Tableview的委托和数据源,要执行此操作,请转到界面构建器,使用cmd +右键单击您的表视图,然后拖动到界面构建器中的黄色标题图标。

You should see two options, 'datasource' and 'delegate', make sure that they are both checked and then rerun your app, you should see the table populate with whatever data you've loaded 您应该看到两个选项,“数据源”和“委托”,确保都选中了它们,然后重新运行您的应用程序,您应该看到该表中填充了已加载的所有数据

You've got three issues 你有三个问题

1) Your not populating a datasource for your tableview. 1)您没有为表视图填充数据源。 This is typically an array that is stored in the class and because it's by .value you will need to iterate over those values to get to each child nodes data 这通常是一个存储在类中的数组,因为它是通过.value进行的,所以您需要遍历这些值以获取每个子节点数据

2) You are observing by .value. 2)您正在通过.value进行观察。 This will return everything in the node, all children, their children etc so you won't be able to directly read it as a string value unless that's all the node contains, as in a single key:value pair, otherwise all of they key:value pairs will be read. 这将返回节点,所有子节点,它们的子节点等中的所有内容,因此您将无法直接将其读取为字符串值,除非该节点包含所有节点,例如在单个key:value对中,否则它们都将作为关键字:value对将被读取。

3) Firebase is asynchronous so within the observe block, you need to populate the array, and then re-load the tableview 3)Firebase是异步的,因此在observe块中,您需要填充数组,然后重新加载tableview

Here's the solution: 解决方法如下:

Given a structure 给定结构

users    
    user_id_0
       name: "Biff"
    user_id_1
       name: "Buffy"
    user_id_2
       name: "Skip

here's the associated code to read in each name and populate a namesArray 这是相关的代码,可读取每个名称并填充一个namesArray

var namesArray: [String] = []

ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        for child in snapshot.children {
           let name = child.value["name"] as! String
           namesArray.append(name)
        }
        self.myTableView.reloadData()
})

substitute your items array for the namesArray. 将您的项数组替换为namesArray。

They key is to let Firebase load the data asynchronously before telling the tableView to refresh itself, and when using .Value, ensure you iterate over all of the children in that node with snapshot.children 它们的关键是让Firebase在告诉tableView刷新自身之前异步加载数据,并且在使用.Value时,请确保您使用snapshot.children遍历该节点中的所有子级。

  • This is happened because there is no data in your items array. 发生这种情况是因为您的items数组中没有数据。 So first inside your viewDidAppear method you need to append your Firebase data dictionaries into items array and then call tableView.reloadData() . 因此,首先需要在viewDidAppear方法内部将Firebase数据字典追加到items数组中,然后调用tableView.reloadData()
  • Also check your Firebase database url is correct and you need to fetch and store data in proper format while appending to items array. 还要检查您的Firebase数据库URL是否正确,并且在附加到items数组时需要以正确的格式获取和存储数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM