Flutter初心者がMVVM&サブスクリプションのアプリ公開までにやったこと

## はじめに
6月末、Flutter で作ったアプリを公開しました。
習慣化アプリで、MVVM + Repositoryパターンを採用し、定期購入（サブスクリプション）機能を導入しています。

この記事では、Flutter初心者がアプリ公開までに辿った過程を書いていきます。
（なお、筆者はFlutter初心者ではありますが、プログラミング経験者です）
これからFlutterを始める方、始めたばかりの方の参考になれば幸いです。

### 作成したアプリ
- iOS

https://apps.apple.com/jp/app/habit-switch/id6450116586

- Android

https://play.google.com/store/apps/details?id=com.may88seiji.habitswitch

## 全体の流れ まとめ
記事の流れは下記になります。それぞれの詳細を書いていきます。

1. 2023年4月初旬:
Flutter学習開始

2. 2023年5月初旬:
申請 公開を経験するためのアプリをリリース

3. 2023年6月下旬:
 MVVM + Repositoryパターン、定期購入機能のアプリリリース

## Flutter学習開始
- 環境構築
公式: 

https://docs.flutter.dev/get-started/install

環境構築の方法は `flutter 環境構築`　で検索すると詳しい記事がでると思いますので、そちらを参照ください。

個人的には FVM (Flutter Version Management) https://fvm.app/ にてバージョン管理をしておくと、今後の開発でも便利なのでおすすめです。

- Flutter Dart の使い方を学ぶ
オーソドックスに書籍学習から入りました。

基礎から学ぶ Flutter https://amzn.to/43iOZgZ

最初は主に Dart の使い方に目を通してハンズオンに移り、わからないところを理解するためにリファレンスのように使いました。
Dartの使い方はネット上に丁寧な記事がありますので、そちらを参照されても充分だと思います。

- ハンズオン
ハンズオンには下記書籍を利用しました。

スマホで動くアプリを作ろう！ゼロから始めるFlutter実践入門編
https://amzn.to/3pGI8A5

こちら三冊のシリーズになっており、環境構築の仕方、実装のTips、 実装画面の画像、 GitHubのコードなどとても親切に解説されていました。（私が購入した際は三冊で100円だった気がしますが、7/10現在、一冊300円になっていました）
ハンズオンはネット上の他の記事、チュートリアルでも実践できますので、上記の本にこだわる必要はないです。

## 申請 公開を経験するためのアプリをリリース
書籍でFlutter Dart の基本的な使い方を学び、実際に簡易なアプリを作り終えました。
この段階で4月中旬頃だったと思います。
そして、「アプリを作るぞ...！!」 と 意気込むのですが、実際に手と頭は全然動きませんでした。
理由は下記になります。
- Flutterを動かしたと言っても、写経、既存のコードを書き写したレベル
- 教科書通りには書けるが、応用ができない
- 何を、どのように組み合わせるか、その引き出しがない
- アプリをストアで公開のために何をしたら良いかわからない

複数の課題が混在し、不確実性と複雑性が高くて、頭が痛くなります。
`作りたいアプリの制作` を一旦保留しました。

ここで、今までのプログラミングの学習はどうだったか、と思い出します。
1. 写経、言われた通りにプログラムを書いて動かす
2. 1 のコードを部分的にカスタマイズする
3. お手本を離れて、プログラムを書く

`守破離`ですね。
同時に `困難は分割せよ` という言葉も思い出します。
使い慣れていないプログラミング言語、フレームワークでの実装を進めつつ、アプリ申請といった未知の作業を行うのは複雑性があまりに高く、1からいきなり3に移れるほど私は有能ではありません。
なので、最初のアプリは実装の難易度を極力下げて、アプリ申請公開を経験することを目的にしました。

- では、どんなアプリを作るか？
→ TODOアプリをベースにしたアプリを作ろう、という結論になりました。

TODOアプリは新しくプログラミング言語、フレームワークを学ぶ際にチュートリアルの題材によくなります。それは、CRUD（データ操作の基本である作成 `Create`、読み出し`Read`、更新`Update`、削除`Delete`）を学ぶことができるからです。
Flutter でカウントアップのアプリを写経していましたが、TODOアプリは作っていません。
それで写経後、TODOアプリのロジックはそのままにアプリを作成しました。
それが↓になります。

### Dustbin
- iOS

https://apps.apple.com/jp/app/dustbin/id6448772401

- Android

https://play.google.com/store/apps/details?id=com.may88seiji.dustbin

Dustbin は　ゴミ箱という意味の英単語です。
TODOアプリと違って対象が `やること`ではなく、`イライラすること・ネガティブなこと`になります。
簡単に言うと、Dustbinは嫌なことを書いて捨てるストレス解消アプリになります。
ロジックはTODOアプリそのままで、完了後にゴミ箱に捨てるアニメーションをつけてみました。
学んだパッケージは以下になります。

```
lottie // アニメーション
flutter_localizations // 言語対応
google_mobile_ads // 広告
shared_preferences // データの保存
webview_flutter // プライバシーポリシーなどのwebページの表示
flutter_launcher_icons // アプリアイコン作成
```

TODOアプリのカスタマイズなので、実装はサクサク進んでくれました。
ただ、やはりアプリの申請、公開は手がかかりました。
具体的には下記になります。

- ストアのための画像を用意しなければならない
- app store connect, google play consoleの登録、登録料の支払い
- iOS Android 各ストアに公開、申請するために必要な作業、build の仕方

それぞれを説明します。

### ストアのための画像を用意しなければならない
- iOS 
```
6.7インチ 1290x2796
5.5インチ 1242×2208
iPad 2048×2732
```
- Android
```
16 : 9  1,080 ピクセル以上
フィーチャーグラフィック 1,024 x 500 
```
簡易的に書きましたが、それぞれの画像を用意する必要があります。
また、多言語対応する場合は、その分画像が必要になります。
ネットで検索すると、ストア用の画像生成サービスが出てきますが、有料であったり、利用してみてもあまり使い勝手は良くない印象でした。

なので結論としては `Figma` (個人無料)を使って対応しました。
Figma はコンポーネント機能があり、インスタンス化した画像は元のコンポーネントを変えることで一括で変更することができます。
Figma での作成は未経験でしたので、使い方から学びました。
↓の記事のように簡略化もできるようです

device_previewとFigmaでFlutterのStore用スクショを簡単に作る

https://zenn.dev/k9i/articles/69eb5a52ce16d1

### app store connect, google play consoleの登録、登録料の支払い
### iOS Android 各ストアに公開、申請するために必要な作業、build の仕方

この二つはやってみると大したことないのですが、初見は色々とエネルギーを吸い取られる印象です。
参考にした記事を貼っておきます。
- iOS

https://cat-prog.com/799/

→ build 部分は flutter ではないので`flutter build ios` で実行

https://www.mechengjp.com/%e3%80%90flutter%e3%80%91appstore%e3%81%ab%e3%82%a2%e3%83%97%e3%83%aa%e3%82%92%e3%83%aa%e3%83%aa%e3%83%bc%e3%82%b9%e3%81%99%e3%82%8b%e6%89%8b%e9%a0%86/

- Android

https://www.flutter-study.dev/create-app/publish-android

途中、詰まることがありましたが、問題を分解して、ひとつひとつ小さくすることで着実に対応できました。
記事はありますが、過程をメモしておくと次の公開時にスムーズになります。
（実際にメモを残しておいたので、次のリリースはサクサク進められました）

### 初アプリ リリース完了👏
GW中に初アプリの公開ができました。
Android でアプリアイコンの当たり方がおかしかったり、公開したAdMobで対応必要なことがあったりと、想定をこえた出来事が頻発します。
やってみないとわからないことが多く、試験的に公開してよかったです。
他にも SharedPreferences、アニメーションの使い方、Figmaの使い方もわかってよかったです。



# 作りたいアプリの制作
GW明けから `Habit Switch`の制作に着手しました。
制作期間は約1ヶ月半。
使用したパッケージはだいたい下記になります。

```
flutter_riverpod
freezed
sqflite
table_calendar
flutter_local_notifications
purchases_flutter
share_plus
in_app_review
url_launcher
flutter_native_splash
carousel_slider
tutorial_coach_mark
shared_preferences
flutter_localizations
lottie
```

このアプリ制作では二つ課題を設定しました。
- MVVM + Repository で実装する
- 定期購入（サブスクリプション）を導入する

そして、全体の中でこの二つの難易度が高く、時間がかかった印象です。
それぞれを順に詳細を書いていきます。

### MVVM + Repository で実装する

`MVVM` とは、`Model - View - View Model` の略称で
アーキテクチャのパターンの一つです。
`Repositoryパターン` は、ローカルストレージや外部APIのようなデータソースへのアクセスを抽象化するためのデザインパターンです。
詳細は検索すると多数出てくるので、そちらを参照ください。

- MVVM + Repository を採用し、DBはSQLiteを使用する。
これらのキーワードで検索すると、いくつか参考記事がヒットします。
記事には `Riverpod` にて状態管理を行うものが多い印象です。他にも状態管理のパターンはありますが、Riverpodを利用したMVVM + Repositoryでアプリを作ることに決めます。

https://riverpod.dev/

- 記事を参考にMVVM + Repository実装してみる。コピペ、写経的実装。
→ 失敗

...なぜ？
- 作りたいアプリは記事のアプリとは違う点があるので、その部分をよしなに修正する必要がある
→ 基本的な挙動、利用方法がわかっていないのにいきなり応用しようとしている。
表層的な理解だけでの応用🙅‍♀️
- 一つ前のバージョンのRiverpodの記事が多い。
→ 公式ドキュメントを読んで、基本的な仕組みを理解する必要がある
- SQLiteといきなり連携させていた
→ SQLiteだけで動かして挙動を確認し、それから連携する

どうしても楽をしたがって、横着をしてしまいます。が、上手くはいきません。
`困難は分割せよ`
`応用は基本の組み合わせ`
`急がば回れ`
ということで、SQLite、Riverpodと分割して実装し、個別の動作確認後に連携と手順を踏みました。
公式ドキュメントを読み、日本語だけでなく英語の記事や動画での補足が参考になりました。

https://pub.dev/packages/sqflite

さくしんさんの Udemy の講座も参考になりましたので共有いたします。

https://www.udemy.com/course/riverpod/

MVVM + Repository 実装後、データの持ち方、流れを一段深く理解できるようになった印象です。
その後、 `table_calendar` `flutter_local_notifications` などの実装においても、
公式ドキュメントを確認する、個別に動かす、それから連携、アプリに組み込むという手順で着実に実装することができました。


### 定期購入（サブスクリプション）を導入する
最後、定期購入の実装詳細になります。
導入方法を検索すると、購入者の情報を開発者が管理し、アプリストア、アプリと連携する方法が出てきます。
こちらは難易度が高く、実装に三週間以上はかかる印象でした。

他の選択しとして、`RevenueCat` による実装を見つけました。
こちらはアプリ内課金を簡単に扱えるようにしてくれるサービスで、購入者の情報、アプリストア、アプリとの連携を行ってくれます。料金体系も収益が $1,000/月 までは無料で、導入に問題はなさそうでした。
（簡単になる、と言ってもそれなりに複雑性はありました）

https://revenuecat.com/

https://www.revenuecat.com/docs/flutter


RevenueCat も検索するといくつか日本語の参考記事が出てくるのですが、最新版に対応している日本語記事は見つけられませんでした。
ここでも公式ドキュメントを確認し、古い記事で大まかな流れを把握し、英語の記事、動画で補足しました。

日本語の記事ではPentagonさんのものが非常に参考になりました。

https://blog.pentagon.tokyo/3020/

◾︎ つまずきポイント
- 課金アイテムの登録
それぞれのストア、RevenueCatに課金アイテムを登録する必要があります。実装というより事務部分で煩雑性が高かったです。

- アプリ内課金を実装するためには、テスト環境（Sandbox）を用意する必要がある
Androidではテスト環境のために申請が必要で、公開のための用意（スクショやストアの文章）をしておく必要があります。
私は先にiOSでのSandboxで挙動を確認し、その後 Androidでの確認を行いました。
商品情報などを、RevenueCatのapiで取得するようにしていたのですが、申請ではapiを叩けないのでベタ書きにしておく必要があります。

- 課金画面
課金情報を表示する画面では、プライバシーポリシー、利用規約、解約方法、その他注意書きを載せる必要があります。既存のアプリを参考に実装しましたが、この部分で不足があり一度リジェクトを受けました。

つまりながらも、だいたい一週間半ほどで定期購入を実装できました。

定期購入を実装して、なんとかリリースの目処がたちました。
この後は1回目のリリリースで使用したメモが活躍しました。
書いていてよかった。

## おわりに

実装がなんとか終わり、6月末に無事リリースができました。
リリース後に友人に使用してもらうと、様々なフィードバック、ご指摘をいただきました。
アプリはリリースしてからがスタートですね。

今回、Flutterでアプリを公開して、非常によい勉強になりました。
未知、未経験の事柄は複雑性、不確実性が高く、嫌になって放り出したくもなります。
それでも地道に問題を切り分け、ドキュメントを読み込み、試行錯誤、解決、実装し切ることで、何か言語化できない実装力が上がったような気がします。

問題にぶつかっても、切り分けをして、小さくする。
表層的に対応するのではなく、基本、原理原則を積み重ねる。
地味で地道ですが、それがなにより大事だなと改め痛感した次第です。
この記事がプログラミング、Flutter 初学者の方の参考になりましたら幸いです。