我正在使用消息傳遞應用程序,並且想要顯示消息內容的消息發送位置。我嘗試將用戶的位置數據發送到Firebase,然後嘗試檢索數據以將其顯示爲字符串。從Firebase中檢索文本時未顯示在應用程序中
獲取用戶位置正常(我使用CoreLocation
這樣做),因爲上傳數據到我的Firebase實時數據庫。餘與每個消息一起保存的位置爲這樣:
讓的itemref = messageRef.childByAutoId()// 1 讓messageItem = [// 2 「文本」:文本, 「senderId」:senderId, 「位置「:的getLocation() ] 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檢索。
如果有人能幫我解決這個問題,那將不勝感激。
這裏是代碼的其餘部分我的類引用(以防萬一):
類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))
}
}
謝謝!這非常詳細。我只有一個問題,我的單元代碼是什麼意思?你可能看過我包含的代碼,但是我的程序中會包含哪一個類,因爲我很困惑它會是哪一個......再次感謝! –
好的,我忽略了你正在使用某種JSQ集合視圖而不是你自己的事實。在這種情況下,如果可以輕鬆子類化JSQMessagesCollectionViewCell,則可以創建自己的子類,該子類實現獲取位置並將其用於現在使用的位置。有時候,當你繼承了基類的實現時,你必須手動重新實現,但我認爲這不是這種情況。 –
如果您無法創建工作子類,則可以創建一個能夠獲取位置的對象,並在完成閉包中,您的代碼將通過cellForRowAtIndexPath獲取適當的單元格,並將其設置爲底部標籤。這個對象將是你的視圖控制器的一個屬性,你將在viewDidLoad中實例化它。或者,您可以存儲位置ID數組,並將其寫入閉包中,並在collectionView上觸發reloadData(或更新單個indexPath)。爲底部標籤返回適當文本的委託方法將從該數組中獲取它的值。 –