LoginSignup
65
54

More than 3 years have passed since last update.

【Swift】Firebase Realtime Database を用いてチャットアプリを爆速コーディングしてみた。

Last updated at Posted at 2019-06-27

はじめに

本記事で分かること

  • Firebaseで新規プロジェクトの作成〜アプリにFirebaseを組み込むまで
  • Firebase Realtime Databaseを用いた超簡易的なチャットアプリ

本記事で分からないこと

  • Firebaseのアカウント作成
  • いい感じのUIのアプリ

完成形

1. Firebaseで新規プロジェクトの作成

まず、Firebase へアクセスして、コンソールへ移動。
下記の赤枠箇所より、新規プロジェクトを追加。
Screen Shot 2019-07-02 at 3.25.07 PM.png
下記のように、プロジェクト名、アナリティクスの地域を選択してプロジェクトを作成。

Screen Shot 2019-07-02 at 3.25.20 PM.png Screen Shot 2019-07-02 at 3.25.45 PM.png

これで作成完了。

2. アプリにFirebaseを導入

CocoapodsでFirebaseを導入します。
詳細は、公式ドキュメントを参照してください。

コマンド実行後は、拡張子が.xcworkspaceとなっている方からプロジェクトを開くようにしてください。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
スクリーンショット 2019-06-27 21.09.33.png

2. Firebaseコンソール画面でiOSアプリの作成

ここからはFirebase公式の手順に従ってください。
先程作成したプロジェクトのページから、以下の赤枠をクリック
Screen Shot 2019-07-02 at 3.26.13 PM.png

バンドルIDはXcode上の赤枠の項目を参照
Screen Shot 2019-07-02 at 3.36.37 PM.png

スクリーンショット 2019-06-27 21.22.26.png

後はFirebaseの画面上のステップ通りに進めてください。

Screen Shot 2019-07-02 at 3.39.55 PM.png Screen Shot 2019-07-02 at 3.40.11 PM.png

こちらについては、
今回導入するのは、Firebase/core と Firebase/Database になります。

以下コマンドでpodfileの作成。

shell
pod init

podfileの内容は下記になります。プロジェクト名は各々変更してください。

podfile
source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '10.0'
use_frameworks!
target 'firebase-chatting' do
  pod 'Firebase/Core'
  pod 'Firebase/Database'
end

そしたら、以下のコマンドを実行しましょう。

shell
pod install
Screen Shot 2019-07-02 at 3.40.30 PM.png
AppDelegate.swift
import UIKit
import Firebase //←add this line

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions:
      [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure() //←add this line
    return true
  }
}

画面左上の「>」ボタンを押して、アプリをRunしてください。
Screen Shot 2019-07-02 at 3.45.39 PM.png

Screen Shot 2019-07-02 at 3.45.02 PM.png

はい!これでFirebaseの導入は完了です!!
ここまでだいたい10秒ですかね、、www笑

3. RealTimeDatabaseのルールを変更

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

ルールを上記のように設定して、読み込み権限、書き込み権限を与えます。
設定する場所はこちら↓↓↓
Screen Shot 2019-07-02 at 3.50.56 PM.png

4. UI画面の作成

Xcodeの右上の赤枠の箇所をクリックして、UI部品の選択画面を表示する。
スクリーンショット 2019-06-27 21.44.57.png

テキスト表示用のUITextViewをドラッグ&ドロップ
スクリーンショット 2019-06-27 21.37.29.png

UITextViewにConstraints(制約)を付与
今回はSafeAreaに対して、余白15の制約をつけます。
スクリーンショット 2019-06-27 21.38.04.png

画面下部にテキスト入力用のUIViewをドラッグ&ドロップ
スクリーンショット 2019-06-27 21.38.47.png

UIViewの制約をSafeAreaに対して、左0,右0,下0で付与する
スクリーンショット 2019-06-27 21.56.05.png

UIViewの中に入力用のUITextFieldを配置(2つ)
スクリーンショット 2019-06-27 21.40.35.png

UIViewの中にコメント送信用のボタンを配置
スクリーンショット 2019-06-27 21.40.47.png

各部品に制約を付与
スクリーンショット 2019-06-27 21.42.45.png
スクリーンショット 2019-06-27 21.43.25.png
スクリーンショット 2019-06-27 21.43.58.png

これで一旦画面は作成完了です。
スクリーンショット 2019-06-27 22.01.37.png

5.配置したUI部品とコードの紐づけ

Xcode右上の赤枠の箇所を選択して、画面分割させます。
スクリーンショット 2019-06-27 22.03.38.png

左側がstoryboard。右側がViewControlle.swiftが開かれている状態にします。
スクリーンショット 2019-06-27 22.05.28.png

左のstoryBoardから、controlを押しながらドラッグ&ドロップします。
名前は適当につけてください。
UITextViewとUITextFieldを紐づけてください。
スクリーンショット 2019-06-27 22.09.14.png

ボタンはActionを指定して同じように紐づけてください。
スクリーンショット 2019-06-27 22.13.55.png

最後に、画面下部のView.bottomとSafeArea.bottomにつけられている制約も同じくドラッグ&ドロップで紐づけます。
スクリーンショット 2019-06-27 22.15.50.png

6. データの読み込み処理

初期設定

Database.database().reference()でインスタンスを取得します。

ViewController.swift
    var databaseRef: DatabaseReference!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        databaseRef = Database.database().reference()
        

データの読み込み

observeでイベントの監視を行います。
.childAddedを指定することで、子要素が追加されたときにwithで与えた処理が実行されます。
データに追加があると自動で呼ばれるので、更新処理を実装する必要はありません。

ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        
        databaseRef = Database.database().reference()
        
        databaseRef.observe(.childAdded, with: { snapshot in
            if let obj = snapshot.value as? [String : AnyObject], let name = obj["name"] as? String, let message = obj["message"] {
                let currentText = self.textView.text
                self.textView.text = (currentText ?? "") + "\n\(name) : \(message)"
            }
        })
        
    }

7. データの書き込み

ボタンを押した時に、UITextField2つに入力されている値を送信します。

ViewController.swift
    @IBAction func tappedSendButton(_ sender: Any) {
        view.endEditing(true)
        
        if let name = nameInputView.text, let message = messageInputView.text {
            let messageData = ["name": name, "message": message]
            databaseRef.childByAutoId().setValue(messageData)
            
            messageInputView.text = ""
        }
    }

ここまでで、一旦動かしてみてください。
入力時に入力域がキーボードで隠れてしまいますよね、、
なので、ここからはおまけ的にキーボードに入力域が隠れないようにする方法を紹介します。

8. 入力域がキーボードで隠れないように動的に入力域の位置を変更

ViewDidload内に以下を追記。
こちらは、キーボードが表示されるタイミングと非表示になるタイミングを監視してくれるものになります。

ViewController.swift
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil)

そしたら、上記によって呼び出されるメソッドにて入力域の末端の制約を動的に変更させます。

ViewController.swift
    @objc func keyboardWillShow(_ notification: NSNotification){
        if let userInfo = notification.userInfo, let keyboardFrameInfo = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            inputViewBottomMargin.constant = keyboardFrameInfo.cgRectValue.height
        }
        
    }
    
    @objc func keyboardWillHide(_ notification: NSNotification){
        inputViewBottomMargin.constant = 0
    }
    

9. 完成

これで完成です!!

最後にViewControllerの全貌を貼っておきます。

ViewController.swift
import UIKit
import FirebaseDatabase

class ViewController: UIViewController {
    
    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var nameInputView: UITextField!
    @IBOutlet weak var messageInputView: UITextField!
    @IBOutlet weak var inputViewBottomMargin: NSLayoutConstraint!
    
    var databaseRef: DatabaseReference!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        databaseRef = Database.database().reference()
        
        databaseRef.observe(.childAdded, with: { snapshot in
            dump(snapshot)
            if let obj = snapshot.value as? [String : AnyObject], let name = obj["name"] as? String, let message = obj["message"] {
                let currentText = self.textView.text
                self.textView.text = (currentText ?? "") + "\n\(name) : \(message)"
            }
        })
        
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil)
        
    }

    @IBAction func tappedSendButton(_ sender: Any) {
        view.endEditing(true)
        
        if let name = nameInputView.text, let message = messageInputView.text {
            let messageData = ["name": name, "message": message]
            databaseRef.childByAutoId().setValue(messageData)
            
            messageInputView.text = ""
        }
    }
    
    @objc func keyboardWillShow(_ notification: NSNotification){
        if let userInfo = notification.userInfo, let keyboardFrameInfo = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            inputViewBottomMargin.constant = keyboardFrameInfo.cgRectValue.height
        }
        
    }
    
    @objc func keyboardWillHide(_ notification: NSNotification){
        inputViewBottomMargin.constant = 0
    }
    
}

最後に

実際にだいたい1時間くらいで実装できてしまったので、ほんとに驚きです。
今後Firebaseの諸々を調査していく予定です。

よかったらいいねください!!

参考記事

Firebase を使って30分でiOSのチャットアプリを作ってみる(新SDK対応版)
【Swift】リアルタイムチャットを実現するFirebaseでCRUD(データ作成、読み込み、更新、削除)をやってみる

GitHubはこちら

65
54
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
54