茶漬けの技術メモ

Golang, Rubyで趣味開発します。テックニュース書いたり。ガジェット触ったり。

【Swift】Firebaseを使ってチャットアプリを作る。3 〜メッセージを送受信できるようにする〜

この記事は、以下の記事の続きとなっております。

【Swift】Firebaseを使ってチャットアプリを作る。1 〜画面を作る〜 - 茶漬けの技術メモ

【Swift】Firebaseを使ってチャットアプリを作る。2 〜Firebase をアプリに追加する〜 - 茶漬けの技術メモ


前回までで、アプリにFirebase を追加することができました。

今回で、Firebase を使ってメッセージを送受信できるようにしていきます!


Firebase のデータベースに書き込む

ViewControlle.swift に以下のコードを追加します。

import Firebase
import FirebaseDatabase

// 送信ボタンを押した時の処理
    override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
        inputToolbar.contentView.textView.text = ""
        let ref = FIRDatabase.database().reference()
        ref.child("messages").childByAutoId().setValue(["senderId": senderId, "text": text, "displayName": senderDisplayName])
    }

didPressSend メソッドはJSQMessagesViewController のコールバックメソッドで、チャットの「Send」ボタンを押すと呼び出されます。
FIRDatabase.database().reference() はFirebaseDatabase のルートを返します。
子要素にmessages を設定し、そこにsetValue メソッドでデータを保存していきます。

ここでアプリを実行し、実際にメッセージを送信します。

f:id:biwako_no_otyazuke:20161130014236p:plain

ここで「Send」ボタンを押すと。

f:id:biwako_no_otyazuke:20161130014427p:plain

Firebase のDatabase にデータが保存されていますね!
※ここで表示されている、date は後に実装するので、今は無視してください。

メッセージを動的に表示する

Firebase のDatabase にデータを保存することができたので、これから、そのデータを取得し、画面上に表示していきます。
また、Firebase のRealtime Database では、サーバー上のデータに変更があった場合に、各クライアントに処理を行うことができます。
この機能により、自分以外の人が送信したメッセージをリアルタイムで画面に表示することができます。

ViewControlle.swift を以下のように変更します。

class ViewController: JSQMessagesViewController {
    
    var messages = [JSQMessage]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        senderDisplayName = "tsuru"
        senderId = "Tsuru"
        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, AnyObject>> 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()
    }
}



ここでアプリを実行すると、

f:id:biwako_no_otyazuke:20161130112440p:plain

先ほど送ったメッセージが表示されていることがわかります。

さらにメッセージを送っていきます。

f:id:biwako_no_otyazuke:20161130112605p:plain

    override func viewDidLoad() {
        super.viewDidLoad()
        senderDisplayName = "gami"
        senderId = "Gami"
        let ref = FIRDatabase.database().reference()


このようにアカウントを変えて実行すると、

f:id:biwako_no_otyazuke:20161130112827p:plain

別ユーザーとして表示できていることがわかります。

アカウントを戻して、その後もメッセージを送信していくと。。。

f:id:biwako_no_otyazuke:20161130113110p:plain

あ。

あれ。。。。。

f:id:biwako_no_otyazuke:20161130113213p:plain

あれれれれれれれ。。。

メッセージの順番がめちゃくちゃになっとるがな。。。。。

メッセージを順番に表示する

メッセージがなぜか順番通りに表示されていないので、修正を次回で実装していきます!!


続きはこちら

【Swift】Firebaseを使ってチャットアプリを作る。4 〜メッセージを順番通りに表示する〜 - 茶漬けの技術メモ