使用Swift中的snapShot值填充TableViewCells

时间:2017-10-24 16:37:04

标签: swift uitableview firebase snapshot

我正在尝试使用他们发送的最后一条消息填充我的用户的tableview,或者像iphone上的初始查看消息应用程序一样发送。我有这个代码,但它没有工作迭代字典数组,我保留了发送给用户的所有消息的快照并返回预期的结果:

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"
  }}}}

1 个答案:

答案 0 :(得分:0)

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

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

IMO,应该重写代码以遵循该设计模式。我不打算编写所有代码,但会提供一个流程和几个代码片段来为您提供一些指导。这些都没有经过测试,所以不要复制和粘贴。

首先,从两个类开始

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的dataSource

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

同样,这不是复制/粘贴的意思,而是提供示例流程。

当发布新消息时,如果消息是针对该用户的,则将通过查询观察者通知消息,并在事件中显示消息。消息被填充到消息类对象中,添加到数据源数组中并更新tableview以显示它。

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

希望有所帮助。