从 Firebase 检索的文本未显示在应用程序中
Text retrieval from Firebase is not displaying in app
我正在开发一个消息传递应用程序,我想在消息内容下方显示消息发送的位置。为此,我尝试将用户的位置数据发送到 Firebase,然后尝试检索数据以将其显示为字符串。
获取用户位置工作正常(我正在使用 CoreLocation
这样做),将数据上传到我的 Firebase 实时数据库也是如此。我将位置与每条消息一起保存如下:
让 itemRef = messageRef.childByAutoId() // 1
让消息项 = [ // 2
"text": 文字,
"senderId": 发件人编号,
"location":获取位置()
]
itemRef.setValue(messageItem) // 3
然后尝试用另一种方法检索数据:
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
var locationId: String = ""
let messagesQuery = messageRef
let message = messages[indexPath.item]
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
locationId = snapshot.value!["location"] as! String
print(locationId)
}
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: locationId)
}
}
控制台打印出正确的位置,但我的应用程序中没有显示任何内容。但是,如果我将变量 locationId
替换为任何其他字符串,它就可以工作。
我认为我的问题是 Firebase 检索。
如果有人能帮我解决这个问题,将不胜感激。
下面是我的 class 的其余代码,供参考(以防万一):
class ChatViewController: JSQMessagesViewController, CLLocationManagerDelegate {
// MARK: Properties
//Firebase
var rootRef = FIRDatabase.database().reference()
var messageRef: FIRDatabaseReference!
var locationRef: FIRDatabaseReference!
//JSQMessages
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
var purp = UIColor.init(red:47/255, green: 53/255, blue: 144/255, alpha: 1)
var roastish = UIColor.init(red: 255/255, green: 35/255, blue: 35/255, alpha: 1.0)
var orangish = UIColor.init(red: 231/255, green: 83/255, blue: 55/255, alpha: 1.0)
var gray = UIColor.init(red: 241/255, green: 251/255, blue: 241/255, alpha: 1)
//Location
var city: String = ""
var state: String = ""
var country: String = ""
var locationManager = CLLocationManager()
func getLocation() -> String {
if city == ("") && state == ("") && country == (""){
return "Planet Earth"
}
else {
if country == ("United States") {
return self.city + ", " + self.state
}
else {
return self.city + ", " + self.state + ", " + self.country
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Initialize location
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
//collect user's location
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.requestLocation()
locationManager.startUpdatingLocation()
}
// Change the navigation bar background color
navigationController!.navigationBar.barTintColor = gray
self.navigationController!.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "Avenir Next", size: 20)!]
title = "RoastChat"
setupBubbles()
// No avatars
// Remove file upload icon
self.inputToolbar.contentView.leftBarButtonItem = nil;
// Send button
self.inputToolbar.contentView.rightBarButtonItem.setTitle("Roast", forState: UIControlState.Normal)
// Send button color
self.inputToolbar.contentView.rightBarButtonItem.setTitleColor(roastish, forState: UIControlState.Normal)
// Input bar text placeholder
self.inputToolbar.contentView.textView.placeHolder = "RoastChat"
collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
//Firebase reference
messageRef = rootRef.child("messages")
locationRef = rootRef.child("locations")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
observeMessages()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//--- CLGeocode to get address of current location ---//
CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
if let pm = placemarks?.first
{
self.displayLocationInfo(pm)
}
})
}
func displayLocationInfo(placemark: CLPlacemark?)
{
if let containsPlacemark = placemark
{
//stop updating location
locationManager.stopUpdatingLocation()
self.city = (containsPlacemark.locality != nil) ? containsPlacemark.locality! : ""
self.state = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea! : ""
self.country = (containsPlacemark.country != nil) ? containsPlacemark.country! : ""
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error while updating location " + error.localizedDescription)
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item] // 1
if message.senderId == senderId { // 2
return outgoingBubbleImageView
} else { // 3
return incomingBubbleImageView
}
}
override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
roastish)
}
func addMessage(id: String, text: String) {
let message = JSQMessage(senderId: id, displayName: "", text: text)
messages.append(message)
}
override func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
as! JSQMessagesCollectionViewCell
let message = messages[indexPath.item]
if message.senderId == senderId {
cell.textView!.textColor = UIColor.whiteColor()
} else {
cell.textView!.textColor = UIColor.whiteColor()
}
return cell
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!,
senderDisplayName: String!, date: NSDate!) {
let itemRef = messageRef.childByAutoId() // 1
let messageItem = [ // 2
"text": text,
"senderId": senderId,
"location": getLocation()
]
itemRef.setValue(messageItem) // 3
// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()
// 5
finishSendingMessage()
Answers.logCustomEventWithName("Message sent", customAttributes: nil)
}
private func observeMessages() {
// 1
let messagesQuery = messageRef.queryLimitedToLast(25)
// 2
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
// 3
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
// 4
self.addMessage(id, text: text)
// 5
self.finishReceivingMessage()
Answers.logCustomEventWithName("Visited RoastChat", customAttributes: nil)
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
var locationId: String = ""
let messagesQuery = messageRef
let message = messages[indexPath.item]
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
locationId = snapshot.value!["location"] as! String
print(locationId)
}
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: locationId)
}
}
override func collectionView(collectionView: JSQMessagesCollectionView, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout, heightForCellBottomLabelAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return kJSQMessagesCollectionViewCellLabelHeightDefault
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAtIndexPath indexPath: NSIndexPath!) {
super.collectionView(collectionView, didTapMessageBubbleAtIndexPath: indexPath)
let data = self.messages[indexPath.row]
print("They tapped: " + (data.text))
}
}
99% 的时间,当您从 Internet 检索一些数据时 - 就像这里的情况一样,您观察到 Firebase 事件以获取其他用户发送的位置 - 代码以异步方式工作。
这意味着当您检索位置时触发的闭包将独立于 attributedTextForCellBottomLabelAtIndexPath 函数的其余部分进行调用。
因此,当您实际获取位置时,该函数已经返回了使用空 locationId 创建的 NSAttributedString;为什么是空的?因为您已将其初始值设置为“”。
调用 messagesQuery.observeEventType 时传递的闭包在本地捕获 locationId 属性,因此您可以将其设置为从 API 中检索到的内容,打印工作正常。但是在流程到达闭包代码的末尾之后,这个值就从内存中消失并且无处使用。
要使您的应用正常运行,您需要做的是在您获得 locationId 后更新单元格的底部标签。您可以通过几种不同的方式进行处理。我会推荐两个类似的。
最简单和最直接的方法是单元能够观察 Firebase 事件并自行更新。
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(YourCellClass.identifier, forIndexPath: indexPath) as! YourCellClass
cell.messagesQuery = messagesRef
return cell
}
在你的单元格代码中,你会有这样的东西:
class YourCellClass: UICollectionViewCell {
static let identifier = String(YourCellClass)
var messagesQuery: FIRDatabaseReference {
didSet {
messagesQuery.observeEventType(.ChildAdded) { [weak self] snapshot in
guard let `self` = self, value = snapshot.value as? [String: AnyObject], locationId = value["location"] as? String else { return }
dispatch_async(dispatch_get_main_queue()) {
self.bottomLabel.attributedText = NSAttributedText(string: locationId)
}
}
}
}
// all your other cell code goes here
}
一个不同的更好的选择是使用 MVVM 并且单元格的视图模型将负责获取位置,单元格将观察它的视图模型并自行更新,但我认为这有点对你来说现在要学的东西太多了 ;)
P.S。请记住,我写了这段代码,所以我不能 100% 保证它会立即编译。
我无法通过任何其他方式进行检索。相反,我利用 JSQMessagesViewControllers 其他内置方法来解决我的问题。该框架有一个名为 senderDisplayName 的内置变量。由于我制作的这个应用程序的性质是匿名的,所以我不需要使用它,所以我操纵 senderDisplay 名称来显示用户的位置。
func addMessage(id: String, text: String, displayName: String) {
let message = JSQMessage(senderId: id, displayName: displayName, text: text)
messages.append(message)
}
然后我将 displayName 设置为位置:
private func observeMessages() {
// 1
let messagesQuery = messageRef.queryLimitedToLast(25)
// 2
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
// 3
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
let locationId = snapshot.value!["location"] as! String
// 4
// self.addMessage(id, text: locationId.lowercaseString + ": \n" + text)
self.addMessage(id, text: text, displayName: locationId)
// 5
self.finishReceivingMessage()
Answers.logCustomEventWithName("Visited RoastChat", customAttributes: nil)
}
}
然后我只是使用内置的 attributedTextForCellBottomLabelAtIndexPath
将我的底部标签设置为用户的位置:
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
let message = messages[indexPath.item]
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: message.senderDisplayName)
}
}
效果很好!这就是编程的意义所在,解决问题。
感谢所有帮助我并为我指明正确方向的人。
我正在开发一个消息传递应用程序,我想在消息内容下方显示消息发送的位置。为此,我尝试将用户的位置数据发送到 Firebase,然后尝试检索数据以将其显示为字符串。
获取用户位置工作正常(我正在使用 CoreLocation
这样做),将数据上传到我的 Firebase 实时数据库也是如此。我将位置与每条消息一起保存如下:
让 itemRef = messageRef.childByAutoId() // 1 让消息项 = [ // 2 "text": 文字, "senderId": 发件人编号, "location":获取位置() ] itemRef.setValue(messageItem) // 3
然后尝试用另一种方法检索数据:
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
var locationId: String = ""
let messagesQuery = messageRef
let message = messages[indexPath.item]
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
locationId = snapshot.value!["location"] as! String
print(locationId)
}
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: locationId)
}
}
控制台打印出正确的位置,但我的应用程序中没有显示任何内容。但是,如果我将变量 locationId
替换为任何其他字符串,它就可以工作。
我认为我的问题是 Firebase 检索。
如果有人能帮我解决这个问题,将不胜感激。
下面是我的 class 的其余代码,供参考(以防万一):
class ChatViewController: JSQMessagesViewController, CLLocationManagerDelegate {
// MARK: Properties
//Firebase
var rootRef = FIRDatabase.database().reference()
var messageRef: FIRDatabaseReference!
var locationRef: FIRDatabaseReference!
//JSQMessages
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
var purp = UIColor.init(red:47/255, green: 53/255, blue: 144/255, alpha: 1)
var roastish = UIColor.init(red: 255/255, green: 35/255, blue: 35/255, alpha: 1.0)
var orangish = UIColor.init(red: 231/255, green: 83/255, blue: 55/255, alpha: 1.0)
var gray = UIColor.init(red: 241/255, green: 251/255, blue: 241/255, alpha: 1)
//Location
var city: String = ""
var state: String = ""
var country: String = ""
var locationManager = CLLocationManager()
func getLocation() -> String {
if city == ("") && state == ("") && country == (""){
return "Planet Earth"
}
else {
if country == ("United States") {
return self.city + ", " + self.state
}
else {
return self.city + ", " + self.state + ", " + self.country
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Initialize location
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
//collect user's location
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.requestLocation()
locationManager.startUpdatingLocation()
}
// Change the navigation bar background color
navigationController!.navigationBar.barTintColor = gray
self.navigationController!.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "Avenir Next", size: 20)!]
title = "RoastChat"
setupBubbles()
// No avatars
// Remove file upload icon
self.inputToolbar.contentView.leftBarButtonItem = nil;
// Send button
self.inputToolbar.contentView.rightBarButtonItem.setTitle("Roast", forState: UIControlState.Normal)
// Send button color
self.inputToolbar.contentView.rightBarButtonItem.setTitleColor(roastish, forState: UIControlState.Normal)
// Input bar text placeholder
self.inputToolbar.contentView.textView.placeHolder = "RoastChat"
collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
//Firebase reference
messageRef = rootRef.child("messages")
locationRef = rootRef.child("locations")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
observeMessages()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//--- CLGeocode to get address of current location ---//
CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
if let pm = placemarks?.first
{
self.displayLocationInfo(pm)
}
})
}
func displayLocationInfo(placemark: CLPlacemark?)
{
if let containsPlacemark = placemark
{
//stop updating location
locationManager.stopUpdatingLocation()
self.city = (containsPlacemark.locality != nil) ? containsPlacemark.locality! : ""
self.state = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea! : ""
self.country = (containsPlacemark.country != nil) ? containsPlacemark.country! : ""
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error while updating location " + error.localizedDescription)
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item] // 1
if message.senderId == senderId { // 2
return outgoingBubbleImageView
} else { // 3
return incomingBubbleImageView
}
}
override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
roastish)
}
func addMessage(id: String, text: String) {
let message = JSQMessage(senderId: id, displayName: "", text: text)
messages.append(message)
}
override func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
as! JSQMessagesCollectionViewCell
let message = messages[indexPath.item]
if message.senderId == senderId {
cell.textView!.textColor = UIColor.whiteColor()
} else {
cell.textView!.textColor = UIColor.whiteColor()
}
return cell
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!,
senderDisplayName: String!, date: NSDate!) {
let itemRef = messageRef.childByAutoId() // 1
let messageItem = [ // 2
"text": text,
"senderId": senderId,
"location": getLocation()
]
itemRef.setValue(messageItem) // 3
// 4
JSQSystemSoundPlayer.jsq_playMessageSentSound()
// 5
finishSendingMessage()
Answers.logCustomEventWithName("Message sent", customAttributes: nil)
}
private func observeMessages() {
// 1
let messagesQuery = messageRef.queryLimitedToLast(25)
// 2
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
// 3
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
// 4
self.addMessage(id, text: text)
// 5
self.finishReceivingMessage()
Answers.logCustomEventWithName("Visited RoastChat", customAttributes: nil)
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
var locationId: String = ""
let messagesQuery = messageRef
let message = messages[indexPath.item]
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
locationId = snapshot.value!["location"] as! String
print(locationId)
}
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: locationId)
}
}
override func collectionView(collectionView: JSQMessagesCollectionView, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout, heightForCellBottomLabelAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return kJSQMessagesCollectionViewCellLabelHeightDefault
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAtIndexPath indexPath: NSIndexPath!) {
super.collectionView(collectionView, didTapMessageBubbleAtIndexPath: indexPath)
let data = self.messages[indexPath.row]
print("They tapped: " + (data.text))
}
}
99% 的时间,当您从 Internet 检索一些数据时 - 就像这里的情况一样,您观察到 Firebase 事件以获取其他用户发送的位置 - 代码以异步方式工作。
这意味着当您检索位置时触发的闭包将独立于 attributedTextForCellBottomLabelAtIndexPath 函数的其余部分进行调用。
因此,当您实际获取位置时,该函数已经返回了使用空 locationId 创建的 NSAttributedString;为什么是空的?因为您已将其初始值设置为“”。 调用 messagesQuery.observeEventType 时传递的闭包在本地捕获 locationId 属性,因此您可以将其设置为从 API 中检索到的内容,打印工作正常。但是在流程到达闭包代码的末尾之后,这个值就从内存中消失并且无处使用。
要使您的应用正常运行,您需要做的是在您获得 locationId 后更新单元格的底部标签。您可以通过几种不同的方式进行处理。我会推荐两个类似的。
最简单和最直接的方法是单元能够观察 Firebase 事件并自行更新。
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(YourCellClass.identifier, forIndexPath: indexPath) as! YourCellClass
cell.messagesQuery = messagesRef
return cell
}
在你的单元格代码中,你会有这样的东西:
class YourCellClass: UICollectionViewCell {
static let identifier = String(YourCellClass)
var messagesQuery: FIRDatabaseReference {
didSet {
messagesQuery.observeEventType(.ChildAdded) { [weak self] snapshot in
guard let `self` = self, value = snapshot.value as? [String: AnyObject], locationId = value["location"] as? String else { return }
dispatch_async(dispatch_get_main_queue()) {
self.bottomLabel.attributedText = NSAttributedText(string: locationId)
}
}
}
}
// all your other cell code goes here
}
一个不同的更好的选择是使用 MVVM 并且单元格的视图模型将负责获取位置,单元格将观察它的视图模型并自行更新,但我认为这有点对你来说现在要学的东西太多了 ;)
P.S。请记住,我写了这段代码,所以我不能 100% 保证它会立即编译。
我无法通过任何其他方式进行检索。相反,我利用 JSQMessagesViewControllers 其他内置方法来解决我的问题。该框架有一个名为 senderDisplayName 的内置变量。由于我制作的这个应用程序的性质是匿名的,所以我不需要使用它,所以我操纵 senderDisplay 名称来显示用户的位置。
func addMessage(id: String, text: String, displayName: String) {
let message = JSQMessage(senderId: id, displayName: displayName, text: text)
messages.append(message)
}
然后我将 displayName 设置为位置:
private func observeMessages() {
// 1
let messagesQuery = messageRef.queryLimitedToLast(25)
// 2
messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in
// 3
let id = snapshot.value!["senderId"] as! String
let text = snapshot.value!["text"] as! String
let locationId = snapshot.value!["location"] as! String
// 4
// self.addMessage(id, text: locationId.lowercaseString + ": \n" + text)
self.addMessage(id, text: text, displayName: locationId)
// 5
self.finishReceivingMessage()
Answers.logCustomEventWithName("Visited RoastChat", customAttributes: nil)
}
}
然后我只是使用内置的 attributedTextForCellBottomLabelAtIndexPath
将我的底部标签设置为用户的位置:
override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
let message = messages[indexPath.item]
if message.senderId == senderId {
return nil
} else {
return NSAttributedString(string: message.senderDisplayName)
}
}
效果很好!这就是编程的意义所在,解决问题。
感谢所有帮助我并为我指明正确方向的人。