こんにちは。
iOS開発者のもぐめっとです。
この度firebaseを使ったサービス第一弾として、「mimicha – 匿名シェアチャットアプリ」をリリースしました。
そこで使った技術やハマった箇所諸々を紹介します。
使ったライブラリ群
車輪の発明は極力避けたいもの。
ということでできるだけライブラリを使って頑張りました。
“SVProgressHUD/SVProgressHUD”
ローディング表示するのに超定番ライブラリ。
最初の匿名ログインのときなど、Firebaseとの通信を待つ必要がある場合に使ってます。
“mac-cain13/R.swift.Library”
これも定番ですね。
ローカライズの言語をAndroidのRみたいなのりで定数を使って呼ぶことができるようになります。
storyboardからの初期化や、Assetの呼び出しなどもR.swiftを使って呼ぶことができるので、文字列違いでうまく表示できなかったといったことが避けられるようになります。
“alickbass/CodableFirebase”
RealtimeDBや、Firestoreの値の一部の方はCodableに対応してないのですが、それを対応させるライブラリ。
しかし、Timestampの変換がうまくできなかったため、結局これは使わずに終わりました。。。
しかし、軽く使う分にはとても便利なので一応紹介。
公式ライブラリ上でもCodableの話は出てるのでもしかしたらいずれ公式SDKにとりこまれるかもしれませんね。
cf: Codable firestore #838
(ただ現在なんかしらないが止まってる)
“vikmeup/SCLAlertView-Swift”
mimichaでは標準のアラートを使わずSCLAlertViewを使っておしゃれなアラートを実装してます。
ただ、MessageKitと一緒に使う際、キーボードの方が上のレイヤーに表示されるという状態になってしまうので、SCLAlertViewを表示する際には、表示前にresignFirstResponder()して、アラートが終わったあとは、becomeFirstResponder()を実行と、ちょっとめんどくさいけど うまく使う必要があります。
“xmartlabs/XLPagerTabStrip”
タブの切り替えができるような感じにするために使ってます。
これを使えば横にスワイプでタブの切替ができるので便利になるんじゃないかなぁ〜と思ってます。
しかし、androidはtabで表示しているので普通にUITabBarControllerで実装してもよかったのかもしれない。。
mimichaでは3つとも部屋の表示のセグメントがちがうだけで、構造は同じなので、表示する部屋をinjectする形で実装して、部屋の表示は同じソースで表現できるようにしています。
“kean/Nuke”
画像非同期読み込みツールのNukeです。
今まではSDWebImageをよく使ってたのですが、中身がObj-cですし、他にもないかと調べたところいろいろ出ており、AlamofireImage、Kingfisher、PINRemoteImageなど出ておました。
Swiftの有名画像キャッシュライブラリを比較してみたを参考にしたところ、Nukeがダントツに飛び抜けて早かったのでこちらを採用させていただきました。
画像のキャッシュの設定はreturnCacheDataElseLoadにしたほうがいいみたいです。
cf: iOSの画像ローダーの選定とキャッシュについて -こうして私はNukeを選んだ-
“ephread/Instructions”
はじめての起動時の使い方説明みたいなやつの実装に使ってます。
注目させたいviewを指定するだけなので割と使いやすいです。
NavigationBarにおいてあるUIBarButtonItemに対して表示するときはすこしコツが必要でした。
こんなかんじ。
1 2 3 4 5 6 7 8 9 10 11 |
@IBOutlet weak var addRoomButton: UIBarButtonItem! func coachMarksController(_ coachMarksController: CoachMarksController, coachMarkAt index: Int) -> CoachMark { let view = addRoomButton.value(forKey: "view") as! UIView return coachMarksController.helper.makeCoachMark(for: view) { (frame: CGRect) -> UIBezierPath in // This will create a circular cutoutPath, perfect for the circular avatar! return UIBezierPath(ovalIn: frame.insetBy(dx: -4, dy: -4)) } } |
“Moya/Moya”
objective-cで通信といえばAFNetworking
swiftで通信といえばAlamofire
そんな2大巨塔になってる(と思ってる)この世界、Alamofireをラップしてさらにいい感じに使えるようにしたのがMoyaです。
Moyaが効果を発揮するのが、unit testや、モックで動作をみたいときになります。
Moayaを使うと簡単に通信をフックしてモックを突っ込めるのがとてもすごいです。
あと、ソースもイケメンにかけるので、通信で使う場合はとても気に入ってるライブラリです。
firestoreを使っているとほとんど通信ライブラリいじらないんですけど、mimichaでは画像アップロードするためにMoyaを使っています。
“MailOnline/ImageViewer”
画像のイメージビューワです。
使い方がシンプルすぎて説明になってない感じだったので別途使い方の記事を描きました。
cf: iOS いい感じに画像のプレビューを出せるImageViewerをサクッと使う
いい感じに簡単にビューワを実装できるのでなかなかいいです。
“ashleymills/Reachability.swift”
後ほど紹介する、RemoteConfigを用いる際に、オフラインでfetchを行うとアプリが固まってしまうというバグが有ったため、fetchを行うのはオンラインのときに限定するために使いました。
オンラインの判定をして通信を行うといった感じですね。
“MessageKit/MessageKit”
チャットはだいぶこいつにおせわになりました。
しかし、ドキュメントがあまり充実してないので結構ソース内を見回したりしました。
ハマったポイントはいくつか別記事にして書いたりしました。
cf: MessageKitでmessageInputBarが消えたときに再表示させる方法
cf: MessageKitでAvatarViewの上にラベルを表示する
cf: MessageKitで画像の非同期読み込みを行う
cf: MessageKitでチャットの長押しを実装する
途中でライブラリ使ってるのになんでこんな使うのに苦戦してるんだと思ったりもしましたが、ちゃんと探せばやり方はあるので、このへんのHowToてきなのがもうちょい公式的にもまとまってるといいですね。
Firebase編
ここからはFirebaseで使ってるものを紹介します。
Cloud Firestore
チャットのコアとなってる技術ですね。
クライアントとして使ってて感じたものや罠としては以下の様な感じ。
- setDataを使うと指定したdocumentIdで作成もしくはデータのセットができる
- merge: trueのオプションをいれると既存のデータが有れば消さずにマージしてくれる
- updateDataはデータがないとエラーになる
- setDataのほうが安全に使えるのでupdateDataよりsetData使ってる
- 2つの値を指定してデータを取るときはそれぞれindexを貼る必要がある
- Timestampのデータを送るときは基本的にFieldValue.serverTimestamp()を使って同期をとるようにする。
- 上記方法でやる場合、場合によっては時間がとれないことがあるので、DocumentSnapshotからDataをとる際には、snapshot.data(with: .estimate)といったかんじでDataをとるようにしている
- サブコレクションを含むドキュメントはサブコレクションを全部削除してから削除しないとゴミが残る。
- ただし、信頼できる場所でサブコレクション削除は行うようにする。→CFで頑張ろう
- cf: Cloud Firestore データモデル
- 複数トランザクションはbatchを使う
- cf: トランザクションと一括書き込み
Firebase Authentication
匿名認証で使っています。
これ使うとtwitter/facebookなどの連携も簡単にできるのでとても便利ですね。
mimichaではログインしないとそもそもfirestoreが使えないので、最初の起動画面で匿名ログインが成功したら画面遷移するようにしています。
Firebase Cloud Messaging
push通知を使うためにこれだけを入れてる方も多いのではないでしょうか。
mimichaでは手動でのプッシュの他、チャット作成時に、CloudFunctionを用いてpush通知を各種端末に送るようにしています。
Google AdMob
広告はこれ。
ネイティブ広告もサポートし始めたので、mimichaではこれも使わせてもらってます。
Firebase Remote Config
アプリのアップデートをしなくてもアプリの動作を変えるために使用しています。
mimichaではアプリの強制アップデートや、微妙な動作変更をするために使用しています。
Firebase Crashlytics
もはやこれも必須といった感じですね。
クラッシュの原因をさぐるために必要なものになりますね。
ただ、iTunes Connectにアップロードしたあと、dsymをアップロードしないと詳細がみれないので要注意です。
その他技術
デプロイ周りとかそこらへんで使ったものの軽く紹介。
(ただしCIは今回は使用していない)
Fabric(beta)
テスターに実機にインストールできるようにするために使用しています。
いまだにTestFlightでもやはり反映が遅いですから少し時間がかかりますもんね。
Fastlane
archiveしてからbetaやiTunesConnectにuploadするのにコマンド一発でできるようにしています。
(ただ、upload_symbols_to_crashlyticsが Shell command exited with exit status instead of 0. と表示されてうまく動かなくていつも手動であげてるので誰か教えてほしい・・・)
さらに、証明書やプロビジョニングプロファイルの管理にmatchも使ったりしています。
これで誰がやってもコマンド一つで簡単にiTunesConnectにアップロードできますね。
mogmetの所感
firestoreを使って初めてアプリを作ってみましたが、本当にサーバ側の仕組みを殆ど作らなくてもチャットシステムができてしまうので私の中では神サービスと崇めています。
ただ、CloudFunctionは少しは作らないといけないのですが、ほんとうにちょっといじるくらいなので目を潰れる範囲かと思っています。
今後もfirestoreを使ってガンガンサービスを出していこうかと思っていますので温かい目で見守ってもらえると幸いです。
“匿名型チャットmimichaを作った際に使ったiOSライブラリ19選” への2件の返信