「TODO × SNS」アプリに使用した技術と課題
こんにちは。私はFlutterを用いて個人開発をしているKyoichiです。私は勉強系アプリを作りたいと考え、2022年6月29日から個人で新規アプリ開発を行いました。
アプリ自体は8月17日にリリースできたのですが、いくつもの課題が見つかりました。この記事では、アプリ開発の経験から得た知見と課題をアウトプットします。
※ 2022年2月に第1作目となるアプリをリリースしていますので、もしよければダウンロードお願いします🙏
なぜアプリを作ったか
私が勉強系のアプリを作成したい考えた理由は以下のようになります。
- 以前使用していたStudyPlusとForestというアプリのいいとこ取りをしたい
- タスク管理と勉強計画を一体化したい
まず、StudyPlusというアプリは勉強系SNSです。
twitterのように友達をフォローすることができて、勉強をすると勉強時間がタイムラインに表示されます。更に合計勉強時間などで切磋琢磨することができます。勉強特化型のtwitterのようなサービスは勉強のモチベーションを保つために非常に有益であるということが受験勉強の経験からわかりました。次に、ForestというサービスもSNSのような要素があります。
しかし、Forestの真の良いところは「勉強時間に応じた実績や達成項目があるところ」です。勉強量に応じて木が成長したり、ゲーム内通貨が溜まって、その通貨で新しい木を購入することができます。つまり、Forestにはソシャゲっぽい要素があるということです。この2点を組み合わせたアプリは調べた限りは存在しません。よってこの2点をコアサービスとしたアプリを開発しようと考えました。また、もう一つアプリに組み込みたい要素がありました。それはタスク管理と勉強計画を統合したいということです。現在自分はMicrosoft Todoというアプリでタスク管理をしています。大学の課題を登録して課題の提出を忘れないようにしています。また、作りたいアプリのアイデアや計画をNotionに記録し、課題以外の自己学習のザックリした予定をGoogleカレンダーで管理しています。Microsoft Todoの良い点は、タスクに期限を設定して絶対に忘れないようにできることです。しかしカレンダー表示がないため、タスクから一週間の予定を考えたりするときに不便となります。結局、大学の課題は期限を鑑みながら時間があるときに取り組むという計画性のないやり方になってしまいました。よって、カレンダーとタスク管理を一体化し、タスクにはカテゴリーや期限を設けたいという需要が自分にありました。よって、以下の要素をコアサービスに組み込むことにしました。
よってアプリが提供するコアサービスは以下のようになります。
- SNS機能で友達と勉強時間を切磋琢磨する
- 勉強時間に応じた実績や達成項目を設けてモチベを沸かせる
- 勉強計画をタスク管理風に追加し、カレンダーで表示する
使用技術
まず、iOSアプリのフロントエンドにはFlutterを用いました。Flutterはライブラリが豊富で、コードが書きやすく、高速で開発ができます。またマルチプラットフォーム対応が可能なため、iOSでそこそこダウンロードされれば、アンドロイド版を即座にリリースできるという強みもあります。
Dart, Flutterで使用したライブラリの一部を紹介します。
- Hooks Riverpod (アプリの状態管理に使用)
- Freezed (データクラスをimmutableにして値が書き換わらないようにする)
この他にも多くのUI構成に関するライブラリなどを使用しました。
バックエンドにはFirebaseを使用しました。FirebaseはGoogleが提供しているmBaasで、モバイルアプリのバックエンド処理を簡単に実装することができます。
使用した技術は以下の通りです。
- Firebase Auth (ログイン、ログアウト)
- Firebase Firestore (データ保存)
- Firebase Storage (画像保存)
- Firebase Cloud Functions (任意の関数を実行可能, アカウント削除機能に必要)
- Firebase Hosting (静的サイトの構築, アプリのプライバシーポリシーに仕様)
以上の機能は最初はドキュメントを読んで理解しながら実装しますが、慣れれば秒でバックエンドを実装できます。
詰まったところ
状態管理
まず、フロントエンド開発には必須の状態管理を学ぶ必要がありました。値の再代入やUIの再構築に関する理解をしていないと、アプリが意図しない動作をしてしまうことがあります。Riverpodのドキュメントを読み漁りました。
Firebase関連
アカウント作成にはFirebaseAuthのメソッドで対応できます。一方アカウント削除には、セキュリティ的な理由からCloudFunctions経由でしか削除できないことが判明しました。しかしCloudFunctionsでデプロイしようとすると、node.jsやnpm, firebase-toolsのバージョン関連のエラーが発生して何時間か詰まりました。また、Javascriptをある程度勉強する必要がありました。
appleのリジェクト対応
AppStoreへのリリース時に2回リジェクトされてしまいました。原因は以下のようなものでした。
- カメラやフォトライブラリの使用を許可する文言に「具体的な使用理由」を書きなさい。
- SNS機能には「通報」機能が必要です。(通報されたら24時間以内に対応しなさい)
- SNS機能には「ブロック」機能が必要です。
- EULAが必要です。
- タイムライン機能やフォロー機能などは事前にコンテンツやフォロワーがいる状態のテストアカウントを用意しなさい。
- QRコード機能をつけるなら準備がいるからreviewのメモに書いておいて欲しい。
見つかった課題
個人開発に機能もりもりアプリはきつい
第1作目のアプリでは、リリースを目標にしていたため簡単な機能のみでした。しかし、今回は自分が納得行くようなアプリを目指したため、機能の要件が肥大化しました。よって細部までこだわれずにリリースしました。もう少し開発計画を見直して、コア機能を絞って、他の機能を段階的にリリースする方針を取る必要があると考えました。
そのアプリは他の人は欲しいのか?
すでにあるアプリを組み合わせて汎用的なアプリを作るという戦略では、機能が肥大化するという問題があるだけでなく、ユーザ層を絞れないという問題があります。個人開発ならば「よりニッチな」アプリを作ることによって特定のユーザを確実に取り込んでいく戦略のほうが向いているとも考えられます。自分が欲しいアプリを追求するだけでなく、もっとユーザの需要を調査する必要があったのかなと反省しています。
良かった点
SNS機能とアプリのサービス部分を分離して、SNS機能のコードを再利用できるようにした
ユーザ情報のデータモデルや、ログイン、ログアウト、アイコン画像登録、フォロー、ブロック、通報機能などの一連のSNS機能をメインロジックから分離するような設計を最初から考えていました。これは、SNS機能搭載のアプリを次回作ろうと思ったときに、コードを再利用するためです。この設計方法はコードを再利用できること以外にもメリットがありました。まず、アカウント情報(アイコン画像やメールアドレス)と拡張ユーザ情報(合計勉強時間など)を分離することによって、拡張ユーザ情報に新たなデータを導入(例えば、新機能としてユーザが持っている達成項目を追加)したとしてもアカウント情報やログインメソッドには影響がありません。よってコードの保守性が圧倒的に向上しました。
ER図などを書いて、丁寧に設計した
個人開発だからといって、見切り発車的に開発を開始するのではなく、しっかりと設計をしました。アークテクチャの勉強をして、ドメイン駆動設計を採用しました。これによってコードの拡張性や保守性が向上し、結果的に効率的に開発することができました。「急がば回れ」を身を持って実感しました。
友達にレビューしてもらった
リリース前にTestFlightでアプリを友達と弟のみに公開し、テストしてもらいました。これによって様々なバグや不具合を発見して改善できました。この工程は個人開発者にとって必須ではないかと感じました。
終わりに
まだまだ実装しきれていないものや不具合などが見つかっているので、改善の余地は相当あります。また今回の課題をもとに、新たなアプリ開発の規格も検討しています。Firebaseではなく、バックエンド開発に挑戦してみたいという気持ちもあります。またアプリのWeb対応や、ログやお問い合わせをを自動収集してslack通知したりする機能の実装も検討しています。まだまだ初心者エンジニアですが、まだ夏休みも長いので勉強頑張っていきます💪
Discussion