Flutterでゴミアプリを作って得た知見


## はじめに

就活でアピールする為に、モバイルアプリケーションというもの初めてを作成してみました。実際役に立ったといえばたったのですが、きちんと目的ユーザーを捉えてなかった面が強く、見事ゴミアプリとなってしまいました。更にネイティブアプリ(Java, Kotlin)ではなく、クラスプラットフォームアプリ(**Flutter**, React-Naitive)系なのでモバイルエンジニアです！とも威張れるわけもなく・・・折角なので次回に活かす為に感想等を残す事にしました。



## アプリ紹介

実際にどんなものを作ったかという話ですが、**AtCoderに登録されている情報をAtCoder非公式APIとAtCoder ProblemsのAPIを利用してお手軽にユーザー（自分、他人含め）の情報を確認することができる**、という主題のアプリとなります。

失敗ポイントは後述するので省略しますが、今回作成いた感想としては、一番やりたいことと、実装が上手く噛み合ってないと感じました。アプリの先にある利用ユーザーの事を全く考えていなかったのです。デザインを考える時も同じですが「こっちのがかっこいい」「こっちのがスタイリッシュ」などの観点は二の次で、第一に**「目的は何か、何を一番に伝えたいか」**という事を強く考えておくべきだったのだと気が付きました。



[AtCoder Tracker](https://play.google.com/store/apps/details?id=upmountains.tech.tracker_status_atcoder)



## 学習リソース

### 公式ドキュメント



[Flutter DOC](https://flutter.dev/docs])



一番お世話になる上に学習ガイドラインも載ってます。下記のUdemyの講座もここに紹介されていたので選択しました。Udacityの方もちょろっと見たのですが、あまり身についている感じがしなかったので個人的には微妙でした。



### Udemyの講座



[Udemy](https://www.udemy.com/course/flutter-bootcamp-with-dart/)



おそらく**プログラミング初心者でも出来るように**作られています。多彩なイラストや、面白い例え、リファクタリングのやり方や学習の仕方、暗黙知としてあまり語られない（恐らく語るのが面倒）なワークフローの解説。**全てが体系的に纏まっていて、一人で開発する能力がこれ一本で身につきます。**インフラ関係の話は、モバイルアプリ自体で必要となるケースは大規模にならないとないので、踏み込んではいませんが総合的な知見は得られました。

ちなみに僕は英語が出来ませんが、文字起こし機能があったので、それをGoogleページ翻訳しながら見ていました。だいたいの意味は通じますが、時々英語自体が上手く書き起こされていない時があるので、音声を聞きながら進めていました。


### Medium



[Medium](https://medium.com/)



海外でよく使われているブログサービスです。Flutterは正直日本ではまだ流行っているとは言い難いのでリソースがあんまり見つかりません。英語で調べると結構Medium上で色々な文献が出てきます。

日本語の記事では[Monoさん](https://medium.com/@mono0926)の記事が分かりやすいと思います。



[A beginner’s guide to architecting a Flutter app](https://medium.com/flutter-community/a-beginners-guide-to-architecting-a-flutter-app-1e9053211a74)



アーキテクチャを最初どのように構築すればいいのか分からないので、こういう記事を参考にするとそれなりに纏まったアーキテクチャが構成出来ます。ちょっと前はBLoCが流行っていたらしいのですが、**現在の主流はProviderを使用した状態管理っぽいです。**（間違っていたらすみません）BLoCの概念はちょっとむずかしいのでシンプルなProviderの方で個人的にはやりやすかったです。



[FieldStacks](https://www.filledstacks.com/)



他にFieldStacksなどのスニペットを見ると色々カスタマイズすることが出来るようになります。ちょっと情報が古い部分のやつがあったり、競合しちゃったりするものがあるので慎重に選択する必要がありますが、それを理解出来る頃には自分で解決出来るようになっていると思います。



## 作成までのフロー



###1. 目的設定

目的設定と言ってしまえば格好良いですが、**「他人のレートとかすぐ見られるようにしよう！」**とか**「進捗具合を簡単に見られるようにしよう！」**とかの凄く簡単な要件定義だけでした。

最初のうちはあまり想像がつかないのでアイディアは出てきにくいですが、この時点でもっと目的を明確に定義しておくべき・・・だったのだと思います。



### 2. 学習

これに関しては上記にある学習リソースでひたすら小さなアプリを作りつつ、実践です。今回は学習リソースがかなり優秀だったので、特に苦労することなく進めることが出来ました。



### 3.機能実装/テスト

Google TODOリストを使いながら、実装したいことを１つ１つ消化していきました。UI/UXを全く考えていなかったので何回もUIを作り直して時間ロスしてしまいました。これも反省点です。

加えて、人様のAPIを使用している部分があるので通信回数にはかなり気を使いました。人様のサーバーに負荷を掛ける訳にはいかないので、最小限の通信で抑える為です。~~因みにこの心配は杞憂に終わりました。~~



### 4.ビルド/リリース

ビルド自体はAndroidのちょっとしたプロファイルを設定してリリースするくらいだったので難なく出来ました。コロナの影響もあり、審査に１週間近くかかったのはかなりドキドキしました。

Appleの方にもリリース出来るっちゃ出来るのですが、Apple税(年１万円)がストアにかかってしまうのでお財布状況が厳しい僕はAndroidだけにしました。



## 良かった点



### 開発に対する知見を得られた

**「なんでもいいからとりあえずアプリを１個作ってみろ」**とよく言われる言葉を実践することが出来ました。確かにbotやウェブページやサンプルアプリなどは作ったことがあったのですが、モバイルアプリとして1つをちゃんと作り上げたのは初めてです。**「何が辛いのか、何が楽しいのか、何が大変なのか、何が大切なのか、何が必要なのか、何が目的なのか、何が要らないのか」**を身を以て実感することが出来ました。これで僕も今日から**「なんでもいいからとりあえずアプリ1個作るといいよ」**という言葉を他人に使うことが出来ます。



### 抽象クラスの便利さを知った

今まで抽象クラスとは顔見知り程度で全く使い道が思い浮かばなかったのですが、今回仕様変更をいくつか行ったので、その際に抽象クラスの便利さを実感しました。



といってもインターフェースとしての抽象クラスの使い方ですが、端末本体にデータを保存する方式からSQliteを使ってデータを保存する方式に変えた際に役立ちました。実装に困った時に抽象クラスの方をちょっと変えたのは絶対に良くないことですが、技術が未熟なのと、個人開発なのでやってしまいました。個人開発のいいところでもあり、悪い所です。



### 曲がりなりにも就活に役立った（気がする）

21卒コロナ世代の就活です。幸いIT業界はそこまで影響を強く受けるわけではないですが、従来より環境が大きく変わるのは間違いないです。Web面接などになるので。

自分の企業検索能力が高いと感じられなかったので就職エージェントを利用することに決め、[レバテックルーキー](https://www.filledstacks.com/)を利用しました。その際に成果物を用意しなきゃいけない場面があったので（なくても可）胸を張ってこのアプリを使うことが出来ました。



個人的なレバテックルーキーに対する評価としては、「自分の探しているタイプの企業を見つけやすい」という点です。他にも公募が始まっていない企業等にも早めにエントリーして採用貰えるようですが（ずるい）、自分は利用しなかったので実感はできませんでした。後東京オフィスは近未来的すぎて田舎モノの僕には恐ろしく感じました（怖い）。

就職対策などはPDFポイ、と投げられて特に練習することはないので（言えばやってくれるのかも）そっち方面で期待している人には合わないかもしれません。僕は職業案内所として期待していたので、企業に口添えしてくれたり、フワフワとして要望でも企業をいくつかピックアップしてくれたので高評価です。~~就活終わった最後に「転職の時はぜひまた使ってね！」というプロモにはちょっと笑ってしまいました。~~



参考までですが、某マクドナルドのアプリを使ってる会社や某ShowRoomを作ってる会社とか結構幅広いベンチャー等の斡旋もありませんでした。因みに僕はFlutterというマイナー技術を使っていたため、面接すら行けませんでしたが・・・。



### Reactを学ぶのがちょっと楽になった

Flutterの概念はWidgetというものを組み合わせていく、さながらレゴブロックのような性質をしています。最近ほんのちょっとだけReactを触って見たのですが、Widgetの概念に似ているように感じました。なので0から始めるよりはｽｯ・・・と吸収出来るようになってるなぁと感じます。





### プログラミングがめちゃくちゃ楽しかった

**Flutterはみんな言ってる通りコーディングが楽しいです。**レゴブロックみたいだし、フロントエンドはすぐ出来るし、ホットリロードですぐ更新されるし・・・。夜中にモンスター飲みながらデキるプログラマーごっこしてる時が一番楽しかったと思います。あとパッケージも結構充実してるので実装コストが少なめで実装出来るのも良いポイントでした。ただちょっとNullの扱いが面倒くさかったです。



## 失敗した点

### 目的設定が激アマだった

要件の優先度の決定がアマアマでした。1番に達成したいことを明確に定義してからそれに付随する機能等を考える必要がありました。やっぱりアレも欲しい！これもあったら便利！UIはオシャレにしたい！とか考えているうちに操作しにくい、わかりにくい、使いにくい、レスポンスが遅いなどの、**昔のセブンイレブンコーヒーマシン**が出来上がってしまいました。戒め。



### ユーザーが全く見られていなかった

自分がこれあったらいいな〜ｗという世の中を舐め腐った考えで機能を考えていたので、他の人からすると「・・・それいるか？」という機能はたくさん盛り込まれてしまいました。AtCoderのコンテストで優勝した回数を表示する所があるのですが、**これ機能するの世界で300人くらいしかいないんじゃないか・・・？**という事に気づいた時には時すでに遅し。見栄えのために実装しました。

それに加えてユーザーが真に求めているのは通知機能！迅速な更新！素早いレスポンス！だったということに作り終わって時間がたった今気づきました。残念がら実装予定はありません。



### コネクションがなさ杉内俊哉だった

これは後述のプロモーションに繋がる部分でもあるのですが、単純にモノを聞ける人がいなかったという点になります。わからない事をツイートしたら教えてくれる・・・という事は過去1件ありましたが（嬉しい）基本的には皆無です。それにやっぱり初めてのアプリは自分で作りたいからアイディアは自分のもの！！！という愚かな発想があるので、他人に意見を求めるという事をしませんでした。

**やっぱり普段から悩みを相談出来る人をTwitterでちゃんと見つけてコネクションを築いておくのは大切だなぁ〜と実感しました。**そのうちbotで自動でふぁぼするようにしてこっそりフォロワーに恩を売る作戦を実行しようかなと思っています。



### 全くプロモーションを行わなかった

**アプリをリリースしました！何人がインストールしてくれるかな！？ドキドキ・・・0人・・・。**

これは結構あると思います。僕のアプリの名前は「AtCoder Tracker」ですがGoogle Playの検索ではトップに出てこないどころか何処にも見当たりません。SEO負けしてるのです。ダウンロード数が増えれば自動的に上に昇ってくるのでしょうが、雑魚アプリは土に埋もれるだけです。これだけでもプロモーションの大切さがわかってもらえると思います。



Twitterで「よく○○をリリースしました！よろしくお願いします！！」といったツイートを見ると思います。・・・そうです、よく見る中の裏にはよく見られないツイートもあるわけです。これは日頃から拡散（RT,ふぁぼ）してくれるような人をフォロワーに抱えている人だからこそ使える手段であり（もしくはアプリが魅力的でプロモーション力が高い）基本的に僕みたいな雑魚がツイートすると、(0RT, 1ふぁぼ)くらいが関の山です。しかし！ここで臆病になっては行けませんでした。**どんなにゴミアプリだろうと、どんなに将来性がなかろうと、どんなに自分のフォロワーが1桁しかいなかろうと僕はツイートするべきでした。これが格安で出来て影響力が大きい唯一のプロモーションだからです。**

おかげさまでリリースから2ヶ月程度立ちましたがダウンロード数は1です。（友人）

アンインストールされるとアナリティクスから分かるのでまだアンインストールはされていませんが、この前「アンインストールしてないだけ感謝しろよ」と言われてしまいました。

これって友達料と何が違うんでしょうか・・・。



### APIを自前で用意してなかった

APIを自前で用意していない上に個人のであるということです、**これはつまり、他人の褌で相撲を取るようなことです。**それは何を意味するかというと、サーバー負荷を限りなく少なくするように実装しなくちゃいけない、万が一にもDDoSになるような実装にしちゃいけない、応用が効かない事を意味します。今はJavaScriptを勉強したのでAPIを自前で用意する事が出来るようになったわけですが、開発当時は利用することに拘っていたので、応用性がなく、苦しい実装をしていました。

ちなみに、これからもAPIを自前で用意するつもりはありません。誰にも使われないので・・・。



### UI/UXをその場のノリで作ってた

これは愚かです。せめてワイヤーフレームを作って、モックアップをを作るべきでした。確かに開発中に様々なパッケージを知って色々実装したくなるのですが、ベースになる部分は決めておくべきでした。UIで悩みすぎて結局無駄に時間を取られてしまう、という自体が発生し、そうなるとなかなか別の事にも手が回らなくなります。むしろ最初はUIガン無視で機能だけ実装してからゆっくりUIを考えるってことをすればまだマシでした。**途中途中でUIをコロコロ変えてしまったので無駄に工数がかかってしまいました。二度とやりません。**開発休憩に[Dribbble](https://dribbble.com/)を見るのは危険。



### ロジックが素直にゴミ

**ロジックがゴミ**、この一言に限ります。お前何回APIと通信してんだよ！とか何回同じ部分を再生成してるんだよ！とか条件分岐汚すぎワロタ！とか画像ファイルデカすぎワロタ！とか理由はたくさんあります。ユーザーのストレスに直結するレスポンス速度に関わってくるのでこの部分は拘って作る必要があるように感じました。言語理解が甘いとか、アルゴリズム力が単純に低いとか、データ構造の使い方が下手とか原因はたくさんあります。前向きに1個1個処理していこうと思います。



### 状態管理を深く理解していなかった

Flutterにおける状態管理としてProviderとかの話があるのですが割愛（）

結局の所、表面上の理解だけで作り進めてしまったので、状態を通知させたい時に通知デキなかったり、意図せぬタイミングで通知が行われて再生成が行われたり、パフォーマンス問題に大きく関わっていました。開発時の出来る限りの力で実装はしているのですが、やっぱり不十分な所は不十分で、これはもっとスキルがある人に指摘して貰わないと自分では見つけるのが難しい部分かなと思いました。やっぱりコネクションは大切なんですね・・・って感じです。



### 使う人がいないと更新もしたくない

**説明する必要も感じません。誰も使わないので更新してどうすんだよ！ってお話です。**



## 次回以降活かしたい事

- UI/UXの設計をフワフワさせない！

- アルゴリズム力を付ける！

- ミニマルなアプリで状態管理のカラクリを理解する！

- APIとかインフラは出来る限り自前で用意して好き勝手する！（人様のサーバに迷惑をかけない）

- 恥を捨ててプロモーションをする。（知られなきゃ何も始まらない）

- 人とのコネクションを大切にする（意見交換はめちゃくちゃ大事）

- ターゲッティングをはっきりさせ、何が1番達成したいのかを念頭に置く

- 他人にも意見を聞く

  

## 終わりに

つい最近[AtCoder Stalkerを支える技術](https://qiita.com/zaurus/items/5a8665cb9d5c56d9ea09)というものを見つけました。僕が目指すべきだったところはここだったんじゃないかなぁ・・・と反省しています。素晴らしく使いやすいサービスなので、ぜひ使ってみてください。僕も友人を数人追加して常に監視しています。



失敗から学べる人間だと自負しているので次のアプリには絶対活かそうと思います。ちなみに僕のアプリはインストールしないでください。（更新するつもりがないため）