この記事は「Develop fun!」を体現する Works Human Intelligence #2 Advent Calendar 2020 23日目の記事になります。
他の記事と合わせて楽しんでいただければと思います。
タイトルと内容について
「時をかけるタコライス ~ アプリ作りで駆け抜けた、3つの技術 ~」
自作スマホアプリを3年間作り続ける中で、
**「3層構造」という古典的な構造から「Cloud Firestore」**を利用した今風の構造までを経験しました。
歴史的には何十年もの時間をかけて進化してきた3つの技術を短期間で経験したことを表現するために、
好きな本と、私のエンジニア名を組み合わせてこのタイトルにしました。
この記事ではそんな3年間を物語風に振り返っていきます。
目次
- はじめに
- まえがき
- 第1章 プログラミングとの出会い
- 第2章 初めての自作アプリのリリースと挫折
- 第3章 2度目の挑戦と1000ダウンロード
- 第4章 新しい技術の衝撃とアプリとの別れ
- 3年間の振り返り
- おわりに
はじめに
私は、今からちょうど3年前にプログラミングを始めた駆け出しエンジニアです。
この記事は、一人のプログラミング初心者の振り返り記事ではありますが、
各読者の方にはそれぞれ以下の価値を提供できればと考えています。
各読者の方に提供したいこと
-
全ての方
- アプリ作りの中で学んだこと
-
エンジニア経験の長い方
- 初心者エンジニアが何を感じ、どういうことに悩むのか
-
アプリを作ってみたい方・プログラミング未経験者の方
- アプリ作りの道のり
-
数年後の自分自身
- プログラミングを始めた頃の初心
この記事はとても長いお話になります。
書き終えてみて、21000字を超えていました。原稿用紙50枚越えです。
そのため、皆さんにお伝えしたい「アプリ作りの中で学んだこと」を先に書いておきます。
ここだけチラ見してブラウザバックしていただいて問題ありません。
その先はもし興味を持ってくださいましたら、お時間のある際に読み物として眺めていただければと思います。
アプリ作りの中で学んだこと
「ある技術の便利さを理解するためには、その技術よりも古い技術で同じ機能を実現する苦労を経験することが重要である」
まえがき
振り返りの物語に入る前に、私の作ったアプリを先に紹介しておこうと思います。
このアプリの開発は、現在は終了したため宣伝ではありません。
ただ、初心者が3年間勉強するとこういうものが出来上がるというのを見ていただければと思います。
自作アプリの紹介
「チャット時間割」
開発したのは**「チャット時間割」**というアプリです。
大学生向けの時間割アプリです。
時間割で同じ授業を受けている生徒同士のトークルームを作成し、チャットや画像の投稿ができるアプリになります。
アプリの詳細
**アプリの目的** 「友達が多ければ単位が取れる」というのは大学生の常識だと思います。 ただ、大学3年生だった自分はその文化があまり好きではありませんでした。友達が少ない生徒はどれだけ真面目に授業に出たとしても、過去問などの有利な情報を得ることができません。 それに対して、知り合いが多い生徒は授業をサボっていたとしても過去問を手に入れることで楽に単位を取っていきます。 そんな状態があまり好きではありませんでした。
この状態を解決する一つの方法として、授業を受ける生徒同士でコミュニケーションを取れる環境を作りたいと考えました。 それがこのアプリを作ったきっかけであり目的です。
**アプリの現在** 現在は、完全上位互換のアプリが誕生したので開発を終了しました。 この2,3年で同じコンセプトを持ったアプリが多く生まれました。 そして、自分の技術では勝つことができませんでした。 悔しい思いももちろんありましたが、アプリを作った目的が他のアプリによって達成されているのでそれで良いと考えています。
ことわり
文章はその当時に考えていたままの言葉で表現しております。
エンジニアの方から見ると認識が違う部分も多いかと思いますが、
これがプログラミングを知らない人間の考えか、という目線で見守っていただければ幸いです。
さて、まえがきが長くなってしまいました。
それでは、さっそく本編に入っていきましょう。
第1章 プログラミングとの出会い (2017年12月)
プログラミングはお好きですか
私は、私立文系の大学生3年生でした。
いかにもプログラミングとは縁のなさそうな肩書きです。
元々は文系の就職を目指して入学したのですが、入学してすぐに読んだIT関連の本に感動し、
大学1年生の時点でIT業界でエンジニアになることを目指すようになりました。
しかしそうは言ったものの文系の環境では周りにITに詳しい人がおらず、
何をすればいいのかわからないままただ時間だけが過ぎていきました。
2年生の冬ごろに、ついにプログラミングの勉強を始めました。
書店で初めて手に取った本は**「苦しんで覚えるC言語」**という本でした。
どうして苦しいと書いてあるのにこの本を選んだのかはわかりません。
「苦しい = きっちり学べる」
当時の私はそう考えていたのかもしれません。
それと、聞いたことがあるプログラミング言語がC言語だけだったことも理由の一つかもしれません。
言うまでもなくこの本にはとても苦しみました。
初心者の私にはローカルのPCでプログラムを書きながら読むと言う発想がありませんでした。
ただひたすら、文章として本を読み進めました。
プログラミングという全く知らない概念だらけの世界。
よく分からない記号とルールの嵐。
何度も挫けそうになりながらも読み進め、なんとか1周読み終えました。
しかしその本をそっと閉じた後、再び開くことはありませんでした。
当時の私は、プログラミングというものを正直好きにはなれませんでした。
あの冬の泡
そんな私が再びプログラミングに触れる機会が、その年の冬に訪れました。
その出来事をきっかけに、私は本格的にプログラミングの世界にはまっていくことになりました。
それは、仮想通貨バブルです。
覚えていますでしょうか。
3年前、2017年の冬。
嬉しい記憶の方も、苦しい記憶の方も、全く関わりのない方もいらっしゃるかと思います。
(私は50万円をきれいに溶かした人間です。)
私は仮想通貨の値段が急激に上がる中、仮想通貨取引の世界に入っていきました。
数週間、チャートを眺めながら過ごす日々を送っていたのを覚えています。
そんなある日、私は友人からこんな話を聞きました。
「仮想通貨の自動売買botを作ってみたんだけど、全然上手くいかなかったよ」
私はこの話を聞いて「ぼっと?自動売買?」という気持ちでしたが、
友人から詳しく話を聞いて仮想通貨を自動で取引するプログラムが作れるということを知りました。
そして私はこう考えました。
「不労所得、万歳」
こうして私は再び、プログラミングの世界へと足を踏み入れたのでした。
プログラミングを好きになった日
さて、意気込んだはいいもののどうすれば仮想通貨の自動売買で利益を出せるのでしょうか。
最初は全くわかりませんでしたが、ネットを調べてみるうちに自動売買にも多くの手法が存在することがわかりました。
悩んだ結果、その中から私が選んだ手法は**「3通貨間アービトラージ」**でした。
一言で説明すると、3つの通貨における各ペア(合計3ペア)の一時的な価格差を利用した裁定取引
です。
(3通貨間アービトラージについての記事)
取引所のアカウント作成など必要な準備を整えた私は、早速プログラミングを始めました。
時期はちょうど今から3年ほど前、12月の最後の週だったと思います。
この時、私は初めて自分でプログラムを作る経験をすることになりました。
ただ、プログラミングを始めてみたはいいものの初心者にはわからないことだらけでした。
- プログラミング言語はどれを使えばいいのか
- botはどうやったら動くのか
- そもそもどうやったらブラウザ画面以外から取引なんかができるのか
文系大学生だった私がパソコンを使うのは、 ノートを取ったりレポートを書くのにワードを使う時、授業のプレゼンを作るのにパワポを使う時ぐらいでした。
そんな人間だったので、プログラムを自分のパソコンで作るのに苦労したことは言うまでもありません。
ただ運が良かったことに、私は知らないことを調べて学ぶことが大好きでした。
朝から晩までネットサーフィンをして調べ続けて必要な情報を集めていきました。
調べた結果、使う言語はPythonに決めました。
- 初心者におすすめ
- 文法がわかりやすい
- スクリプト言語のため、書いてすぐに実行できる
こんな情報を元にPythonに決めた覚えがあります。
実際のところは**「初心者におすすめ」**と言う言葉に惹かれただけかもしれません。
プログラミング言語が決まった後は、調べては1行書いて、調べては1行書いてをひたすら繰り返しました。
当時はbotの作成も流行っていたので似たようなことをしている記事が多く、
それらを参考にしてコードを書き進めていきました。
年末年始を実家で過ごしていましたが、この年の大晦日は
家族がテレビを見ているリビングでプログラムを書き続けていたことをよく覚えています。
元旦も2日も書き進めました。
本で勉強した時は全く好きになれなかったプログラミングに、この時は驚くほど熱中しました。
なぜ自分がそれほどまでにのめり込んだのかはわかりませんが、
本を読んでいた時とは一つ違うことがあったのだと思います。
それは、
「自分の作りたいものを、実際に手を動かして作っている」
ということだと思います。
本を読んでいた時は実際にソースを書くことはせず、ただの読み物としてプログラミングを勉強していました。
でも、今回は違いました。
**「こういうものが作りたい」**という明確な目標に向かって、実際に手を動かしてソースを書いていました。
何もないところから、自分の書いた文字列が組み合わさって動くものが出来上がっていく。
そんな物づくりのような面白さに、私は熱中していきました。
そして、ようやく自分で作った初めてのプログラムが完成しました。
それはそれはとても可愛いbotでした。
今はもうソースは残っていませんが、そのbotが画面に映し出した文字列を今でもはっきりと覚えています。
そのbotは取引を行う度に画面に以下の文字列を出力してくれました。
- 現在時刻
- 現在持っているビットコインの量
3通貨間アービトラージの取引を開始してから取引が一巡して終了するタイミングで出力を行いました。
そうすることで、自分の持っているビットコインの量の推移が見れるようになっていました。
botが映し出す文字列は見事でした。
取引を行う度にビットコインの量が減っていくのです。
ゆっくりと、そして着実に
私はあの光景をこの先もずっと忘れません。
と、少しネタっぽく話してしまいましたが、忘れない1番の理由は別にあります。
それは、
「自分で作ったプログラムがきちんと動いて、どこかの遠くのサーバーとやり取りをして取引を成立させている」
という感動でした。
プログラムの行数は300行ほどだったと思います。
たったそれだけの行数なのにこんな複雑な作業ができるということに衝撃と感動を覚えました。
自分のビットコインが減っていくことは本当にどうでもいいことでした。
そのbotが健気に取引をしている様子を、かなり長いこと見守っていた覚えがあります。
この経験が、僕がプログラミングを好きになったきっかけでした。
第2章 初めての自作アプリのリリースと挫折 (2018年4月)
旅のはじまり
2018年1月、初めてのプログラムを作りその世界に魅せられた私はすぐに次のものを作りたくなりました。
そしてこの時から、始まりました。
3年間のアプリ開発の日々が。
まえがきの「アプリの詳細」で書いたように、
大学3年だった私は友達が多ければ単位が取れるという大学の仕組みに違和感を抱いていました。
それまでは、この違和感に対して特段の抵抗を行おうという気持ちも術も持ち合わせていませんでしたが、
プログラミングというものを知った私は、この問題を解決するアプリを作ろうと考えました。
一歩ずつ
さて、いざアプリを作ろうと意気込んだはいいものの、botなどとははるかにレベルの違う開発です。
どこから始めればいいのかどころか、よくよく考えたらスマホアプリってどういうものなんだ?という状態でした。
iOSかAndroidか
当時の私はiPhoneユーザーで、日常的にアプリを使っているけれども
よく考えると「アプリ」というものが何なのかは実際よくわかっていませんでした。
「OSがあって、そこにアプリが乗る」と言われても、
「おーえす、ね。知ってる知ってる。Windows?ってOSってやつだよね?」というぐらいの知識量です。
スタート地点はそこからでした。
まず初めに、スマホアプリにはiOSアプリとAndroidアプリという違いがあることを知り、
どちらを作れば良いのかから調べ始めました。
調べた結果、大学生のOSシェアはiOSの方が多いというデータを見つけて、iOSアプリを作ることに決めました。
Mac
ここでiOSアプリを作るためにはMacが必要だということを知ります。
iOSアプリを作ろうと思った時に、Macを買うというハードルによって心が折れるケースもあると思いますが、
運が良いことに私はMacbook Airを使っていました。
「Mac持ってカフェにいるお兄さんかっこいい」
というよくある理由で、大学入学に際してパソコンを買う時にMacを選んでいました。
Macbook Airを買う時に、使う用途は全くないのに
当時のAirで選べた最高のCPU(core i7)にアップグレードして購入していたのもラッキーでした。
ちなみにiOSアプリ開発を始めるまでのほぼ3年間、core i7はワードとパワポのためだけに存在しました。
典型的な文系大学生という感じですね。
開発に当たって何が必要なのか
さて、iOSアプリを作ることに決めたはいいものの、
アプリというものは様々なものが組み合わさってできている事を知ります。
- アプリ
- サーバー
- データベース
※当時の認識での分類
アプリはイメージが付くけど、アプリに必要な処理をするためのサーバーが必要らしい。
さらにデータを蓄積するためのデータベースというものが必要らしい。
それを知った私は、正直何が何だかという気持ちでしたがひたすら調べました。
「スマホアプリ 作り方」
という検索ワードで調べ続けた覚えがあります。
3層構造
そして、様々な作り方を見た中で私が選んだ構造は**「3層構造」**でした。
**「選んだ」**と言いましたが、実際は様々な種類の作り方の中で当時の自分が理解できたものがこれだけだったからです。
きっとこの時点で私はサーバレスやFirebaseと言った文字には触れていたのだと思います。
ただ、プログラミングを始めたばかりの私にはその仕組みは難解すぎて理解できず、
意識に上がることもなく通り過ぎて行ったのだと思います。
そうして、私はアプリケーションの古典的な構成である3層構造での開発を始めていくことになります。
今思うとこの時に便利な新しい技術を触らずに、
3層構造というサーバーを触る方式を選んだことはとても幸いなことだったと思います。
と、こんなことを思えるのは振り返っている今になってからですが。
ここから私は、サーバーとの長く苦しい闘いの日々に突入していくことになるのです。
サーバー
さあ、早速「3層構造」とやらを作ってみようと思いますが、
そのためにはまずサーバーを立てる必要があります。
サーバーという言葉自体は聞いたことはありました。
と言っても、サーバーが無数に並ぶ大きな部屋「サーバールーム」のイメージを持っているだけです。
そのため、「サーバーを立てる」と聞くと「何事?」という気持ちでした。
買うわけにはいかないだろうし、どうするんだろう?とまたネットの海に潜ります。
その中で、レンタルサーバーとクラウドサービスという2つを知りました。
コンピュータを知らない人間には、クラウドと言われても雲?としか本当に思えませんでしたが
何度も「レンタルサーバー クラウド 比較」で調べて少しずつ理解していきました。
結果的に、クラウドを推す記事が多かったのでクラウドというものを使ってみようと決めました。
クラウドサービスでどれを選ぶかについてはあまり迷いませんでした。
AWSのシェアが大きいということで、ここは単純にAWSを選択しました。
普段からAmazonでよく買い物をしていて愛着があったのも理由の一つかもしれません。
iOSアプリを作るにあたっては、普通であればフロント側とバックエンド側を並行して開発し、
互いにフィードバックを与えながら開発するかと思います。
しかし、この時の私はサーバーのことで頭がいっぱいです。
フロント側のSwiftが入ってくる余地などありませんでした。
そして、サーバー構築の長い1月が始まるのでした。
Ruby on Rails
さて、今回作る3層構造というのはどうやらこういう構造になっているようです。
- Webサーバー
- アプリケーションサーバー
- DBサーバー
とは言ってもどれ一つ馴染みのない私には、どこから手をつけていいのかが全くわかりませんでした。
そこで私は
「サーバー プログラミング言語」
という検索ワードで何の言語を使えばサーバーというものが作れるのかを調べました。
すると、サーバー側の実装には数多くの言語が使えることを知りました。
その中で私が一番興味を持ったのは**「Ruby on Rails」**でした。
どうやらRuby on Railsというものは魔法らしい。
魔法のように、とても簡単にバックエンドが作れるらしい。
そんな夢のような言葉に魅せられて、Railsでの開発を決めました。
- Railsのカバー範囲は主に「アプリケーションサーバー・DBサーバー」の部分らしい
- DBサーバーの部分は、ActiveRecordという機能によってRailsで簡単に作れるみたいだ
- Webサーバーについては「Nginx」という物を使うと複数のアクセスを上手く捌いてくれるらしい
こう言った情報を調べて**「Nginx・Ruby on Rails」
**の構成でバックエンドを作ることに決めました。
魔の1ヶ月
私はここから始まった1ヶ月のことをこの先もきっと忘れないと思います。
サーバーを動かすにはまず、AWSでEC2というものを使うのがいいみたいだ。
そう知った私は、初めて触るAWSに苦戦しながらもEC2の起動に成功します。
しかし、大変なのはここからでした。
ターミナルとサーバー作業。
初心者にとっての大きな壁が立ちはだかったのです。
自動売買botの時は、ターミナルを開くのはせいぜい実行する時ぐらいでした。
しかし、これからはサーバーの中で作業するためにはほとんどターミナルを使う必要があります。
最初の接続すらとても苦戦した覚えがあります。
- ユーザーを新規作成・ルートユーザーを削除
- 公開鍵方式を使う
- chmodコマンドで権限の変更
ここでは書ききれないほどに意味のわからないことのオンパレードでした。
接続を何とか乗り越えてRailsの導入に進みましたが、ここからが特に長い道のりでした。
Railsでサーバーを無事に立ち上げられると
「Yay! You’re on Rails!」
の画面が出てくるということでしたが、何度試しても上手くいきません。
色々な階層をターミナルで行ったり来たりしながら、各設定ファイルの値を調整しては再起動して、また調整して。
そんな風にネットで調べながら、エラーを一つ一つ潰すことをひたすら繰り返しました。
この時、大学3年の2月で冬休みということもあり、ありがたいことに多くの時間がありました。
朝起きたらすぐ自分の部屋でコンソールに向かい、
朝昼混ざったご飯を食べたらコンソールに向かい、
夕食を食べたらコンソールに向かい、
風呂に入ったらコンソールに向かい、
深夜2,3時に眠くなって寝て、また起きたらすぐにコンソールに向かう。
1日に13時間ほど作業していたと思います。
家にほぼ引きこもって、そんな生活を30日ほど続けていました。
そしてついに、念願の画面が表示されました。
それは本当に嬉しい瞬間でした。
ブラウザに表示されるたった一つの画像。
しかしそれは、自分でサーバーを立てて、必要な物をインストールして、設定を色々いじって、
そしてようやく現れたものでした。
あの時の感動は今でもよく覚えています。
今思い返してみても、当時どうしてここまで頑張れたのかは正直わかりません。
ただ、今思い返してみると楽しかったという記憶しかないので、
トライアンドエラーを黙々と進めていく作業は自分に合っていたのかもしれません。
挫けそうな時も何度もありましたが、それでも何より**「面白い」**と感じていました。
初めてのSwift
1ヶ月の闘いを経てついにRailsが動き出した頃、季節は春を迎えていました。
時間割アプリということもあり、新学期が始まる4月より前のリリースを目指していましたがこの時すでに3月の上旬でした。
しかしここで諦めることはせず、Swiftでのフロント開発に着手しました。
Swiftでの開発では主に3つのことに悩みました。
- 用意されたファイルの使い方
- UIの作り方
- サーバーとのやり取りの方法
用意されたファイルの使い方
Swiftでは全てを1から書くわけではなく、Appleの用意したファイルを使いつつ開発をしていく必要がありました。
これが、初心者の私にとっては本当に難しかったです。
既存のソースを読んでその目的・使い方を理解する、という経験がなかった私は苦戦しました。
用意されたAppDelegate.swift
という一番ベースとなるファイルにかなり悩まされた記憶があります。
UIの作り方
UIを作ると言っても、
「Storyboardを使うべきかそうではないか」
という論争がネット上で繰り広げられているほどに作り方は様々なようでした。
最初はデフォルトの作り方であり、画面にパーツを並べてアプリを作る方法のStoryboardから着手しましたが、
全くもって使いこなすことができませんでした。
並べたパーツのサイズを各端末に合わせて自動調節してくれる機能があったのですが、
この機能がどうも上手く使いこなせませんでした。
ネットで調べてもこの機能に対する様々な意見(暴言)を見つけました。
その時、Storyboardを使わずにコードだけでアプリを作っている人の記事をいくつも見つけて、
Storyboardを使わない方法に移りました。
その後コードだけでUIを書いていき、
初心者の作ったものというクオリティではありましたがなんとか完成しました。
サーバーとのやり取りの方法
そして最後に待ち構えていたのが、サーバーとのやり取りでした。
ここは特にわからないことしかありませんでしたが、一つ一つ進めていきました。
- RailsでAPIを準備して、ターミナルからHTTPリクエストを投げてみる。
- 上手くいったらSwiftからリクエストを投げてみて、jsonを受け取れるようにする。
- jsonを整形して使える形にする。
Swiftからリクエストを投げても最初はエラーばかりが返ってきました。
それでもRailsとSwiftを少しずつ調整していくと、エラーコードの値が変わっていきました。
そして、最終的にレスポンスがきちんと返ってきた時はとても嬉しかった覚えがあります。
こうして、Swiftにおいても多くの壁に当たりながらも開発を進めていきました。
そして、3週間ほどで基本的な機能を作り終えることができました。
アプリの審査へ
基本的な機能の開発を終えた私は、
4月前リリースのためにはギリギリの時期である、3月の最終週にAppleにアプリの審査を送りました。
それから数日間、どきどきしながらAppleからの承認を待ちました。
そしてついにメールが届きました。
内容はRejectでした。
審査の結果、リリース要件を満たしていないためこのままではリリースができないというものでした。
- 設定画面がiOSアプリとしてのUI基準を満たしていない
- 条件によって画面のレイアウト崩れが発生する
- 通信方式でセキュリティ要件を満たしていない
- ユーザーに対して、表示されるコンテンツの制限機能を提供する必要がある
一つ目のUI基準でのリジェクトを受けてから、修正しては審査に出し、次のリジェクトを受けては修正してを繰り返しました。
上記以外にも数多くのリジェクト理由を受け、一つずつ直していきました。
(今思えば、Appleの審査担当の方にはご迷惑をおかけしました。)
修正を繰り返すうちに、気づけばリリースを目指していた4月を過ぎていましたが諦めずに一つずつ直していきました。
Appleの審査時間は日本時間とは異なるため、だいたい午前3時ごろにメールが来ることが多かったです。
夜中までバグを直してベッドに入り、寝る前にスマホをいじっている間にリジェクトのメールを受け取ったらそのまま机に戻り、バグを直して提出してから再び寝るという生活をしていました。
本当にリリースしたい気持ちが強かったんだなと思います。
そして、2ヶ月ほどの修正を経て5月の中旬にアプリの第1版(以後、Ver1)をリリースすることができました。
時期はすでに前期の中間テストが始まる頃でした。
時間割アプリを入れる時期などはとっくに過ぎていました。
それでも、Appleから審査合格のメールが来た時の感動は今でも忘れません。
「The status for the following app has changed to Pending Developer Release」
結局、アプリのVer1は主に友人たちがインストールしてくれた38インストールで終わりました。
それでも、自分で作ったアプリがApp Storeに並び友人たちのスマホの中に入っていると思うと、とても嬉しく不思議な気持ちでした。
多くのユーザーに使ってもらうという目標は果たせませんでしたが、
全くの無知の状態から約3ヶ月でスマホアプリをリリースできたことが本当に嬉しかったです。
ちなみにVer1はチャットアプリと言いながら、ほとんど掲示板形式のチャットルームでした。
Twitterのようにチャット画面を上から下に引っ張って離すと読み込みが開始され、メッセージを取得するというものになりました。
理由は単純で、GETのHTTPリクエストを投げることでメッセージの受信を行っていたため、
ポーリングの仕組みを実装しない限りメッセージを自動で受信することができなかったのです。
開発を始めた時は、世の中のSNSのようにメッセージが自然に更新されるものを作ろうと考えていました。
というよりも、当然そういうものが作れると甘く考えていました。
しかし、全く知識のない状態でそんなアプリを作ることは難しかったのです。
そして、この仕様をなんとかしたいという思いから、私はアップデートの道を歩み始めました。
第3章 2度目の挑戦と1000ダウンロード (2019年3月)
再挑戦のはじまり
アプリをリリースしてから数回の細かいアップデートをした後、しばらくはアプリ開発から離れていました。
しかし夏が過ぎて秋を迎えた頃、もう一度このアプリの開発に挑戦したい気持ちが湧いてきました。
今度は4月前のリリースに間に合わせた上で、もっとクオリティの高いものを出したいと考えました。
Ver1を超えろ
4年の前期が終わり大学の単位はほとんど取り終わっていたため、空いている時間にひたすら設計を書きました。
1度アプリを作った経験のおかげで、技術を調べる力は以前よりも大きく上がっていました。
また、アプリが抱える問題点を見つけ出せる目を自然と手に入れていました。
Ver1での主な問題点は以下のものでした。
- チャットがリアルタイムで更新されないこと
- 通信がHTTPリクエストを用いた単純な構造だけでできているため
- バックエンドの品質の低さ
- Railsでどのように処理が捌かれているかを理解できていなかったため、どのような問題が起きるかもわからない
- ActiveRecordをあまり理解せずに使っていたため、授業一つ一つごとにDBのテーブルが作成される状態で、テーブルの数が無数に増えてしまう
これらの問題を解決するために、ルーズリーフ約100枚分の設計書を作成しました。
その中で様々な技術を調べた結果、Ver1とは大きく構造を変えて以下の技術で作り直すことに決めました。
- WebSocket
- Lambda
- DynamoDB
これにより以下の状態を目指しました。
- アプリとバックエンドの通信方式にWebSocketを採用し、リアルタイムで更新情報を受け取れるようにする
- 処理はLambdaを使い、安定性とスケーラビリティを確保する
- データの検索が早いNoSQL形式のDynamoDBを採用することで、リアルタイム性を向上させる
さて、設計はできたもののどれもまた新しい概念のものだらけでした。
使い方を学び、手を動かして一つ一つ試行錯誤しながら実装を進めていきました。
試行錯誤の開発
WebSocket
まず、WebSocketを使った実装にはかなり手ごずりました。
WebSocketを使って、バックエンド側からユーザーにメッセージを送信すること自体はあまり難しくありませんでしたが、
前提として必要な送信対象のユーザーアカウントが誰であるかを特定する部分にとても苦戦しました。
悩んだ末、以下の方法で解決しました。
- チャットルーム画面をユーザーが開いたタイミングで、チャット参加者を管理するDynamoDBにユーザーを登録する。
- チャットが投稿されたタイミングで、投稿されたチャットルームに参加しているユーザーをDynamoDBで検索し、メッセージを送信するユーザーを特定して送信する。
- ユーザーがチャットルームから抜けたタイミング・アプリを閉じたタイミングなどにDynamoDBからユーザーのデータを削除する。
このようにチャットルームでのオンライン状態を管理することで、
WebSocketを使用したチャットのリアルタイム更新を実現しました。
完全とは言えませんでしたが、ほとんどのケースで上手く動くものになりました。
Lambda
ソースコードをアップロードするだけで動くLambdaは私にとってとんでもないものに見えました。
Railsの構築にとても苦労した経験があったからです。
逆に言えば、
一度自分自身でサーバー構築の大変さを経験していなかったら、
Lambdaの便利さを理解することはできなかったと思います。
Lambdaで処理を作ることはRailsに比べれば圧倒的に楽でしたが、それでも多くのことに悩みました。
Lambdaで使う言語としては、この時**Go
**を選択していました。
前回はRailsを使っていたため、Rubyを学んだというよりはRailsの作法を学んだようなものでした。
そのため、バックエンド言語をきちんと書くのはGoが初めてのようなものでした。
Goを使っていくつかの処理を実装した後に1つの問題に遭遇しました。
それは、AWSから発表されたばかりの機能が**Node.js
**でのみ提供されていて、Goではまだ使えない状態だったことです。
この時どうしてもこの機能が使いたかったため、Node.jsも書く必要が出てきました。
新しくGoを覚えたばかりなのに、
さらにNode.jsも書けるようにならなければならないのかと少し絶望した覚えがあります。
どうにかGoで書く術はないかと探し回ったものです。
しかし、当時の私には回避策は見つけられずNode.jsを書くしかない状態であったため、仕方なく書き始めました。
書き始めてみると、意外なことにこう思うようになりました。
「どれか1つのプログラミング言語を学んでいれば、次の言語をキャッチアップするのはそこまで難しくないのではないか」
言語が変わると何もかもが変わると思っていた私にとってはとても大きな驚きでした。
今思えば、この時が新しい言語を覚えるということに対する抵抗がなくなったきっかけだったと思います。
DynamoDB
Ver1ではRailsのActiveRecordを使用していたため、基本的にはRDBの考え方でデータを扱っていました。
そのため、DynamoDBのNoSQLの考え方を理解するのにはかなり(本当にかなり)苦労しました。
RDBは表のようなものなので頭の中で理解しやすいですが、
NoSQLの入れ子構造になったデータ形式は理解することが難しいものでした。
その上、なんとかイメージを掴めるようになり、いざ使おうと思っても
どうデータ構造を設計すればいいのかが本当にわからず苦労しました。
わからないなりに、紙にデータ設計を書いては検索効率に問題がないかを考えて、
ダメな部分を見つけてはデータ階層をいじってを繰り返し、どうにか実用に耐えられる設計を作ることができました。
検索をむやみやたらに多く行うとAWSの課金額が跳ね上がるので、かなり慎重に設計をしたことをよく覚えています。
1000ダウンロードの悲しみと喜び
設計を1ヶ月以上かけて作成していたおかげで、
各技術の使い方に悩むことはあったものの、実装全体は当初の設計にしたがってスムーズに作ることができました。
いきなりソース書き始めるのではなく、きちんと設計をしてから開発することは本当に大切だなと身にしみて感じました。
結果として、今回は4月より前の3月の末週にリリースすることができました。
(やはりAppleとの審査のやり取りが何度かあり、ギリギリにはなりましたが)
そして開発とは直接関係ありませんが、この時からSNSに広告を掲載するようになりました。
Ver1でダウンロード数が全く伸びなかった経験があったからです。
リリース時期が遅れた問題もありましたが、
ダウンロードしてもらうためにはまず認知してもらう必要があることをひしひしと感じていた。
対象とするユーザーは大学生のみであったため、
スマホで多くの人が開いているであろうSNSに広告を出すことにし、以下の3つを使うことにしました。
大学最後の春ということもあり、そこまでお金に余裕はありませんでしたが、
貯金と翌月4月の初任給を頼って20万円分の広告を打ちました。
(初任給の大半はこの支払いに消えました)
その結果、Ver2のダウンロード数は1000程まで到達しました。
広告の力というのはすごいなと感じると同時に、
自分の作ったものがこれほど多くの人にダウンロードしてもらえたことが本当に嬉しかったです。
ただ残念なことに、アプリを継続して使ってもらうことはできませんでした。
理由は単純でした。
日本には大学・短期大学が約1100校あります。
1000ダウンロードということは単純計算で1学校あたり1ユーザーということになります。
つまり同じ授業を登録するユーザーがいないため、
このアプリのメリットであるチャットが成立する条件が満たされませんでした。
開発当初からユーザー数が増えない限りチャットが成立しない問題は理解していましたが、
多くの人に使ってもらうことが唯一の解決策であるため、より良いアプリを作っていくしかありませんでした。
結局Ver2でもアプリを普及させることはできませんでしたが、
1000ダウンロードという数字は自分の作ろうとしているものが市場のニーズとマッチしていると思えるのに十分な数字でした。
さらに嬉しいことにApp Storeのコメントで
「まだユーザー数は少ないから使えないけど、ユーザーが増えたらすごくいいアプリ」
というコメントをいただけた時は本当に嬉しかったです。
自分が作っているアプリの先にユーザーがいることを実感できた瞬間でした。
開発から得られるものはソースを書くことの楽しさだけではなく、
自分の考えているプロダクトが市場のニーズとマッチしていることから感じられる嬉しさもあると個人的には思います。
社会人になって
1000ダウンロードを達成できた嬉しさと、
さらに良いアプリを作りたいという思いからその後もしばらくアップデートを続けました。
社会人になって学生の時に比べて自由時間はかなり減ってしまいましたが、
GWはずっと家でアップデート開発をするなどできる限り時間を捻出していました。
しかし、社会人1年目の私には仕事の時間とプライベートの時間を上手く調整する能力がまだなかったため、
プライベートでの開発の時間は次第になくなっていきました。
第4章 新しい技術の衝撃とアプリとの別れ (2020年3月)
最後の挑戦
そして今年もまた秋がやってきました。
秋は「スポーツの秋・読書の秋・食欲の秋」と言いますが、開発の秋でもあるのでしょうか。
次の春に向けてもう一度アプリのアップデートをしたい思いが復活しました。
仕事に過ごしずつ慣れ始めたというのも大きいと思います。
Ver2ではVer1に比べて大きく進歩しましたが、まだまだ多くの問題点を抱えていました。
-
UI
- チャットルームのUIが未だ自作であり、クオリティが高くない
-
データ処理
- LambdaとDynamoDBを使ったメッセージのリアルタイム処理が完全ではなく、メッセージの送受信に失敗するケースがある
- リアルタイム処理を導入したことによるトーク履歴の管理ロジックの複雑化
この問題を解決するために、再び設計を書き始めました。
昨年よりも成長した点として、設計資料をGSSで作成するようになったことがあります。
これにより、会社の行き帰りの電車の中でもパソコンで設計が進められるようになりました。
UIの改善
まずUIに関しては、昨年まではチャットルーム用のライブラリの使い方を理解できていませんでしたが、
リファレンスを読む力が上がっていたおかげで、ライブラリを使用して無事に実装することができました。
LINEのようなUIを目指して開発を行っていましたが、わりと近い見た目のものにすることができました。
データ処理の革命
メッセージのやり取りの方法について調べている中で、私が3年間のアプリ開発で1番の衝撃を受けた技術に出会いました。
それは**「Cloud Firestore」
**でした。
元々Ver1の段階から、Swift側ではローカルDBとしてRealmを使用していたのですが、
Ver3の設計をする中でまず、Realmの**「Realm Platform」
**というものの存在を知りました。
ローカルDBとサーバー側のDBをリアルタイムで同期し、
さらに別のユーザーのローカルDBまで同時に更新してくれるというものでした。
このようなサービスがRealm以外にもあることを知り、様々な比較サイトを見て調べました。
その結果、私が使うことにしたのがFirebaseの**「Cloud Firestore」**でした。
今までAWSを主に使用していたこともあり、当初はAWSの「AppSync」を使用したかったのですが、
この当時はまだプレビュー版で、プロダクトに使用するのは推奨されていない状態でした。
そのためクラウドサービスはGCPになりますが、Firestoreを選定することにしました。
Firestoreの衝撃
Firestoreを初めて使った時の感動も凄まじいものでした。
SwiftでローカルのDBに書き込んでいる感覚なのに、
自動でクラウドのDBにも保存され、さらに別のローカルのDBにも同期される。
もう、「とんでもない」という一言でした。
- チャットルームへの参加処理
- チャットルーム参加者の管理
- ユーザーからのメッセージ送信
- メッセージのDynamoDBへの保存処理
- WebSocketを使用して、ユーザーへのメッセージ送信
- ローカルDBへの書き込み
これらは私がVer2で一つずつ実装したものです。
それが、Firestoreを使うとたったの数行のコードで実現できるのです。
さらに私の実装では全く対応できていなかった、
同期におけるエラーハンドリング、そしてオフライン対応まで自動で行ってくれるのです。
衝撃以外の何者でもありません。
Firestoreの導入によってLambdaとDynamoDBは完全に廃止することになりました。
今まではDynamoDBで管理していた
- ユーザー
- 授業の情報
- 各授業の参加者
- チャットルーム
などのデータはそれぞれをDynamoDBのテーブルで持ち、保存と読み取り処理をLambdaで実装していました。
しかし、それらは全てFiresotreの数行のコードで実現が可能であったため、
構造を大きく変えてFirestoreを用いた構造に作り直しました。
今まではHTTPリクエストによってLambdaを呼び出し、
Lambdaの処理でDynamoDBへの保存・DynamoDBからの読み取りを行っていましたが、
ローカルのFirestoreに書き込むだけで全てが上手くいくのです。
Firestoreの採用による工数の削減は、RailsからLambda・DynamoDBに移行したVer2の時と同様の経験でした。
より簡単な作業で、より良いものを作れる技術がある。
それを使いこなすことで、遥かに生産性の高い開発ができる。
このことを私は身にしみて学びました。
だからこそ、私は新しい技術をキャッチアップしてどんどんと使っていくべきだと実感しています。
ただそれと同時に思うことは、
Firestoreの凄さを理解することができたのは、自分で同様の機能を1から実装した経験があったからだろう
ということです。
最後のリリース
Ver3は3月の中頃に無事にリリースされました。
ただ、これがこのアプリの最後のバージョンになりました。
冒頭の「アプリの詳細」でお話ししたように、完全上位互換のアプリがこの年の春にリリースされました。
もしそういったことがなく、私がこのアプリの開発をまだ続けていたとしたらこの記事は書いてなかったと思います。
この記事で3年間の開発の振り返りを行うことで
**「チャット時間割」**の開発を完全に終えることになります。
チャット時間割に対する感謝
このアプリには、本当に感謝しています。
プログラミングを何もわからない状態の私に、
エンジニアとして必要なことを学ぶ機会を数え切れないほど与えてくれました。
1からアプリを作る大変さ、そして何より、その楽しさも教えてくれました。
このアプリを誰かの役に立つレベルまで育てることはできませんでした。
ただこの経験のおかげで、
- 多くのユーザーに使ってもらえるプロダクトを作ることの難しさ
- プロダクトが目指すべき水準の高さ
を理解することができました。
この経験を活かして、また新しい何かを作れればなと考えています。
3年間、本当にありがとうございました。
3年間の振り返り
3年間のアプリ開発を通して私は多くのことを学びました。
その中から最も重要な2つの学びについて書いておこうと思います。
基礎技術を知ることは大事
新しい技術は古い技術に比べてはるかに生産性の高いものであることが多いです。
今まで使われていた古い技術にかけていた時間がなんだったのだろうと思うほどに、強力で便利なものです。
私は3年間同じアプリを作り続ける中で、同じ機能を実現するための複数の技術を見てきました。
その経験を通して私はこう思いました。
「ある技術の便利さを理解するためには、その技術よりも古い技術で同じ機能を実現する苦労を経験することが重要である」
ネットの世界には古い技術から新しい技術まで多くの情報が蓄積されています。
しかし、ネットの世界では古い技術の情報は検索に出てきにくくなり、新しい技術の情報ほど目につきやすくなっていきます。
そのため私のような最近プログラミングという世界に入った人間には、
最近の新しい技術ばかりが多く目に入ってくることになります。
しかし、私は思うのです。
それはとても怖いことだなと。
なんというか土台がない感覚です。
基礎的な部分を全く理解せずに、とても高度な部分のみに触れている感覚です。
私にとってRailsは魔法でした。
何が起きているのかなど、全くわかりませんでした。
それでも動くからいいか、と使っていたのです。
でもそこには何一つの理解がありません。
使っている技術がどのように成り立っているのか。
それが全くわからないのです。
この経験を通して、私は古い技術をきちんと勉強することが大切だと考えるようになりました。
時間がかかってしまうとしてもきちんと土台の部分から勉強することで、
新しい技術をきちんと理解して使いこなせるようになると思います。
私は新しい物を学ぶ力と、その土台となっている物を学ぶ力、
その両方をきちんと身に付けられるエンジニアになりたいと考えています。
わからないことだらけでも、諦めずに調べ続ける
これは主にプログラミングを始めたばかり・始めようと思っている人に向けてになるかと思います。
私自身もまだまだ技術レベルの低い駆け出しエンジニアですが、この3年間を通じて思ったことがあります。
それは
「わからないことだらけでも、一つ一つ調べていけばいつかは答えにたどり着く」
ということです。
プログラミングの世界は正直訳がわからないことで溢れています。
初めて出会うものは、何かの暗号のようにしか見えません。
それでも、一つ一つ調べていくといつの間にかきちんと理解できるようになるのです。
全く意味のわからないエラーに遭遇したとしても、プログラムが出すエラーには理由があります。
そして、そのエラーを解消して次のエラーが出たのだとしたら、そこにも理由があるのです。
エラーの文章は無機質で冷たいものにも見えますが、ある意味全く嘘をつかない正直な文章だと思います。
挫けずに一つ一つ解消していけばいつかは上手く動き始めます。
有名な方がおっしゃっていますが、
失敗の唯一の原因は、途中で諦めることです。
おわりに
長いお話にお付き合いくださり、誠にありがとうございました。
以上で私のプログラミングを始めてから3年間の振り返りを終わります。
人は定期的に振り返らないと昔のことは忘れてしまうようです。
3年前の部分の記憶は、すでに曖昧になりつつありました。
今、このタイミングできちんと振り返ることができて良かったなと思います。
この記事が皆さんのお役に立てたかはわかりませんが、
最初に提示した「各読者の方に提供したいこと」を皆さんに少しでもお届けできていれば幸いです。
ご覧いただきありがとうございました。
ご意見・ご指摘・アドバイス等ございましたら、何卒よろしくお願いいたします。