iOSアプリ初心者がFirestoreでライフログアプリを作った話

先日「[声で操作できるライフログアプリ Tracka(トラッカ)](https://itunes.apple.com/jp/app/id1378085912)」を個人開発でリリースしました。
この記事では

- 初心者がどのようにiOSアプリの開発を学んだか
- どのように技術調査や開発を進めたか
- 使用ライブラリ

について書きます。個人開発アプリ/サービスを出そうとしている方の参考になればと思います。 🙏

# アプリ概要

![アプリ画面1](https://qiita-image-store.s3.amazonaws.com/0/81874/2da6ef2a-b617-bbb1-50c2-873fe5a471b2.png)

![アプリ画面2](https://qiita-image-store.s3.amazonaws.com/0/81874/39b7b3dd-1f36-9fc7-5f12-0caae66ada91.png)


- 時間に特化したログアプリで、どう時間を過ごしたかを記録、分析できる
- 「Trackaで読書の記録を開始」のように話すだけで記録を開始できる
- 記録した時間はリアルタイムにダッシュボード画面に集計表示する
- Googleカレンダーと連携可能で、スケジュールの開始時刻に届く通知をタップすることでも記録を開始できる
- アクティビティ(記録したい項目)ごとにタイマーを設定可能(筆者はポモドーロタイマーとして使ったり、ネットサーフィンのしすぎを防ぐために使っている)

技術的には

- Sirikitを使って音声に対応
- データストアはFirestoreをRxswiftでラップして使う
- その他FirebaseのFireauth(ログイン), Crashlytics(エラー検知), FirebasePerformance(分析), Admob(広告)を使用 

という感じです。


# 開発の流れ

## テーマを決める

「作りたいものを作ろう」というのはよく個人開発の記事で言われているかと思います。
今回例に漏れず自分が作りたいものとしてライフログアプリに決めました。
これまでいくつかライフログアプリを触ってみて、

- 記録をつけるのにいちいちアプリを開いて操作するのが面倒
- 集計のために何度もポチポチするのが面倒

という思いがあり、「声で記録ができる、アプリを起動したら最初から集計結果が表示されている」ようなアプリにしたいと思いました。
当時は2016年の春で、WWDCでiOS10からSiriと連携出来るようになることが発表され、「これや！」と思って開発を始めました。
開発にあたって、アプリの目指す姿として**「簡単、楽に時間を記録し、手触りを持って振り返る」**と明文化しました。
これのおかげか、元から作りたいイメージが固まっていたおかげかはわかりませんが、開発中作りたいものがブレることはなかったように思うので、テーマを明文化しておくと良いかも知れません。

## iOSアプリの作り方を学ぶ

開発を始めた当時は業務でモバイルゲームを作っていたのですが、webの知識が要求される部分を作っていてiOSアプリの知識はほぼ0でした。

作り始める段階でReactNativeやRxSwiftの存在は知っていたものの、最初から手を出すと詰まった時にすぐ挫折しそうに思って素のアプリとして作ることにしました。(当時はReactの経験もなかったので）

最初にざっくり全体像を把握したいと思い、"iPhoneアプリの教科書"という本を読みました。
文法や標準UIの種類や使い方がなんとなくわかりました。
その後は、実際に作りながら

- まず概要を Qiitaやyoutubeのtutorialビデオ（技術系youtuber?が解説してるようなやつ） で掴む
- 細かい部分は公式のドキュメントを参照
- 詰まったらStuck overflow, teratail, ググりまくる

と言った感じで進めていきました。
**特にyoutubeのtutorialビデオはXcodeの操作がおぼつかない最初期の段階で理解を深めるのにとても助けられました。**

## ライブラリの選定

個人開発ではリソースが圧倒的に足りないので、ベータ状態のライブラリでも使っていきたいと思いました。
[iOS開発が捗るライブラリの探し方](https://qiita.com/tdkn/items/e6e7396e8c803e571a40) のような記事はとても参考になりますね！
(当時はこういうのを知らずに、適当なワードでぐぐって探していましたが😅）

最初に悩んだのはデータストアをどうするか で、

- Apple製のCore Data
- Realm

の２つを検討したのですが、Realm Object Serverがサーバサイドアクセスに対応している　というのが決め手でRealmにしました。
(サーバサイドに保存することで、端末の移行や、IFTTT/Slackとの連携などより便利な機能を作れそうに思った）

## Firestore登場の衝撃

Realmでデータの保存・集計機能を作り、GCEにRealm Object Serverも立ててfireauthの認証が使えるように[custom provider](https://docs.realm.io/platform/v/master/customize/authentication/custom-authentication) も頑張って書いたあとの2017年10月...

Firestoreの登場である。

ネット上での評判は良いし、**サーバサイドアクセスに追加料金がかからない** というのに衝撃を受けてFirestoreへの乗り換えを決意しました。
(当時Realm Object Server ではEnterprise Edition(?) という $1500/月 のものに入らないとサーバサイドアクセスが出来ませんでした）

Realmの場合は

```
let realm = try! Realm()
let records = realm.objects(Hoge.self).filter(...)
```

という感じで同期的にレコードを取得できるものの、Firestoreでは

```
let docRef = db.collection("cities").document("SF")

docRef.getDocument { (document, error) in
    if let document = document, document.exists {
        let doc = document.data()
    }
}
```

という感じでコールバックを渡して非同期に結果を受け取る作りなので、噂に聞くRxSwiftの使い所っぽいなと思ってRxSwiftに手を出しました。
**RxSwiftを理解するのに [オブザーバーパターンから始めるRxSwift入門](https://qiita.com/k5n/items/17f845a75cce6b737d1e) がめっっっっちゃくちゃ参考になりました。**
これさえ繰り返し読んで理解できるようになればokだと思います。

FirestoreとRxSwiftを組み合わせる部分は @mono0926 さん？の [こちら](https://gist.github.com/mono0926/ae6c491862370348ad4b4fcc7b4a5556) を参考にさせていただきました。 🙇🙇🙇


## デザインどうする問題

UIデザインは、最初知り合いのデザイナーに頼もうとしたのですが都合がつかなかったので自分ですることにしました。
アプリを作り始める前は、頭の中でGoogleの[Material Design](https://material.io/)っぽい見た目やインタラクションを入れて・・と妄想していたのですが、厳密に出来るほどの力も時間もないので諦めましたｗ
今なら[Flutter](https://flutter.io/)がありますね、興味ある。。

実際にUIを作り始めるにあたっては、

- 手書きのワイヤーフレームを作ってイメージを固める
- Appleの[Human Interface Guidelines
](https://developer.apple.com/ios/human-interface-guidelines/)に目を通してルールを知る
- [Uplabs](https://www.uplabs.com/) にキーワードを入れて参考になりそうなのを探す
- 実際に手を動かして作っていく

という感じで進めていきました。
(Uplabsはメールマガジンを購読しておくと、数日に１回イケてるUIデザインを紹介するメールが飛んでくるので、これを習慣的に眺めるだけ少しずつデザインのセンスが磨かれるんじゃないかと思っています。自分でもデザインする/せざるを得ない人におすすめです）

アプリアイコンは [coconala](https://coconala.com/) でお願いしました。

## 挫折しないために

noteに [1年半かけて個人アプリをリリースできた理由と挫折しないためのコツ](https://note.mu/junqi/n/n583d24d7e1e4) という記事を書いてみたのでよかったらどうぞ。

# 感想

初めての事だらけでしんどい時もありましたが、リリース出来たときはとても嬉しかったです。
開発中にRxSwiftを学んだのが業務でRxJSを書くのに役立ったり、先日iOSアプリ開発の仕事を頂けたりと相乗効果がありました。
仕事中はTrackaをポモドーロタイマーとして使ってて(=記録を開始して25分たったら通知が来る)、25分経ったらSlackで自分宛てメッセージとして分報を書いてるのですが、これをTracka側にも保存出来るように追加開発したいなーと思ってます。(Cloud Functionsでいけるはず・・）
よろしければアプリを使ってみての感想や、こんな機能があったらいいのになどご連絡ください。 🙏