从 firebase 读取数据并填充 TableViewCell

Read data from firebase and populate TableViewCell

你好,我有一个 tableviewcell,我可以用我的电脑中的自定义数据填充它,但我不能在我制作的单元格上使用我的 firebase 数据。我想用 String 和 Int 填充我的单元格,而不仅仅是字符串。我的代码是:

PlacesTableViewController Class

import UIKit
import FirebaseDatabase

class PlacesTableViewController: UITableViewController {

    //MARK: Properties
    @IBOutlet weak var placesTableView: UITableView!

    //database reference
    var dbRef:FIRDatabaseReference?

    var places = [Places]()

    var myList:[String] = []

    //handler
    var handle:FIRDatabaseHandle?

    override func viewDidLoad() {
        super.viewDidLoad()

        dbRef = FIRDatabase.database().reference()

        // Loads data to cell.
        loadData()
    }
 // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

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


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "PlacesTableViewCell"

        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? PlacesTableViewCell  else {
            fatalError("The dequeued cell is not an instance of PlacesTableView Cell.")
        }

        let place = places[indexPath.row]

        cell.placeLabel.text = place.name
        cell.ratingControl.rating = place.rating

        //cell.placeLabel.text = myList[indexPath.row]
        //cell.ratingControl.rating = myRatings[indexPath.row]

        return cell

    }
//MARK: Private Methods

    private func loadData() {


        handle = dbRef?.child("placeLabel").observe(.childAdded, with: { (snapshot) in
            if let item = snapshot.value as? String
            {
                self.myList.append(item)
                self.placesTableView.reloadData()
                print (item)
            }
        })
/* handle = dbRef?.child("rating").observe(.childAdded, with: { (snapshot) in
            if let item = snapshot.value as? String
            {
                self.myList.append(item)
                self.placesTableView.reloadData()

            }
        })*/
/*guard let place1 = Places(name: "Veranda", rating: 4) else {
            fatalError("Unable to instantiate place1")

        }
        places += [place1]*/

    }

}

地点 Class

import UIKit

class Places {

    //MARK: Properties

    var name: String
    var rating: Int

    //MARK:Types

    struct PropertyKey {
        static let name = "name"
        static let rating = "rating"
    }

    //MARK: Initialization

    init?(name: String, rating: Int) {
        // Initialize stored properties.
        self.name = name
        self.rating = rating

        // Initialization should fail if there is no name or if the rating is negative.
        // The name must not be empty
        guard !name.isEmpty else {
            return nil
        }

        // The rating must be between 0 and 5 inclusively
        guard (rating >= 0) && (rating <= 5) else {
            return nil
        }

    }

}

PlacesTableViewCell Class

import UIKit
import FirebaseDatabase

class PlacesTableViewCell: UITableViewCell, UITableViewDelegate {

    //MARK: Properties
    @IBOutlet weak var placeLabel: UILabel!
    @IBOutlet weak var ratingControl: RatingControl!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Firebase 数据库

假设您的数据库布局应该如下所示(参见上面的评论):

...
placeLabel
    |
    -- XXY: "Veranda"
    -- YYY: "Dio Con Dio"
rating
    |
    -- XXX: 4
    -- YYY: 1
...   

然后试试这个:

private func loadData() {
    dbRef!.child("placeLabel").observe(.childAdded) { 
        (snapshot) in
        let label = snapshot.value as! String
        self.updatePlace(snapshot.key, label: label)
     }
     dbRef!.child("rating").observe(.childAdded) { 
        (snapshot) in
        let rating = snapshot.value as! Int
        self.updatePlace(snapshot.key, rating: rating)
     }
}

private var loadedLabels = [String: String]()
private var loadedRatings = [String: Int]()

private func updatePlace(_ key: String, label: String? = nil, rating: Int? = nil) {
    if let label = label { 
        loadedLabels[key] = label
    } 
    if let rating = rating { 
        loadedRatings[key] = rating
    }
    guard let label = loadedLabels[key], let rating = loadedRatings[key] else {
        return 
    }  
    if let place = Places(name: label, rating: rating) {
        places.append(place)
        placesTableView.reloadData()
    }
}

顺便说一句,如果您想快速验证上述解决方案,您可以暂时 破解您的数据库 — 使用 Firebase(太棒了!)Web 控制台。


写入数据库。尝试使用以下代码 write 数据库中的节点(即,此代码在 all 地点属性中重复使用相同的键):

let key = dbRef!.child("placeLabel").childByAutoId().key

dbRef!.child("placeLabel").child(key).setValue(placeLab‌​el.text)
dbRef!.child("comment").child(key).setValue(commentText‌​Field.text) 
dbRef!.child("rating").child(key).setValue(ratingContro‌​l.rating)

入侵数据库。要手动编辑数据库,请尝试:

  1. 打开http://console.firebase.google.com
  2. select 你的应用程序
  3. 打开数据库选项
  4. 添加一个新的节点
  5. 删除旧的节点