質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Swift

    8752questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Firebase

    904questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

swiftのリアルタイムチャット機能について質問があります

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,130

kazuv2

score 2

http://www.atmarkit.co.jp/ait/articles/1606/06/news020_3.html
上記のサイト様を参考にシステムを開発したのですが、実行した際にチャットの順番がぐちゃぐちゃになってしまいます。

原因を探ってみたのですが、全くわかりません、どうかご助力の方お願い致します。

import UIKit
import JSQMessagesViewController
import Firebase
import FirebaseDatabase

class ViewController: JSQMessagesViewController {
    var messages: [JSQMessage] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        senderDisplayName = "tst"
        senderId = "tst"
        let ref = FIRDatabase.database().reference()
        ref.observe(.value, with: { snapshot in
            guard let dic = snapshot.value as? Dictionary<String, AnyObject>
                else{
                    return
            }
            guard let posts = dic["messages"] as? Dictionary<String,
                Dictionary<String,String>> else{
                    return
            }
            self.messages = posts.values.map { dic in
                let senderId = dic["senderId"] ?? ""
                let text = dic["text"] ?? ""
                let displayName = dic["displayName"] ?? ""
                return JSQMessage(senderId: senderId, displayName:
                    displayName, text: text)
            }
            self.collectionView.reloadData()
        })

    }

    override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
        return messages[indexPath.row]
    }

    override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {
        if messages[indexPath.row].senderId == senderId {
            return JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImage(
                with: UIColor(red: 112/255, green: 192/255, blue:  75/255, alpha: 1))
        } else {
            return JSQMessagesBubbleImageFactory().incomingMessagesBubbleImage(
                with: UIColor(red: 229/255, green: 229/255, blue: 229/255, alpha: 1))
        }
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as? JSQMessagesCollectionViewCell
        if messages[(indexPath as NSIndexPath).row].senderId == senderId {
            cell?.textView?.textColor = UIColor.white
        } else {
            cell?.textView?.textColor = UIColor.darkGray
        }
        return cell!
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return messages.count
    }

    override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {

        return JSQMessagesAvatarImageFactory.avatarImage(
            withUserInitials: messages[indexPath.row].senderDisplayName,
            backgroundColor: UIColor.lightGray, textColor: UIColor.white,
            font: UIFont.systemFont(ofSize: 10), diameter: 30)
    }
    override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
        print("beforeA",text, senderId, senderDisplayName, date)
        inputToolbar.contentView.textView.text = ""
        print("A")
        let ref = FIRDatabase.database().reference()
        print("B")
        ref.child("messages").childByAutoId().setValue(
            ["senderId": senderId, "text": text, "displayName": senderDisplayName]as [AnyHashable:Any])
        //print文を挟み、どこまでコードが動いているかをコンソールの方へ出力。
        //as [AnyHashable:Any]を最後に追加  2016/11/02 1:03
        print("C")
    }
}

(追記)参考画像とデーダベースを貼っておきます

イメージ説明

イメージ説明

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

参考サイトのコードを見ると
ref.observeEventType(.Value, withBlock: { snapshot in
でFirebaseデータベース全体のデータを受け取り、
その中からpostsという変数にDictionary型でメッセージ一覧を取り出し、
self.messages = posts.values.map { dic in
でDictionary内のvalueの一覧を取り出していますから、
メッセージが順不同でバラバラに表示されてしまうのは当然だと思います。

その参考サイトを参照するのはやめて
http://qiita.com/ryotakodaira/items/b234d1d51ae6b1110e8b
とか
https://www.raywenderlich.com/140836/firebase-tutorial-real-time-chat-2
を参考にした方がよいと思います。

こちらは、observe(.childAddedでFirebaseからデータを受け取っていますので
投稿した順にデータを受けとって並べられるはずです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Swift

    8752questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Firebase

    904questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。