Swift 斯威夫特:总是从Firebase获得最新的物品

Swift 斯威夫特:总是从Firebase获得最新的物品,swift,firebase,dictionary,firebase-realtime-database,Swift,Firebase,Dictionary,Firebase Realtime Database,我的目标是构建一个简单的应用程序,它: 通过从Firebase获取项目,使UITableViewCells 点击时,每个单元格执行到另一个ViewController 在显示的ViewController中显示获取的项目的更多详细信息 根据我迄今为止所做的工作: 我可以成功地从数据库中获取数据并将其放入字典中。我还能够基于此数据填充UITableViewCells 点击时,单元格会根据需要显示一个新的ViewController 问题是,无论我点击哪个单元格,我的ViewControll

我的目标是构建一个简单的应用程序,它:

  • 通过从
    Firebase
    获取项目,使
    UITableViewCell
    s
  • 点击时,每个单元格执行到另一个
    ViewController
  • 在显示的
    ViewController
    中显示获取的项目的更多详细信息
根据我迄今为止所做的工作:

  • 我可以成功地从数据库中获取数据并将其放入字典中。我还能够基于此数据填充
    UITableViewCell
    s
  • 点击时,单元格会根据需要显示一个新的
    ViewController
问题是,无论我点击哪个单元格,我的
ViewController
总是显示
Firebase
数据库中最近添加的最少项目。让我提供我的数据库结构和Swift代码:

火基结构:

simple-app:
└── upcoming:
    └── fourth:
        └── desc: "description for the fourth item"
        └── name: "fourth item"
    └── third:
        └── desc: "description for the third item"
        └── name: "third item"
    └── second:
        └── desc: "description for the second item"
        └── name: "second item"
    └── first:
        └── desc: "description for the first item"
        └── name: "first item"
import Foundation
import UIKit
import Firebase

class Upcoming: UITableViewController{
    @IBOutlet weak var upcomingItems: UITableView!
    var itemName: String?
    var itemDesc: String?

    var ref: DatabaseReference!
    var refHandle: UInt!

    var itemList = [Item]()
    let cellId = "cellId"

    override func viewDidLoad() {
        ref = Database.database().reference()
        fetchItems()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemList.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
        itemName = itemList[indexPath.row].name
        itemDesc = itemList[indexPath.row].desc

        cell.textLabel?.text = itemName
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "DetailedInfo", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "DetailedInfo" {
            var vc = segue.destination as! DetailedInfo
            vc.name = itemName
            vc.desc = itemDesc
        }
    }

    func fetchItems(){
        refHandle = ref.child("upcoming").observe(.childAdded, with: {(snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject]{
                print(dictionary) // dictionary is as desired, no corruption
                let item = Item()
                item.setValuesForKeys(dictionary)
                self.itemList.append(token)

                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        })
    }
}
Swift代码:

simple-app:
└── upcoming:
    └── fourth:
        └── desc: "description for the fourth item"
        └── name: "fourth item"
    └── third:
        └── desc: "description for the third item"
        └── name: "third item"
    └── second:
        └── desc: "description for the second item"
        └── name: "second item"
    └── first:
        └── desc: "description for the first item"
        └── name: "first item"
import Foundation
import UIKit
import Firebase

class Upcoming: UITableViewController{
    @IBOutlet weak var upcomingItems: UITableView!
    var itemName: String?
    var itemDesc: String?

    var ref: DatabaseReference!
    var refHandle: UInt!

    var itemList = [Item]()
    let cellId = "cellId"

    override func viewDidLoad() {
        ref = Database.database().reference()
        fetchItems()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemList.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
        itemName = itemList[indexPath.row].name
        itemDesc = itemList[indexPath.row].desc

        cell.textLabel?.text = itemName
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "DetailedInfo", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "DetailedInfo" {
            var vc = segue.destination as! DetailedInfo
            vc.name = itemName
            vc.desc = itemDesc
        }
    }

    func fetchItems(){
        refHandle = ref.child("upcoming").observe(.childAdded, with: {(snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject]{
                print(dictionary) // dictionary is as desired, no corruption
                let item = Item()
                item.setValuesForKeys(dictionary)
                self.itemList.append(token)

                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        })
    }
}

我可以根据需要看到四个具有四个不同名称的不同单元格,但无论点击哪个单元格,next
ViewController
都会显示数据库中最近添加的项目的
name
desc
值,该项目是
first
。如果您有任何想法可以解决此问题,我们将不胜感激

尝试使用这种方法

refHandle = ref.child("upcoming").observeSingleEvent(of: .value, with: { (snapshot) in

但如果不需要经常检查数据库更新,情况就是这样。

尝试使用这种方法

refHandle = ref.child("upcoming").observeSingleEvent(of: .value, with: { (snapshot) in

但如果不需要经常检查数据库更新,情况就是这样。

itemName和itemDesc将始终是最后一个单元格,因为您将其写入cellForRow, 在didSelectRow中设置项目

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
        cell.textLabel?.text = itemList[indexPath.row].name
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        itemName = itemList[indexPath.row].name
        itemDesc = itemList[indexPath.row].desc
        performSegue(withIdentifier: "DetailedInfo", sender: self)
    }

itemName和itemDesc将始终是最后一个单元格,因为您在cellForRow中写入它, 在didSelectRow中设置项目

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
        cell.textLabel?.text = itemList[indexPath.row].name
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        itemName = itemList[indexPath.row].name
        itemDesc = itemList[indexPath.row].desc
        performSegue(withIdentifier: "DetailedInfo", sender: self)
    }

无法尝试此操作,我收到以下错误:“无法将'Void'类型的值分配给'UInt!'”无法尝试此操作,我收到以下错误:“无法将'Void'类型的值分配给'UInt!'”工作正常!工作得很好!