flutter初学者が学び始めて3週間でアプリをリリースするまで

こんにちは！
大学3年生の[からまる](https://twitter.com/karamarooon)です。普段はサーバーサイドを書いています。

この記事では、**Flutterを学び始めてから3週間でアプリをクロスプラットフォームでリリースする**までの過程を記述します。

今からFlutterを学び始める方の参考になれば幸いですmm

タイトルの通り初学者なので、間違い等あればご指摘いただけると幸いです。

## リリースしたアプリ
**『EDM大喜利』**

フリーのお笑い芸人**ラランド**さんが企画した「[**EDMにノレばどんな大喜利の回答も面白くなる説**](https://www.youtube.com/watch?v=WK4mNb4if6o&t=446s)」をアプリにしたものです。

仕様としては以下の感じです。
>
① 曲と制限時間を設定する
② ランダムでお題出題
③ EDMイントロ時間で回答記述
④ EDM停止と共に回答発表
⑤ tapでEDMのドロップ(サビ)再生

<img alt="app" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334600/c76cd1e4-511d-d3ae-cf6c-1f7d829bec63.jpeg">

ios: https://apps.apple.com/jp/app/edm%E5%A4%A7%E5%96%9C%E5%88%A9/id1552617373
android: https://play.google.com/store/apps/details?id=com.karamaru.edm_oogiri （実はまだ審査中なので有効ではない）


## 学習・開発の軌跡

### １週目
HomeScreen実装・riverpodに変更・ci設定・github関連テンプレートの作成

![スクリーンショット 2021-02-12 13.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334600/329c694b-f508-bcba-db32-5b801005c7a8.png)

### 2週目
inGame実装

![スクリーンショット 2021-02-12 13.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334600/4765cd46-7113-20f9-d625-5eff93be6b65.png)

### 3週目
広告の導入・バグ修正・リリース作業
![スクリーンショット 2021-02-12 13.46.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334600/d36b09c1-2e07-b47a-67b4-5198d8c500a6.png)

本当はもっと恥ずかしいPRたくさんあるんですが主にこんな感じでした。


学習方法については**公式サイト**が主で、[CookBook](https://flutter.dev/docs/cookbook)(exampleみたいな奴)で雰囲気を掴んで、詳細な仕様を[WidgetCatalog](https://flutter.dev/docs/development/ui/widgets)で確認するといった流れでした。

細かい記述に関しては、**analysis_options**を設定することで比較的よしとされている記述設定にあやかれます。

どこから勉強していいか分からない際は、Youtuberである[Kboyさんのハンズオン動画](https://www.youtube.com/channel/UCReuARgZI-BFjioA8KBpjsw)を見るのもいいなと思いました。


**flutterは公式のドキュメントが豊富**で、非常に学びやすかった印象です。

[Dart/Flutter の静的解析強化のススメ](https://medium.com/flutter-jp/analysis-b8dbb19d3978)

## 使った技術
### 状態管理
flutterの状態管理のやり方は多岐にわたります。（StatefulWidgetとかBLoC+Providerとか）
そんな中で私は**riverpod**+**StateNotifier**+**flutter_hook**を採用しました。

**riverpod**は従来状態管理のメインだった**Provideｒ**のパワーアップバージョンで、Providerがグローバル変数として定義できる・自動でdispose(解放)される・Widgetツリーが肥大化しないとか色々メリットがある比較的新しいパッケージみたいです。
いくつか試してみましたが、riverpodはグローバルに宣言できる部分など扱いやすく、コンパクトにコーディングできるので個人開発のプロジェクトに特に良いのかなと感じました。

詳しくは偉大な方々の記事を参考にしてみてくださいmm

[RiverpodとFlutter Hooksを使う、はじめの一歩](https://qiita.com/karamage/items/8d1352e5a4f1b079210b)
[Flutterの状態管理手法の選定](https://medium.com/flutter-jp/state-1daa7fd66b94)



### オーディオ関連
アプリの肝である音楽・効果音の再生は[**AudioPlayers**](https://github.com/luanpotter/audioplayers)というライブラリを使用しました。

ローカルアセットの再生は```AudioCache```を用い、以下の様にすることですぐに再生できます。

```audio.dart
import 'package:audioplayers/audio_cache.dart';

AudioCache _player = AudioCache();
_player.play('ローカルアセットへのパス')

```

実際にはインスタンス生成を抑制するためにシングルトン(インスタンス１つを使い回す)設計にしたり、```loadAll```メソッドなどで事前にアセット読み込みしたりすることが勧められています。
以下のサイトにも書いてある通りです👀参考にしました。

[Flutter でゲームを作ってみた Part2](https://zenn.dev/asteroid/articles/31104fc13cd19b256381)


### 広告
広告には[**firebase_admob**](https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_admob)を使用しました。
firebase連携して、アプリをGoogleAdmobに登録した後、以下コードのようにしてインタースティシャル(画面全体)広告を打つことができます。意外と簡単で感動しました👀

```admob.dart
import 'package:firebase_admob/firebase_admob.dart';

InterstitialAd(
        adUnitId: Platform.isIOS
            ? IOSの広告UnitId
            : Androidの広告UnitId,
      )..load()..show();
```

(Iosなら`Info.plist`、Androidなら`AndroidManifest.xml`に広告AppIdの記述が必要です。


## 苦労した・失敗した点

- android・admobのwarningに惑わされた

アンドロイドで広告を表示しようとした際に、```service not redistered```とwarningが表示され困惑したのですが、どうやら以下を見ると仕様らしいですね。かなり考え込んでしまいましたmm

https://github.com/firebase/firebase-android-sdk/issues/1662#issuecomment-744603267

- android・パッケージ名をデフォルトのまま進めた

googlePlayStoreではデフォルトのパッケージ名「com.exmple~」をリジェクトしているため、initした時点で変更しておくべきでしたｍｍ



## 実感したflutterの利点

- **Widget(コンポーネント単位の部品)が豊富**で、**積み木のような感覚でUI設計ができる**
- デフォルトの**マテリアルデザイン**が洗練されている
- iOS・Androidアプリを1コードでリリースできる**開発の速さ**
- **クロスプラットフォーム**で競合のReactNativeより**エラーがわかりやすい・パフォーマンスがいい**(独自レンダリング)
- **静的解析```analysis_options```**の導入が簡単で、初学者でもある程度安全に書ける

過去にReactNativeで開発した経験がありましたが、flutterの方が**ライブラリの管理や画面設計が直感的**で好きだと感じました。
（ReactNativeのビルドエラーがとっても分かりづらかった苦い記憶があります泣

## 最後に
学習し初めて3週間で自分の好きなアプリがリリースできて良かったです!
iosアプリはリリース経験があったのでxcode周りは苦労せず進められましたが、androidは初めてで、貴重な経験ができたなと考えています。

個人でサクッとアプリを作るのにはflutter最強の言語なのではないかなと感じました🔥

主にアプリ開発を主戦場にしていない皆さん、是非個人開発でflutterを始めてみてはいかがでしょうか？