【個人開発】個人の予算を管理するiOSアプリを作った

# はじめに
先日、個人の予算を管理するアプリ「[クイック予算](https://apps.apple.com/us/app/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E4%BA%88%E7%AE%97-%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E3%81%8A%E9%87%91%E3%81%AE%E7%AE%A1%E7%90%86/id1501473191?l=ja&ls=1)」をリリースした。
この記事ではこのアプリを作ったきっかけや、どのように開発したのかを書こうかなと。

# 開発のきっかけ
普段iOSアプリを開発しているのに、そういえば自分でアプリを作成してリリースしたことがなかったのでまず作ってみたかったのがきっかけ。
ただ、どうしてもネタが見つからずそこで嫁さんにどういうアプリが欲しいのかをヒアリングして出てきたのが今回の予算を管理するアプリ。

具体的な要望をまとめると以下の2点のみ

- 年間単位で予算を組んで、その予算内で支出を抑えたい
    - 既存のよくあるアプリは月間で収支を記録するので向いてなかった
- 自分以外の人にも予算の状況を共有したい
    - そもそも家計簿アプリなどでは自分の家計簿を他の人と共有することを、そこまで前提としていない

そのほかにも自分でも有名な家計簿アプリをレビューなどを見ていて、みんな意外と口座との自動連携などの高度な機能を使いこなせていない人がいることを知ってシンプルな予算内でおさめられるようなアプリを作った。

### 余談
実は以前に[テスト管理ツール](https://qiita.com/hackpopo/items/5324583372c174066607)を作っていた時の反省があって。反省内容というのはニッチなサービスだとターゲット層にそもそも届けるのが個人開発レベルだと難しい(法人だとしても難しい)
そのため、そもそもの対象範囲は大きくただし機能を特化して作ろうと。

## 企画する

具体的には以下の順番で進めていきました

1. アプリの価値を考える
2. ターゲットを決める
3. ネーミングを決める
4. ペーパープロトタイピングを行う

### アプリの価値を考える
個人的にはこのフェーズが一番大切かな。要するに一言でこのアプリは何ということを伝えられることが重要。前回、テスト管理サービスを作って思ったが、そもそも大多数の人にはダラダラ興味のないことを説明されるのが嫌いだったりする。
個人であれ企業が作ったアプリであれ訪れた時に結局このアプリではどんなことができるのが伝わらないと、離脱の原因に繋がった。

また、作っていくうちにあれこれも機能を足したり、実は優先順位が低い作業に熱中しがちになるので、そんな時に最初に価値を設定していれば優先順位をつけやすくなる。

このアプリでは、
「**特定の支出に対しての管理・共有が簡単にできる**」
ということを価値に設定しました。

かなり普通だけど結局奇抜なコンセプトを作ったとしても伝えるはすごく難しい！
そのため、普遍的であり多くの人が必要な価値を設定した。

### ターゲットを決める
年齢・性別・シチュエーションを想像して決める。最近、仕事で携わるサービスではそこまで明確にターゲットを絞り込んでいるわけではないが、初期のアプリではターゲットを設定していた方が何かと便利。

例えば、情報設計だったり配色を考えたりする時はターゲットを設定していた方が決めやすくなる。つまりターゲットを設定することで統一感が出る。

### ネーミングを決める
この作業が結果的に一番大変だった。僕たちの業界ではついついカッコいい名前や造語を付けたくなるが、今回のようなツール系アプリはどストレートに何ができるのかを伝える方が重要。
そこで嫁さんに対して色々とネーミングを提案して、やっとこさ最終的にOKが出たのがこの「クイック予算」というネーミング。

何もひねりがないし、一瞬でこれ予算を管理するアプリだと分かるようにしたのが狙い

### ペーパープロトタイピングを行う
あらかじめ必要な機能を箇条書きでまとめておく。
その上でがしがしペーパープロトタイピング行っていく。自分がやったペーパープロトタイピングの一部は以下の画像。

最終的なアプリとは微妙にディテールは違うがたたき台としてはかなり使える。この段階をすっとばしていきなりデザインツールでプロトタイピングを行う人もいるが、自分は部屋でやるより外でやりたいためペーパーでやることが多い。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142868/ada080b6-fa80-7dc4-fcf3-96078f249f2a.jpeg" width="５００">


## デザインを考える
デザインは本職ではないが自分でソフトを使って作るようにしている。ついついエンジニアだとMaterial Designやそういうのを使いがちだが、自分は下手でも自分で作ろうとしている。

結局、ターゲットに合うのを作るには自分で行った方が良かったりする。

自分の場合は、「Adobe Xd」を使っている。非常に軽いし画像の切り出しもアプリ用に切り出してくれるので便利。ソフトはSketchやFigmaなど他にも沢山あるが正直どれでもいい。

![デザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142868/14685af8-1ab3-f1c2-5738-1ee10bbc3fbf.png)


# アーキテクチャについて
FlutterやReact Nativeなどのクロスプラットフォームで開発できるし魅力的だったが、ネイティブでの開発を選んだ。

個人的な意見だがiOSとAndroidなど複数のプラットフォームで新規サービスを同時に出す必要性をそこまで感じていない。Flutterなどのクロスプラットフォーム作成してiOSとAndoroidの両方の動作確認やそれぞれのマーケティングをしないといけないので面倒だと感じる。
仕事で色々なサービスを担当してきたがWEBだけしか展開していないからサービスが成功しなかったということもない。需要があると確認してから作っても問題はないと考えている。

ネイティブの実装では以下の構成にした

- UIKitとAutoLayoutを使用
    - SwiftUIじゃないのかと思われるかもしれないが、iOS12以上を対象にしたかったこととあくまでアプリをきっちり作ることを目的にしていたのでUIKitとAutoLayoutの組み合わせで構築した。
- RxSwift・ReSwift(Redux)
    - SwiftUIとCombineの組み合わせが今後主流になる。その際には`Single source of truth`の世界が当たり前になると考えてReSwiftを導入した。ただ、ReSwiftの書き方を使うとViewWillAppearへの依存になるので、RxSwiftでWrapしてStoreとのバインドは行った。RxSwiftにした理由は使い慣れていただけ。
- VIPPER
    - この[記事](https://qiita.com/hicka04/items/09534b5daffec33b2bec)を参考にしながら実装した。最初は個人開発のプロジェクトでは少し過剰だったのかなと感じたが、後半戦になるとどこに何の処理を書いているのかがはっきりしていたのでかなり使いやすかった。  
    とくに同じViewControllerで作成・更新の処理を分ける時に、Presenterを切り替えて実装したら非常に見通しの良いコードにすることが出来た。
- Realm
    - 後々のことを考えるとFirestoreのローカルキャッシュで保存しても良かったが、使い慣れているRealmを初期の実装では導入した。ただ、RealmのオブジェクトをドメインやView側にも展開するとRealmの使用をやめたい時にリファクタリングが大変なので、使う境界は厳密に定めた。
- Firebase
    - Firebase Analyticsだけ今回は使用した。一つだけ悩んだところは、FirebaseのProjectを一つだけ作って
その中のアプリで環境を分けるのかと、そもそも環境ごとにプロジェクトを分けるのかという点。後にFirestoreを使うことも考えるとプロジェクトを分けていたほうが無難だったので分けることを選択をした。

## まとめ
休日や年末年始のまとまった時間で一気に進めるようにした。平日などは細かく作成しておいたタスクを消化することでコツコツ続けた。
自分でサービスを作ったのは2回目だったが1回目よりもかなりサクサク進んだ。これは自分のモチベーションの持っていき方や進め方について慣れの部分が大きい。個人サービスをいくつも作れる人は流用できるコードやプロジェクトの進め方について経験があるから量産できるんだなと知った。

iOSでは不安のあった証明書周りやリリースの手続きを経験できて良かった。