【個人開発】大学生が独学で英単語アプリを開発した話

# はじめに
独学歴１年と少しのiOSエンジニア志望の大学生です。
学習を始めたきっかけの個人開発アプリをリリースできました。
これまでに学習してきたことの整理を兼ねて投稿します。

### 英検®商標の利用について
- 英検®は、公益財団法人 日本英語検定協会の登録商標です。
- このコンテンツは、公益財団法人 日本英語検定協会の承認や推奨、その他の検討を受けたものではありません。

# 開発したアプリ
「ぶんたん for 英検®」という英検®対策用の英単語アプリを開発しました。

https://apps.apple.com/us/app/ぶんたん-for-英検/id6739174811

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/4p9KxtCaoRlTSL?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

# 開発を始めた際の筆者の技術力
- 工学部（非情報系学科）
- 大学２年生の頃にProgateでHTML, Python, Rubyあたりを触ったことがある程度
- サービス開発経験なし

# 開発スケジュール
![スクリーンショット 2025-03-19 10.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013949/1bea4560-cfd9-4fb5-9e22-5e348fb4840c.png)



# 開発のきっかけ
私は大学３年の夏から１年間、交換留学をしていたのですが、英語でのコミュニケーションにとても苦労しました。原因は多々ありましたが、特に「日本語で考えている」ことがいちばんの問題点だと考え、英単語を覚える際にはChatgptに例文を出力してもらい、できるだけ日本語を使わずに英単語を覚えるということをしていました。そのような学習をきっかけにChatgptについて興味を持ち、APIを使えば自分のプログラムにAI機能を組み込めるということを知りました。そこで、以下のようなPythonプログラムを作成しました。
1. Excelに英単語リストを入力
1. Pythonスクリプトを実行
1. OpenAI APIで取得した各単語の例文をExcelに追加

当時の私にはプログラミングの知識がほとんどありませんでしたが、実装はほとんどChatGPTがしてくれました。ChatGPTのおかげで、プログラミング学習のハードルがかなり下がっていることを知り、これなら自分でもできるかもと思いプログラミング学習を始めました。

私が学習を始めた時点では、英語単語学習に特化したAIサービスはあまりなかったため、英単語学習に特化したAIサービスの開発を目標としました。

# なぜiOSアプリを選んだか
主に以下の理由です。
・自分が使うもの作りたい（筆者はiPhoneユーザー）
・Webサービスよりネイティブアプリの方が愛着が湧きそうだったから

また、フレームワークは新しいものという理由でSwiftUIを選択しました。

# 独学初期
以下の２つを１週間ほどで学習しました。

- 詳細！SwiftUI iPhoneアプリ開発入門ノート

http://www.sotechsha.co.jp/pc/html/1312.htm

- SwiftUI Masterclass: Build To Do List App (Youtube)
<iframe width="560" height="315" src="https://www.youtube.com/embed/t_mypMqSXNw?si=7pcOQeUSZz2i3tbG" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

いずれも、あまり理解できていなくてもそういうものだと割り切って、とりあえず真似をして進めました。細かい部分が理解できていなくても、詰まったタイミングでAIに聞けば大抵のことは解決するので、初学の段階では「こういうことができる」という部分だけ押さえて、後は実際に実装するタイミングでAIに詳細を聞くというのが効率がいいと思いました。

# 試作版の開発
↓試作版のβテストを友人に依頼した際に使用したスライド
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/X3UENPz9sF7rE?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>


試作版では「AIとつくる英単語帳」というコンセプトで、主に以下を実装しました。
### 機能
- SNSログイン
- AIによる単語帳の自動作成
- 作成した単語帳の共有
- 他のユーザーが作成した単語帳を検索
- 学習モード（単語カード、空欄補充）

↓AIによる単語帳の自動作成
![スクリーンショット 2025-03-19 10.08.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013949/e1c77f9d-788e-48f0-b4d8-d33942395cfc.png)

### 使用した外部サービス
- OpenAI
  - 入力：英単語
  - 出力：英訳・例文・例文の日本語訳
- Firebase
  - Authentication（Apple, Google Email）
  - Firestore（リアルタイムデータベース）
  - Functions（管理者通知用）
    - 新規ユーザー作成時に管理者にメール通知
    - １時間ごとにOpenAIのトークン使用量を管理者にメール通知
- AWS
  - Secrets Manager（APIキーの管理） 
- Meilisearch
  - Firebase Firestore と連携して、データベース検索

# テストプレイと方針転換
Test Flightを用いて、友人数名に実際に試作版アプリを試してもらいましたが、自分の実感と友人の反応から、以下のような問題点があると感じました。
- 単語帳アプリにしては機能が多すぎる（SNSログイン、共有機能などは需要低）
- そもそも単語帳をAIで自分で作成しようというモチベーションのある人は少ない

そこで、ユーザーからの需要を見直して、「コンセプトが明確なアプリ」を目指して開発し直すことに決め、コンテンツ面と開発面のそれぞれについて以下のように方針を再決定しました。

## コンテンツ面
### アプリのコンセプトを明確に

| - | - |
| ------- | ------- |
| 何のためのアプリか? | 英検®対策 |
| コンセプトは？ | 例文で覚える |
| ターゲットは？ | 英検®受験者（準２級レベル以上を想定） |
| 他の英検®対策アプリとの差別化ポイントは？ | 網羅性（過去６０回分を分析・網羅） |

### UIをよりわかりやすく
実際にアプリを触ってもらうと、こだわって実装した機能でも、そもそもボタンに気づいてもらえないことが多々ありました。当たり前のことですが、自分にとって使いやすいというのが、他の人にとっても使いやすいわけではないというのは常に意識しなければならないと学びました。本リリース版では、**誰が**使っても**説明なし**で使い方がわかるUIを目指しました。

  具体例
  - 単語カードの周りに以下の文言を表示
    - タップして訳を表示
    - 左右にスワイプして次の単語へ　など
  - 設定ボタンの修正
    - （修正前）学習画面内の「設定」ボタンを押すと、シャッフル・音声・例文を非表示などのコントロールボタンが現れる
    - （修正後）学習画面内に直接、各ボタンを表示

## 開発面
私はこだわりが強すぎるところがあり、当初予定していたよりもかなり開発に時間がかかってしまっていました。そのため、自分の中で以下のルールを決めました。
- 開発内容の記録をつける -> 計画のずれを可視化
- 意識的に妥協する -> リリースすること最優先に

開発の進捗は以下のようにNotionで管理するようにしました。

![スクリーンショット 2025-03-18 14.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013949/5473951c-4554-42cc-b7a3-5ce6cf3ceef0.png)

# 本リリース版の開発
試作版から方針転換したことで、以下の内容を新しく実装することになりました。
- 英検®対策教材の作成
- Realm（ローカルデータベース）
- 学習量の自動記録機能
- テスト機能（カバー率・予想得点がわかる）
- 4択の学習モード


### 教材作成
コンセプトを「AIと単語帳を作る」というものから「英検®対策」に変更したため、英検®対策教材を作成する必要がありました。この作業が開発の半分近くを占めました。具体的には以下の工程で進めました。
1. 過去問を元に掲載単語を決定
1. 掲載する品詞・意味を決定
1. 例文とその訳を作成

例文はChatgpt, DeepL, 各種Web辞書などを参考にして、著作権などに十分配慮して作成しています。「例文で覚える」をコンセプトにしているので、
- 単語のイメージが的確に伝わる
- 長すぎず、短すぎない（6〜10語程度）
- 英検®での出題と同じ用法
- 異なる単語同士の例文の内容が重ならないようにする

のように例文には時間をかけてこだわりました。

### Realm

データベースは、試作版ではFirebase Firestoreを使用していましたが、本リリース版ではデータの保存先をローカルに変更し、Realmを使用することにしました。
まだ自分の中でRealmのベストプラクティスは定まっていませんが、以下のように実装しました。

- Realmに保存するオブジェクトはRealmObjectクラスとNonRealmObjectクラスを作成
  - 読込時：RealmObject -> NonRealmObjectに変換
  - 保存時：NonRealmObject -> RealmObjectに変換
- Realmに関する処理はRealmHandlerクラス内で完結させる
- View内ではNonRealmObjectのみを扱う

設計には以下のスライドを参考にしました
https://speakerdeck.com/musayazuju/databasenokotowokao-ezuniiosapuriwozuo-ru-rokarudetabesuwoshi-utokino-akitekutiyashe-ji?slide=15


この実装によりRealm特有のクラスを扱う箇所が少なくなったため、開発しやすくなりました。また、migrationなどは未実装なので、新規教材を追加するアップデートを行う際に実装したいと考えています。

# リリースまで
リリースまでの間に、開発の他に以下のようなことを行いました。
- 宣伝用スライドの作成
- プライバシーポリシーサイトの作成
- 日本英語検定協会への「英検®」商標の使用許諾申請

最も不安だったのが「英検®」商標の使用許諾申請でしたが、個人での申請に対しても丁寧に対応していただけました。また、リリース前にはアルバイト先の塾の先生方にTest Flightを用いてアプリを試してもらいました。そこでの反応から、試作版と比較してかなり良くなっていると感じました。

# リリース
2025/2/10 リリースしました！

# 個人開発での学び
個人開発されている他の方々も発信されていることですが、
- 最小限の機能でリリース
- 妥協する

これらはサービス開発において何よりも大事だと感じました。
また、私はかなり意識していないとこれらを優先できないと自覚できたのがよかったです。

# 今後について
### アプリのダウンロード数を伸ばす施策
- 英検®各級の教材の追加（リリース時は英検®１級の教材のみ提供）
- SNSでの発信

### 技術面
私には、以下の経験が圧倒的に不足しています。
- チーム開発・インターン経験
- Qiita, SNSなどでのアウトプット

これまでは、個人の独学で進めてきていましたが、これからは積極的にエンジニアのコミュニティに参加していきたいです。また、個人での勉強としては以下に取り組んでいるところです。
- 別アプリの開発
- Swiftの知識の体系化
- Pythonの学習

Swiftに関しては、ChatGPTとの会話で学んできたので、知識の抜けが多い状態だと思っています。そのため、以下の書籍で抜けている知識を拾っています。

https://gihyo.jp/book/2020/978-4-297-11213-4

Pythonでは個人で使う以下のようなツールを作成しています。
- 研究で使用する他変数関数データを扱うパッケージ（微積、フーリエ変換、プロットなど）
- アルバイト先の塾での業務自動化ツール（プリント作成）
    - 問題集の画像を用意 -> OpenAI APIで画像認識 -> PythonでTexに加工 -> PDFとして出力

# さいごに
最後までお読みいただき、ありがとうございました！