LINEのクローンアプリを作成してみた

#はじめに
Firebaseの基本的な知識とチャット機能の学習を目的にLINEのクローンアプリを作成しました。アウトプットする場が特になかったので、学習のまとめと作成したアプリの紹介を兼ねて投稿させていただきます。ご興味があればお読み下さい。


#関連記事
下記のYouTube動画のシリーズを参考にさせていただきました。
https://www.youtube.com/watch?v=XandgrGiV-8&list=PLJGQf09UDweLB6NGPoYnNL7j_z0Rzkpgr

また、記事のまとめ方は[こちら](https://qiita.com/yutosa3/items/64ec77f73e72e35e5ff3)を参考にさせていただきました。


#作成したアプリ
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/4370d76b-3ad4-f143-1adc-0f5c88b74fdd.gif)

:octocat: GitHub
https://github.com/ayukin/ChatApp


- 個人的な趣味にはなりますが、画面UIはできる限りLINEに近づけてみました。
- 色は`Google Chrome`の拡張機能`Color Picker`を使うと簡単にわかりました。


#機能紹介
###１．新規登録
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/1a80eadf-d7d7-dbf8-cdd6-d9bdeb7fb2e5.gif)

- プロフィール画像は`フォトライブラリー`から選択するようにしました。`カメラ`の起動も可能でしたが、実機での動作確認は考えていなかったので省きました。
- `メールアドレス`、`パスワード`、`ユーザーネーム`が記入されていれば新規登録可能としました。
- 新規登録処理の際に`UIActivityIndicatorView`を表示、登録エラーの際は`UIAlertController`を表示するようにしました。


###２．ログイン
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/e944e682-9def-f262-f429-0d12488c1d71.gif)

- `メールアドレス`、`パスワード`が記入されていればログイン可能としました。
- ログイン処理の際に`UIActivityIndicatorView`を表示、ログインエラーの際は`UIAlertController`を表示するようにしました。


###３．トークルーム表示・作成
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/ebb9012b-98ae-76c1-7653-a12d1dede42c.gif)

- トーク相手の`ユーザーネーム`、`プロフィール画像`、`最新のメッセージ内容と投稿時間`をCellに表示するようにしております。
- トークルームの作成時には`ログインユーザー`を表示しないようにしています。


###４．リアルタイムチャット機能
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/c1370080-72b3-4cf1-1bd4-23975d59a86f.gif)

- `addSnapshotListener`を用いてリアルタイムで更新がかかるようにしました。
- `tableView`を反転させ下詰めでの表示も考えましたが、メッセージ量が少ない場合に上部にスペースが生まれてしまうので採用しませんでした。


###５．ログインユーザー情報表示・ログアウト
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/8bcdf9e0-7ff4-d15d-72a6-92b49b2b09d6.gif)

- ログインユーザーの情報がどこにも表示されていなかったので設けました。内容としましてはFirestoreからログインユーザーの情報を取得し表示しているのみです。
- `Auth.auth().signOut()`のログアウト処理になります。ログアウト完了後メイン画面となるトークルーム画面に遷移し、ユーザーの認証状態を判別後にログイン画面へ遷移させるようにしております。

###６．Firestoreデータ構造
![スクリーンショット 2020-10-17 19.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/d63b1f55-60c8-148f-0eb3-aaf347e87839.png)



#技術要素
###１．アーキテクチャ
アーキテクチャを意識したことがなかったため、今回はMVCを採用してみました。

####MVC

- Model・・・データの通信、保存、ビジネスロジックなどを扱うもの
- View・・・画面の描画
- Controller・・・ユーザーの操作を受けて`Model`や`View`を書き換えるもの

###２．ライブラリ
####[Firebase](https://firebase.google.com/?gclid=CjwKCAjwrKr8BRB_EiwA7eFapk8EHVyvNc26aec3HxdkyBKiQ-hyuVuvulIMo3_lOCFSYfoCQMGNERoCcbMQAvD_BwE)
- `ユーザー認証`、`画像の保存`、`ユーザー情報の保存`、`メッセージ情報の保存`に使用しています。

####[IQKeyboardManagerSwift](https://github.com/hackiftekhar/IQKeyboardManager)
- `新規登録画面`、`ログイン画面`に使用してます。
- 導入方法も簡単で、複数の`TextField`のカーソル移動が容易になったり、キーボードとの干渉も自動で検知してくれるのですごく良いライブラリだなと感じました。

###３．その他
- ライブラリ管理は`CocoaPods`、ソースコード管理は`GitHub`を使用しました。


#意識したこと
###１．MVCの責務分割
書籍[iOSアプリ設計パターン](https://peaks.cc/books/iOS_architecture)で設計についての知識を深めながら、`Model`・`View`・`Controller`の責務を分割し、`FatViewController`にならないように心がけました。

###２．変数名・メソッド名の意識
初歩的なことではありますが、初学者のレビュー指摘あるあるみたいな記事を読んでいると、直感的にわからない`変数名`やどうのような処理を表しているのか分かりづらい`メソッド名`について書いてありましたので、なるべくわかりやすい命名をするように心がけました。

#今後の課題
追加で下記項目を実装しようと試みましたが、現状の自分のレベルではわからず断念しました。
悔しいですがいつか再チャレンジしようと思います。

- メッセージを日付でセクション？分けして表示（LINEのような表示方法）
- メッセージの既読・未読
- トークルームに未読のカウント数表示

#まとめ
まだまだ初学者レベルの知識や理解にはなりますが、文法やXcodeやUIKit等少しずつ慣れてきました。
今回意識した、アーキテクチャを考えた設計・コードの書き方については、書籍や心優しい先人の方々の記事で概念等はインプットできましたが、やはり実際には責務を分割する作業に手こずりました。
MVCの概念は流派によって解釈に違いがあるとのことですが、初学者の私達は、わかりやすかった記事あるいは教えていただける人の意見を正にひとまず進んでいくことがベストかなと思います。学習を進めていく上で、自分の考えが生まれたり、認識の間違いに気づいたらその時に正せばいいかなと思います。
また、今回の学習目的にしておりました`Firebase`と`チャット機能`の基本的な学習も、あくまで`基本的な内容`にはなりますが力がついたかなと感じます。課題であげたように応用的な内容もこれから実装できるよう精進していこうと思いました。

長々と感想文のような記事になってしまいましたが、最後まで読んで頂きありがとうございました。