独学でChatGPTを組み込んだAndroidアプリを実装してみた【Kotlin / Jetpack Compose】

## はじめに
こんにちは、Haru（[haru-ish](https://github.com/haru-ish)）と申します。
独学でAndroidおよびKotlinを学び、ChatGPTを組み込んだAndroidアプリ「One Pick」を実装したので、その過程について振り返っていきたいと思います✍👀💻

### 自己紹介
私はSES企業で1年半強の実務経験（研修期間含む）があります。
JavaとJavaScriptは個人開発でも使用しており、ある程度の基礎知識はあるのかなと思っています。
また、Androidに関しては在職中に案件に関わったことがありますが、その際の言語はJavaであり、主にテスト用のコードを少し書いた程度で、ほとんどはテスターとしての参加でした。
そんな経験から、実質的に今回が初めてのAndroid開発となります。

#### Androidアプリを作ろうと思った動機
これまでJavaを学んできた中で、Kotlinはモダンで理解しやすい言語という印象があったので、ずっと学びたいと考えていました。
また、上記の実務での経験からモバイルアプリ開発はWEB開発とは異なる印象を受け、「一度学んでみたい、面白そう！」と興味を持っていました。
帰国後の転職活動に際し、エンジニアとしてのキャリアについて考えた際、「やりたかったことに挑戦してみよう！」と決意したことがきっかけになります。

#### これまで取り組まなかった理由
少ないとはいえ実務経験があるのはJavaでありWEB開発なので、このスキルを強化することが転職に有利だと考えていました。そのため、転職活動用のポートフォリオとしてSpring BootとVue.jsを使用したWEBアプリ開発に取り組んでいました。そしてそのポートフォリオを持ってベルリン（個人都合で今年10月末まで滞在）にて転職活動を行ったりしていました。

▼ Spring Boot × Vue.jsで実装したWEBアプリ

https://rabbit-habit.haruish.de

▼ コードはこちら

https://github.com/haru-ish/RabbitHabit



## Androidアプリ「OnePick」の紹介
### 概要
![OnePick-Logo](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/6d6219df-f617-1bdd-a921-14c9c4ae16a7.png)

**One Pick**は「今のあなたの気分にぴったり」な映画をオススメするAndroidアプリです。
最大3つのキーワードを入力するだけで関連する映画を1つピックアップし、レコメンドします。映画の詳細については画面より確認することができます。

▼ コードはこちら

https://github.com/haru-ish/one-pick

### アプリの使い方
| Screen | Description |
|---|---|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/3eb2225c-c86e-d0e8-bd55-9d7aabc1f935.png" width="240"/>|1. キーワード（最大3つまで）を入力し、「Search」ボタンをタップします。<br>*1つのキーワードあたり、10文字まで入力可能です<br>*全キーワード未入力は許可されていません|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/b87fc02f-03f8-b223-ecac-5752e5de1d7b.png" width="240"/>|2. 検索中です。少し待ちます。|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/667afdca-56f5-ff1c-9bf8-78628d7f07a3.png" width="240"/>|3. オススメの映画が1つピックアップされました。映画の詳細を確認してください。<br>検索画面に戻りたい場合は、画面右上の「X」ボタンをタップします。|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/1fd90d66-8fb2-b622-e669-864899dabf09.png" width="240"/><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/baa4973d-6103-8310-be87-2fabf9475f73.png" width="240"/>|Error: サーバーとの接続に失敗もしくは入力したキーワードで映画が見つからなかった場合はエラー画面が表示されます。<br>「Retry」ボタンをタップして検索画面に戻ってください。|

### 動画で動作確認
![howto.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552700/e9c5eb24-7a89-e951-e654-db16ceff56ae.gif)

### 開発背景
「映画鑑賞が好き」であり、「ChatGPTを組み込んだアプリを作りたい」という思いからこのアプリのアイディアが生まれました。
私は週に2〜3回ほど映画を観るのですが、何を観ようか迷うことがよくあり、時には映画を選ぶために30分以上費やすこともあります。そんな時、「今日観たい映画の気分を伝えるだけで映画をレコメンドしてくれるサービス」があれば便利だと感じていました。
また、日常的に英語の添削などでChatGPTを利用しており、その便利さを実感していました。そのため、このサービスを組み込んだアプリを作成したいと考えていました。
そうして開発したのが「One Pick」になります。

### 工夫した点
#### 確実な映画の情報を表示すること
普段観る映画を決める際にFilmarksやIMDbなどの映画サイトをチェックすることが多いのですが、その際に自分が求めている情報を「One Pick」でも表示したいと考えました。
映画名と映画ポスター（画像）、あらすじは最低限必要な情報ですが、スコアやジャンル、製作年なども個人的に重要な情報です。
これらの情報を一括で確認できることでユーザーは「オススメされたこの映画を観てみようかな」という判断ができるのではないかと考えました。
そこで上記を実現するために、OpenAI API（ChatGPT）から取得した映画名をもとにTMDB APIに通信し、映画の詳細情報を取得するよう実装しました。

```mermaid
sequenceDiagram
  actor U as User
  participant O as OpenAI
  participant T as TMDB
  U->>+O: Request（ユーザーの入力したキーワード）
  O-->>U: Response（映画名）
  U->>T: Request（映画名）
  T-->>U: Response（映画の詳細）
```

この実装により、OpenAI APIとだけ通信していた際に起きていた「映画名やあらすじは取得できるものの、映画ポスターを取得できない」や「時に存在しない架空の映画名が返される」という問題を解決することができました。
また、映画のジャンルやスコアなどの情報も表示することができるようになり、ユーザーが必要とする情報を確実に提供できるようになりました。

#### 簡単にアプリが使えること
* シンプルな操作性
このアプリは非常に使いやすく、キーワードを1つ入力し、「検索」ボタンをタップするだけでオススメの映画が表示されます。また「X」ボタンをタップすることでホーム（検索）画面に戻れるので、簡単な操作で利用できます。

* 分かりやすいUIの採用
Material3を使って美しく直感的なUIを実現しました。ヘッダーを設け、入力欄には視覚的な分かりやすさを持たせるために、虫眼鏡のアイコンを使用しました。

* 「あってもなくても問題ない」機能は省く
`ログイン、オススメされた映画のブックマーク、映画のレビューを記録`などの機能も追加したいと考えましたが、主要な映画サービスにすでに存在しているため、このアプリでは不要と判断しました。代わりに、必要な情報だけをシンプルに提供することに重点を置きました。

機能の削減は、限られた期間でのサービス開発においても非常に重要だったと感じています。

### 使用した技術スタックと選定理由
* **Kotlin**
慣れ親しんだJavaから派生したモダンな言語であるため、学んでみたかったから。実際にKotlinを学んでみると、Javaではできなかったことがたくさん許容されており、書きやすくて楽しい。Kotlinの理解を深めていきたい…！
* **Jetpack Compose**
公式からJetpack Composeを学ぶことを強く推奨されたため。実務での経験ではUIがXMLで書かれており、分かりにくさを感じていたが、Jetpack ComposeはVue.jsのように書くことができ、UIを直感的かつ宣言的に構築できるため、使いやすく理解しやすいと感じた。
* **Retrofit**
効率的かつ信頼性の高い通信を実現するため。映画のタイトルと詳細を取得するためのAPI通信に利用した。
* **Coil Compose**
Retrofitと組み合わせて使用することが一般的であり、Web上から画像をダウンロードして表示する際に軽量で効率的なため、このライブラリを利用した。今回のアプリはJetpack Composeを使用して実装しているため、Coil Composeを採用した。
* **Material3**
アプリをより美しく、直感的に操作できるようにするために採用。WEBアプリ開発ではBootstrapやCSSを使って実装していたが、それに比べて非常に簡単にモダンなUIが実装できることに感動した。
* **Kotlin Serialization**
Retrofitで取得したJSONデータをKotlinオブジェクトに変換するため、このライブラリを使用した。
* **Kotlin Coroutine**
公式の推奨があったため。KotlinとAndroid Studioとの親和性が高く、非同期処理をシンプルに行える特徴がある。
* **（アーキテクチャ）MVVM**
小規模アプリにはMVC（Model-View-Controller）が有効とされる意見もあるが、Jetpack ComposeとMVVM（Model-View-ViewModel）の相性が良いため、今からアプリを作るならMVVMを採用するのが適切だと判断した。

## 学習方法
AndroidとKotlinを学ぶにあたり、以下の計画に沿って学習を進めました。
1. kotlinの基礎中の基礎を学ぶ
2. Android開発の基礎を学ぶ
3. Androidアプリを作り始めて、分からないことはその都度調べて進める
4. 就活の待ち時間を使ってKotlinとAndroidについての理解を深める → 今後の取り組み


1と2を行うにあたり、使用した教材は以下のWEBサイトになります。

https://developer.android.com/courses/android-basics-compose/course?hl=ja

このWEBサイトは公式が提供しており、ステップごとに丁寧な解説があり、各ユニットの最後には練習問題も用意されています。
実際に手を動かしながら段階的に学習を進められるので、私のような初心者の方にはとてもオススメの教材です🙌

基本的にはこのWEBサイトのみを利用し、分からないことがあれば公式のドキュメントを読んだり、技術ブログを参考にして理解を深めました。
そしてユニット5までを駆け足で終えた後、アウトプットとして「One Pick」の実装を開始しました。
作りたいものに向かって、「手を動かして→躓き→調べて→解決」することで理解が深まるため、早い段階からアプリの実装に着手して良かったと思っています。

今年の9月からKotlinやAndroidについて学びはじめ、「One Pick」がひとまず形になるまでは、計約3ヶ月を費やしました。
JavaやJavaScriptといったプログラミングの基礎知識はあるものの、ラムダ式に慣れておらず、関数を引数にすることも未知の領域に感じる…といったレベルで、恥ずかしながらまだまだひよっこなのでこれからもっと学習を重ねて理解を深めていきたいです。

## 今後の課題
* 時間の都合で（一刻も早く就職したいので就活を優先します…）テストコードを書くことができていないので、ローカルテストとインストルメンテーションテストに優先的に取り組みたいです。

* 新規開発者のリリース要件変更により、クローズドテストが実施可能かどうかが課題ですが、GooglePlayストアでアプリをリリースしたいと考えています。
その際にWEBサーバーを経由してOpenAI APIと通信を行うよう、WEBアプリも実装したので、こちらのテストコード等も完成させたいと考えています。

▼ コードはこちら

https://github.com/haru-ish/onepick-server


▼ 新規開発者のリリース要件変更について

https://support.google.com/googleplay/android-developer/answer/14151465?sjid=12055455682409359287-AP

## まとめ
以前からAndroid開発に興味がありましたが、今回初めて挑戦してみてその楽しさに魅了されました！
まだまだ理解は浅いですが、便利なライブラリを使いながらAPI通信や美しいUIを作成することが楽しく、自分のスマホでアプリを動かしたときにはすごく嬉しかったし、作っていて喜びを感じました。面白いことがたくさんできそうなので、ローカルのDBを使うアプリなど今後も色々作ってみたいと思います。

そして今回の経験を通して、この先モバイルアプリエンジニアとしてのキャリアを着実に積み重ねていきたいと考えています。
バックエンドも少しばかり知識があるので、こちらもさらにスキルアップを図りたいです。
バックエンドとの連携やインフラの実装など幅広い知識と経験を積み、モバイルアプリエンジニアとしての専門性を高めていくことができたらすごく理想的だなと思っています。
そのためにも、学習を続けながら就職活動を頑張りたいと思います❤️‍🔥

長文になりましたが、最後まで読んでくださりありがとうございました！