2016-08-01 11 views
1

私はJSQMessagesViewControllerフレームワークを使って構築したシンプルなメッセージングアプリケーションを持っています。私はCoreLocationを使用してユーザーの場所を収集しようとしており、その場所を実際のメッセージの内容(attributedTextForCellBottomLabelAtIndexPath)で表示したいと考えています。私はそれをすべて考え出しましたが、問題はそれぞれの場所が個々のメッセージにユニークである必要があり、それが動作していないということです。ユーザーの場所を表示

たとえば、ユーザーがシアトルからメッセージを送信すると、そのメッセージの下に「シアトル」と表示されます。また、別のユーザーがサンフランシスコに別のメッセージを送信すると、そのメッセージの下に「サンフランシスコ」と表示されます。

現在、何が起こっているかは、ユーザーが現在いる場所(シアトルにいると仮定)からのメッセージです。したがって、他の人物がサンフランシスコにいるかどうかは関係ありません。メッセージには、シアトル出身のメッセージが表示されます。

それはかなり紛らわしい問題ですが、私は仮定迷惑1は、簡単な修正を持っている必要があります...ここで

attributedTextForCellBottomLabelAtIndexPathのコードです:

override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! { 

     let message = messages[indexPath.item] 

     // Call data I have retrieved below with message 
     let text = getLocation() 

     if message.senderId == senderId { 
      return nil 
     } else { 
      return NSAttributedString(string: text) 
     } 

    } 

注:私は持っていますgetLocation()という関数は、単純にユーザーの都市/都道府県/国を返します。

ここでは残りのコードを示しますコンテキストのEクラスChatViewController

/* 
* Copyright (c) 2016 Ahad Sheriff 
*/ 

import UIKit 
import Firebase 
import JSQMessagesViewController 
import CoreLocation 

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! 

    //Location 
    var city: String = "" 
    var state: String = "" 
    var country: String = "" 
    var locationManager = CLLocationManager() 
    var locationId: String = "" 

    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() 
     } 

     title = "Chat" 
     setupBubbles() 
     // No avatars 

     // Remove file upload icon 
     self.inputToolbar.contentView.leftBarButtonItem = nil; 
     // Send button 
     self.inputToolbar.contentView.rightBarButtonItem.setTitle("Send", forState: UIControlState.Normal) 

     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! : "" 

      print(getLocation()) 

     } 

    } 


    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(
      purp) 
     incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
      redish) 
    } 

    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 
     ] 
     itemRef.setValue(messageItem) // 3 

     let locRef = locationRef.childByAutoId() 
     let locItem = [ 
      senderId : [ 
       "location": getLocation() 
      ] 
     ] 

     locRef.setValue(locItem) 

     // 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! { 

     let message = messages[indexPath.item] 

     // Call data I have retrieved below with message 
     let text = getLocation() 

     if message.senderId == senderId { 
      return nil 
     } else { 
      return NSAttributedString(string: text) 
     } 

    } 

    override func collectionView(collectionView: JSQMessagesCollectionView, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout, heightForCellBottomLabelAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     return kJSQMessagesCollectionViewCellLabelHeightDefault 
    } 

} 

注:また、私はFirebaseにユーザーの位置を保存していたコードを無視することができます。

ご協力いただきありがとうございます。ご質問がある場合はお知らせください。

答えて

2

問題は、メッセージのデータではなくクライアントの下部メッセージラベルを設定していることです。したがって、すべてのボトムラベルは、メッセージの発信者ではなくユーザーによって設定されます。

シアトルにいるMarkと、シアトルにいないDericの間に会話がある場合は、基本的にロケーションデータが取得されていることがわかりません。

EX.Conversation

マークこんにちは

(デリック・ワン)Wazzup

あなたがローカルクライアントからの位置データを取得していると、この機能でそれを設定しているので、それは常に、シアトルを言うだろう。

func getLocation() 

だから、Markも、 『(デリック・ワン)』からのメッセージのための場所の電話はあなたがMarkに基づいて位置データを設定している」から会話を見たとき。

これを解決する方法は、位置データをメッセージに保存してfirebaseに保存することです。次に、この関数を変更してボトムラベルのデータを取得します。これらの線に沿って何か。

override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! { 

let message = messages[indexPath.item] 

// Call data I have retrieved below with message 
let text = message.location <- Here is a suggested solution **** 

if message.senderId == senderId { 
    return nil 
} else { 
    return NSAttributedString(string: text) 
} 

は}私はそれは明らかだった願っています。私はその混乱しやすい質問とほぼ同じくらい混乱する答えを知っています。しかし、本質的には、その場所をmessageDataに保存して、バックエンドfirebaseにポストし、それを指定されたメッセージに表示する必要があります。

私はあなたが間違いなく1つの部分を欠落している正しい道にいると思います。

編集: 私はこの https://firebase.googleblog.com/2015/09/introducing-multi-location-updates-and_86.html

を見てみましょうが、私はちょうど位置データを解析し、firebaseのメッセージオブジェクトに保存します物事を簡単にするために、あなたがそれを処理する必要はありませんメッセージを表示しようとしているときにクライアント側で

+0

ありがとうございました!どのように私がデータを保存することができます/あなたはそうするための構文の知識を持っているかのようにデータを取得するための任意のアイデアを持っていますか? –

+0

それはそれのためのfirebaseのドキュメンテーションでしょう。 –

+0

私は一見をして参照してください –

関連する問題