使用 Swift 中的 snapShot 值填充 TableViewCells

Populate TableViewCells with snapShot values in Swift

我正试图用他们发送或被发送的最后一条消息填充我的用户的表格视图,就像 iphone 上消息应用程序的初始视图一样。我有这段代码,但它无法遍历字典数组,我保留了发送给用户的所有消息的快照和 return 预期结果:

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

 func getMsg()-> Int{
  var getIndex = Int()
  let messageDb = Database.database().reference().child("iMessenger/Messages")
  messageDb.observe(.childAdded) { (snapshot) in

  if let snapshotvalue = snapshot.value as? [String:Any], let sender = snapshotvalue["sender"] as? String, let key = snapshotvalue["key"] as? String{

 // I thought that I could iterate through my array of dictionaries taking care to find a matching sender value for the user at indexpath.row and the key for the message

  for (index, dict) in newMessageDictArr.enumerated(){
  if self.users[indexPath.row].userPhone == sender && dict["key"] == key{getIndex = index}}}}

  return getIndex}


 if newMessageDictArr.count !=  0{
 cell.userMessage.text = newMessageDictArr[getMsg()]["messageBody"]}

 return cell}

我遇到的代码问题是

cell.userMessage.text = newMessageDictArr[getMsg()]["messageBody"]

让我的所有单元格都具有 ["messageBody"] 的第一个值,所以我的所有用户似乎都向我发送了相同的消息。试图找出我哪里出错了...

还有我的 FireBase 结构,谢谢。

{
"iMessenger" : {
"Messages" : {
    "-KxDSQOBuCkpFdw4SPDh" : {
      "messageBody" : "TEST ",
      "receiver" : "+197862",
      "sender" : "+16698"  
  },
  "-KxBjNM_iA2XaapyyC9o" : {
    "key" : "-KxBjNM_iA2XaapyyC9o",
    "messageBody" : "TEST",
    "receiver" : "+197862",
    "sender" : "+1914862"
      },
"Messages+199862+197862" : {
  "-KxB7P-vgdfxRpSdnwCT" : {
    "messageBody" : "yo, wassup world",
    "receiver" : "+197862",
    "sender" : "+199862"
  },
  "-KxB81fbn5_OHxdj4lcA" : {
    "messageBody" : "Hello World",
    "receiver" : "+19147862",
    "sender" : "+1997862"
  }
},
"Users" : {
  "-Kx41o03NIMBR68F2sCS" : {
    "displayName" : "sleeping beauty ",
    "firstName" : "",
    "lastName" : "",
    "phoneNumber" : "+165698"
  },
  "-Kx42IXgN1z9D5Zoz0fk" : {
    "displayName" : "KarmaDeli",
    "firstName" : "",
    "lastName" : "",
    "phoneNumber" : "+1397862"
  }}}}

问题有点不清楚,但让我试一试:

从概念上讲,tableView 由一组数据支持。当该数据更改时,应更新数组,然后应调用 tableView.reloadData 来刷新 tableView 中的内容。通常,该技术为用户提供了最流畅的体验。

IMO,应该重写代码以遵循该设计模式。我不会编写所有代码,但会提供一个流程和几个代码片段来为您指明方向。这些未经测试,因此请勿复制和粘贴。

首先,从两个classes

开始
class MessageClass {
  var msgId = ""
  var msgBody = ""
  var msgSenderUid = ""
  var msgReceiverUid = ""
}

class UserClass {
  var uid = ""
  var name = ""
  func init(aUid: String, aName: String) {
       self.uid = aUid
       self.name = aName
  }
}

然后是两个数组来跟踪数据 - 第一个是 messagesArray,它将是您的 tableView 的数据源

var messagesArray = [MessageClass]()
var usersArray = [UsersClass]()

我们假设该应用程序有几百个用户,因此我们将在应用程序启动时加载所有用户数据。请记住,如果添加了新用户,usersArray 将自动更新为新用户

func viewDidLoad() {
   let ref = firebaseRef.child("users")
   ref.observe(.childAdded..... { snapshot in
       let userDict = snapshot.value as! [String: Any]
       let uid = userDict.key
       let name = userDict["name"] as! String
       let userClass = User(aUid: uid, aName: name)
       self.usersArray.append(userClass)

同时向消息节点添加一个观察者,以便您的应用程序收到新消息通知。我们将利用 Firebase 查询观察器,因此该用户只会收到针对他们的消息的通知

   let queryRef = firebaseRef.child("messages")
   queryRef.queryOrdered(byChild: "msg_receiver_uid").query(equalTo: thisUsersUid) {
       let dict = snapshot.value as! [String: Any]
       let sendersUid = dict["msgSenderUid"] as! String
       let msgText = dict["msgBody"] as! String
       //create a MessageClass object and populate it with data
       //add it to the messagesArray
       tableView.reloadData()

最后,在您的 tableView 函数中,从 dataSource messagesArray 获取每一行并创建和填充每个单元格。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
   let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
     let msg = self.messagesArray[indexPath.row]
     let msgSenderUid = msg.msgSenderUid
     let sendersName = //some function to look up the senders name from the users array
     let msg = msg.msgBody
     //populate cell with  users name and msg body
     return cell

同样,这不是为了 copy/paste 而是为了提供示例流程。

发布新消息时,如果消息是发给该用户的,他们将通过查询观察器收到消息通知,并在事件中显示消息。消息被填充到消息 class 对象中,添加到数据源数组并更新表视图以显示它。

如果您不想加载所有用户,请注意这一点。在这种情况下,当消息事件发生时,在用户节点上执行 observeSingleEvent 以检索用户信息。然后在那个闭包中,构建 messageClass,添加到数组并重新加载 tableView。

希望对您有所帮助。