CrossBridge Lab

技術ネタ、デバイスネタを...

Firebase を使って30分でiOSのチャットアプリを作ってみる

本記事の内容は2016年5月に発表された新しいSDKについてではなく、古いSDKの記事になります。新しいSDKについては以下の記事を参照してください。

crossbridge-lab.hatenablog.com


はじめに

BaaS の1つである Firebase の勉強がてらサンプル的なiOSのチャットアプリを作ったメモです。Firebaseの使い方はとても簡単でした。

f:id:crossbridge-lab:20160225075107p:plain

Firebaseとは

Firebase とはチャットアプリのようなリアルタイムにデータを同期する必要があるサービスに適しているバックエンドサービスです。データはSQLではなくJSONのオブジェクトとして保存されます。Parse を使おうとした矢先に終了のお知らせが出てしまったので、何か他のサービスを使ってみようと Firebase を選んでみました。 ※使う理由としてはチャットアプリではないのですがまずは勉強に簡単なチャットアプリをということです。

REST APIの他、以下のSDKが用意されています。

アカウント登録

https://www.firebase.com からGoogleアカウントで SIGN UP すれば完了です。速い。

管理画面

ログインすると Dashboard (管理画面)が表示されます。初回ログイン時にすでにMY FIRST APPと名前でアプリが1つ登録されています。そこに表示されているhogehoge.firebaseIO.comというのがエンドポイントになります。

f:id:crossbridge-lab:20160225075118p:plain

ここで新たにアプリを登録することが出来ますがとりあえず今回はそのままで。

CocoaPodsでSDKを導入

Xcodeで新規プロジェクトを作ったらCocoaPodsでSDKをさくっと入れます。

pod 'Firebase'

UIを適当に作る

UITextView と UITextField x 2 の極めてダサいシンプルなUIにします。

f:id:crossbridge-lab:20160225075126p:plain

Outletも忘れずに。

@IBOutlet weak var textView: UITextView!
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var messageTextField: UITextField!

初期設定

firebaseRef = Firebase(url:"https://<your-firebase-app>.firebaseio.com/chat/message")

エンドポイントを与えてFirebaseクラスのインスタンスを生成します。 https://ほげほげ.firebaseio.com/ ではなく https://ほげほげ.firebaseio.com/chat/message のように要素の名前を先に指定することもできます。

※データはJSONで保存される

データの読み込み

observeEventTypeメソッドが名前の通りイベントを監視するメソッドです。ここでは.ChildAddedを指定して子要素が追加されたときにwithBlockで与えた処理が実行されるようにしています。データに追加があると自動で呼ばれるので、更新ボタンやPull to refreshを実装する必要はありません。

snapshotというのが追加されたデータで、そこからnameとmessageの値を取り出してTextViewに追記していきます。

firebaseRef.observeEventType(.ChildAdded, withBlock: { snapshot in
    if let name = snapshot.value.objectForKey("name") as? String,
        message = snapshot.value.objectForKey("message") as? String {
            self.textView.text = "\(self.textView.text)\n\(name) : \(message)"
    }
})

データの書き込み

送信ボタンを作るのも面倒なのでReturn入力時に送信するようにしています。childByAutoIdメソッドがランダムな名前の子要素を作るメソッドで、setValueメソッドでデータを書き込みます。Dictionaryを作って与えています。

func textFieldShouldReturn(textField: UITextField) -> Bool{
    
    let messageData = ["name": nameTextField.text!, "message": messageTextField.text!]
    firebaseRef.childByAutoId().setValue(messageData)
    
    textField.resignFirstResponder()
    messageTextField.text = ""
    
    return true
}

実際には以下のようにデータが保存されます。

f:id:crossbridge-lab:20160225075137p:plain

完成

以上で完成です。多分、30分もかかっていないですね。ViewControllerのソースはキーボードを開いた時にTextFieldを上に持ち上げる処理などを除けば以下のように。

@IBOutlet weak var textView: UITextView!
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var messageTextField: UITextField!
    
var firebaseRef:Firebase!
    
override func viewDidLoad() {
    super.viewDidLoad()
    
    firebaseRef = Firebase(url:"https://ほげほげ.firebaseio.com/chat/message")
    firebaseRef.observeEventType(.ChildAdded, withBlock: { snapshot in
        if let name = snapshot.value.objectForKey("name") as? String,
            message = snapshot.value.objectForKey("message") as? String {
                self.textView.text = "\(self.textView.text)\n\(name) : \(message)"
        }
    })
}

func textFieldShouldReturn(textField: UITextField) -> Bool{
    
    let messageData = ["name": nameTextField.text!, "message": messageTextField.text!]
    firebaseRef.childByAutoId().setValue(messageData)
    
    textField.resignFirstResponder()
    messageTextField.text = ""
    
    return true
}

最後に

でもお高いんでしょ?https://www.firebase.com/pricing.html が料金プランのページです。コネクション数、ストレージの容量、転送量などで分かれています。小さなアプリ(サービス)なら無料でもいけるのでは?といった感じです。

f:id:crossbridge-lab:20160225075145p:plain