我正在尝试编写用户之间的消息聊天记录。所以我只想从我的消息数组中检索特定数据。例如,当有人发送短信时,我只想从我的消息数组中检索 fromId、toId 和文本。当有人发送图像时,我只想检索 fromId、toId 和 imageUrl。目前应用程序崩溃是因为当一个人发送文本时“imageUrl”为零,反之亦然发送“文本”为零的图像。有没有解决的办法?还是我必须创建 2 个单独的数组?提前致谢
消息数组
class Message {
var fromId: String
var text: String
var toId: String
var timeStamp: NSNumber?
var imageUrl: String
init(fromId: String, text: String, toId: String, timeStamp: NSNumber, imageUrl: String){
self.fromId = fromId
self.text = text
self.toId = toId
self.imageUrl = imageUrl
}
init(snapshot:FIRDataSnapshot) {
self.fromId = (snapshot.value! as! NSDictionary)["fromId"] as! String!
self.toId = (snapshot.value! as! NSDictionary)["toId"] as! String!
self.text = (snapshot.value! as! NSDictionary)["text"] as! String!
self.imageUrl = (snapshot.value! as! NSDictionary)["imageUrl"] as! String!
}
Firebase 结构
{ "messages": {
"KkGAWnQhqnOx525vv2W": {
"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2,
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2,
"text": "Hello"
},
"hujU6UF6mWZeewAJXt0": {
"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2,
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2,
"imageUrl": "https://firebasestorage.googleapis.com/v0/b.."
}
用于检索数据的方法
var message = [Message]()
func observeMessages(){
let ref = FIRDatabase.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded, with: { (snapshot) in
let messageId = snapshot.key
let messageReference = FIRDatabase.database().reference().child("messages").child(messageId)
messageReference.observe(.value, with: { (snapshot) in
for posts in snapshot.children{
let message = Message(snapshot: posts as! FIRDataSnapshot )
let chatPartnerId = message.chatPartnerId()
self.messagesDictionary[chatPartnerId!] = message
self.messageTableView.reloadData()
})
}
}, withCancel: nil)
}
最佳答案
它崩溃的原因是因为你在用字典下标时强行包装了值(value)。您需要使用 if let
或 guard let
来包装可选的,或者您可以使用默认值为空的 Nil-Coalescing Operator
并稍后检查哪个一个是非空的 text
或 image
。
init(snapshot:FIRDataSnapshot) {
let dictionary = snapshot.value as! [String:Any]
self.fromId = dictionary["fromId"] as! String
self.toId = dictionary["toId"] as! String
self.text = dictionary["text"] as? String ?? ""
self.imageUrl = dictionary["imageUrl"] as? String ?? ""
}
此外,更棒的选择是再添加一个键,您的消息对象为 type
,值为 text
或 image
。使你的结构像这样。
{
"messages": {
"KkGAWnQhqnOx525vv2W": {
"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2,
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2,
"type" "text"
"text": "Hello"
},
"hujU6UF6mWZeewAJXt0": {
"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2,
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2,
"type" "image"
"imageUrl": "https://firebasestorage.googleapis.com/v0/b.."
}
}
}
然后获取类型的值并比较它是text
还是image
init(snapshot:FIRDataSnapshot) {
let dictionary = snapshot.value as! [String:Any]
self.fromId = dictionary["fromId"] as! String
self.toId = dictionary["toId"] as! String
//Make one more property with name type of String
self.type = dictionary["type"] as! String
self.text = dictionary["text"] as? String ?? ""
self.imageUrl = dictionary["imageUrl"] as? String ?? ""
}
现在,当您访问此对象时,检查其类型并根据它访问其属性 text 和 imageUrl。
关于ios - 快速从对象数组检索数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44031634/