我有一个tableviewcontroller,其中包含已登录用户在应用中向其选择的所有用户发送的所有消息的列表:
使用此代码附加登录用户与应用程序的任何其他用户之间的消息并显示在tableviewcell中:
func loadData()
{
FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for post in postsDictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let info = value as! [String: AnyObject]
let convoId = info["convoId"]
let toId = info["ReceiverId"] as! String!
let fromId = info["senderId"] as! String!
if (toId == self.loggedInUserUid || fromId == self.loggedInUserUid) {
let ref = FIRDatabase.database().reference().child("messages").child(convoId as! String)
ref.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let message = Message(dictionary: dictionary)
// self.messages.append(message)
if let receiver = message.convoId {
self.messagesDictionary[receiver] = message
self.messages = Array(self.messagesDictionary.values)
print(self.messages)
self.messages.sort(by: { (message1, message2) -> Bool in
return (message1.timestamp?.int32Value)! > (message2.timestamp?.int32Value)!
})
}
//this will crash because of background thread, so lets call this on dispatch_async main thread
DispatchQueue.main.async(execute: {
self.MessageTableView.reloadData()
})
}
}, withCancel: nil)}
}
}}})
}
但是,当我单击一个单元格时,我想转到一个详细的视图控制器,它显示登录用户和单击的单元用户之间的消息,因此我使用此代码进行划分:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let message = messages[indexPath.row]
if message.ReceiverId != self.loggedInUserUid {
var newVariable = message.ReceiverId
if let userpicuid = newVariable {
let ref = FIRDatabase.database().reference().child("users").child(userpicuid)
ref.observeSingleEvent(of: .value, with: { (snapshot)
in
if let dictionary = snapshot.value as? [String: AnyObject]{
for post in dictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let username = messages["username"] as? String
self.userpicuid = userpicuid
self.username = username
}}}})}} else if message.senderId != self.loggedInUserUid {
let newVariable = message.senderId
if let userpicuid = newVariable {
let ref = FIRDatabase.database().reference().child("users").child(userpicuid)
ref.observeSingleEvent(of: .value, with: { (snapshot)
in
if let dictionary = snapshot.value as? [String: AnyObject]{
for post in dictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let username = messages["username"] as? String
self.userpicuid = userpicuid
self.username = username
}}}})}
}
performSegue(withIdentifier: "MessageNow", sender: self)
}
override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "MessageNow", let chatVc = segue.destination as? SendMessageViewController else {
return
}
print(self.userpicuid)
chatVc.senderId = self.loggedInUser?.uid
chatVc.receiverData = self.userpicuid
chatVc.senderDisplayName = self.userpicuid
chatVc.username = self.username
}
然而,当我点击单元格时,我收到错误致命错误:在展开可选值时意外发现nil 所以我包含了一些打印语句以找出nil的位置。结果是userpicuid,用户名返回nil。我不确定我做错了什么,特别是因为我的代码正在检查receiverId和senderId,并且其中一个不是登录用户的uid,那么uid应该是发送者ID,它会分割成详细消息。
错误发生在let receiverId = receiverData上!详细消息视图控制器中的行:
var receiverData: String?
override func viewDidLoad() {
super.viewDidLoad()
let receiverId = receiverData!
let receiverIdFive = String(receiverId.characters.prefix(5))
let senderIdFive = String(senderId.characters.prefix(5))
if (senderIdFive > receiverIdFive)
{
self.convoId = senderIdFive + receiverIdFive
}
else
{
self.convoId = receiverIdFive + senderIdFive
}
}
答案 0 :(得分:0)
尝试这一行:
performSegue(withIdentifier: "MessageNow", sender: self)
就在这里:
let username = messages["username"] as? String
self.userpicuid = userpicuid
self.username = username
performSegue(withIdentifier: "MessageNow", sender: self)
答案 1 :(得分:0)
我用这个找到了问题的解决方案:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageTableViewCell
if message.ReceiverId != self.loggedInUserUid {
var newVariable = message.ReceiverId
if let imageName = newVariable {
let ref = FIRDatabase.database().reference().child("users").child(imageName)
ref.observeSingleEvent(of: .value, with: { (snapshot)
in
if let dictionary = snapshot.value as? [String: AnyObject]{
for post in dictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
self.username = messages["username"] as? String
self.userpicuid = messages["uid"] as? String
}}}})}}else if message.senderId != self.loggedInUserUid {
let newVariable = message.senderId
if let imageName = newVariable {
let ref = FIRDatabase.database().reference().child("users").child(imageName)
ref.observeSingleEvent(of: .value, with: { (snapshot)
in
if let dictionary = snapshot.value as? [String: AnyObject]{
for post in dictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
self.username = messages["username"] as? String
self.userpicuid = messages["uid"] as? String
}}}})}
}
return cell
}
override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "MessageNow", let chatVc = segue.destination as? SendMessageViewController else {
return
}
chatVc.senderId = self.loggedInUser?.uid
chatVc.receiverData = self.userpicuid
chatVc.senderDisplayName = self.userpicuid
chatVc.username = self.username
}