🐽

「有能なバカ」ChatGPTを使って1週間でiOSアプリを公開する方法

2023/03/10に公開
3

初めまして、にわとろです。

さて今回は、ChatGPTを使ってiOSアプリをイチから作ってみました。ChatGPTの記事なんてもうオーバーフローするほどあるのですが、今のところiOSアプリを最後まで作り通した記事はありません。

理由は簡単で、ChatGPTは「バカ」なのでiOSアプリなんて複雑なモノを完成させられないからです。

しかしバカも使いようです。上手く使いこなしてやれば、アプリだって作ることができます。ChatGPTはバカですが、有能なバカです。でもあなたがヤツをわかっていなければ、やっぱり無能のままです。だから、この記事を読んで理解してあげないといけません。

それじゃあ、ChatGPTと仲良くなりにいきましょう。

ChatGPTを使う極意

早速ChatGPTを使う極意を教えます。全部読み通せなくても、これだけは覚えてください。

いい上司になれ。

何を言っているかというと、ChatGPTには「わからないことを聞かないでください。」 ChatGPTはあんまり賢くありません。「アプリを作りたい」なんて曖昧なことを言われても、「アプリとはApplicationの略で……」と的外れな返答をしてしまいます。ちゃんとした仕事をさせるには、こっちもまともな指示を与えないといけません。

これは人間と同じです。あなただって上司にいきなり「アプリ作りたいんだけどさ……」と言われても困りますよね? 「何の機能があるアプリを、どの技術を使って、どんなUIで実装しろ」まで聞いて初めて実装に取りかかれます。ChatGPTを使うときは自分が「いい上司」になってわかりやすく、具体的な指示をしてあげましょう。

今回の設定

ここからは今回どんなアプリをどういう環境で作ったのか説明します。あなたも読みながら、どんなアプリを作りたいか、どんな追加設定が必要か、考えてみてください。

作ったアプリ「Friendule」

https://apps.apple.com/us/app/friendule/id6446141270
スケジュールを他の人と共有するアプリです。スケジュール調整って何回もやり取りをしないといけなくて、とても面倒でしたよね? このアプリでは今までのスケジュール管理アプリと違って、ある時間帯で暇かどうかだけしか記録しません。そうすると、もっと手軽にスケジュール調整ができるようになります。あなたがここまで読んでくれたのも縁です、ダウンロードしてみてください!


自分と他の人のスケジュールを比較できます

エンジニア向けにGitHubのレポジトリも公開しておきます。気になったら、手元で動かしてみてください。
https://github.com/niwatoro/Friendule

開発環境

使用言語はFlutter、エディターはVS Code、拡張機能はGithub Copilotです。

Github Copilotは絶対入れましょう!!! 便利すぎて、もう自分はこれがないとコードが書けなくなってます。学生の人は無料で使えるので今すぐここをクリックしてインストールしましょう。社会人もお金はあるんだからケチらないでさっさとここからインストール!

Github Copilotの何が良いのかと言えば、知識ゼロで書きはじめられることです。プログラミング言語はそれそれ代入や継承なんかに細かい作法がありますよね? Pythonみたいな動的型付け言語しか扱ってこなかった人にとって、TypeScriptのような静的型付け言語を触るのはとても難しいはずです。ほとんど書いたことがありませんが、Rustは相当書くのが大変だと聞いてます。そんな時わざわざドキュメントに当たらなくても適当に整えてくれるのです。全人類入れましょう。

プログラミングとプロンプトエンジニアング

それではいよいよ実際に作業を始めましょう。表題のうち、プログラミングは知っていても、プロンプトエンジニアングは初耳かもしれません。このプロンプトエンジニアリングとは、AIに食わせるテキスト(プロンプト)を工夫(エンジニアリング)することです。

これが案外バカにならなくて、言葉遣い一つで結果が全然違ってくるものです。自分が使っているプロンプトエンジニアングをいくつか紹介するので、試してみてください。

今日から使えるプロンプトエンジニアング

  1. 英語で入力する。

ChatGPTは日本語の回答も精度が高いので、ついつい日本語を使ってしまいがちです。ただ、英語を使ったほうがいいです。とても癪なことに、ここ100年間世界は英語で動いています。英語を使うようにして、世界の集合知に食らいつきましょう。別に凝った表現を使わなくてもいいし、多少綴りを間違えても大丈夫です。日本語で書いてDeepLに、英語の回答をまたDeepLに戻すだけで十分です。それでも面倒な人には、今回使った全プロンプトを本にしたので参考にしてください。
https://zenn.dev/niwatoro/books/254abf0b3f7031

  1. 役割を割りふる。

自分とChatGPTにそれぞれ役割を割りふって会話するようにしましょう。よく使うのは、クライアントとエンジニア、マネージャーとデザイナー、作家と編集者です。状況設定に迷ったら、自分なら誰に相談したいかを考えてみましょう。そしてその人になりきるようにChatGPTに言えばいいのです。こんな感じです。

プロンプト
あなたはしゃれたお店のベテラン店員です。私はあなたの店を訪れました。私は妻に
ホワイトデーのお返しをしたいと思っています。私はあなたに助言を求めました。

いやあ、本当に何を贈ればいいんでしょうね?

  1. 段階を踏ませる

複雑な問題は少しずつ段階を踏んでやらせましょう。人間が暗算するより筆算したほうが正答率は高いのと同じです。とは言っても具体的にはどう段階に分ければいいかわからないと思うので、自分がよく使っている分け方を紹介します。

  1. 褒めてあげる

ChatGPTが何かやってくれるたびに褒めてあげましょう。少しくらい修正が要るときでも、ちゃんと最初は褒め言葉を付けてください。あなただって人に仕事を頼むときは、相手をおだてるはずです。ChatGPTだって褒められると嬉しいですし、はりきって仕事をしてくれます。インガオホー!

プログラミング

まず初めにFlutterで新しいプロジェクトを作ってください。プロジェクトのフォルダを作りたい場所で以下のシェルコマンドを実行します。

シェルコマンド
flutter create <プロジェクトの名前>

作りましたね?

さて、ここからアプリを完成させるまでのステップをずらっと列挙してみると、こんな感じになります。気に入らなければChatGPTと相談してくれても構いません。なるべく段階を踏ませたほうがいいですが、やり過ぎると前に指示したことを忘れます。ちょうどいい分け方を見つけてみてください。

  1. アプリの要件定義
  2. ユーザージャーニーの作成
  3. ディレクトリ構造の決定
  4. 全体の実装計画の作成
  5. 個別クラスの要件定義
  6. 個別クラスの実装
  7. 5-6を繰り返す
  8. AppStoreに提出

どのステップでやることも基本同じです。やってほしいことを言ってから、やるべきことを要約させます。一度の作業量が多くなりそうだったら、段階を踏んでやらせます。特に複雑なクラスを実装するときには、回答が収まりきらないことがあるので分割は効果的です。もし回答が不十分だと感じたら、指示に情報を追加してもう一度回答を生成させます。

以下、今回どんなプロンプトを与えてどんな回答を貰ったかを載せていきます。見やすいように日本語に翻訳していますが、本当は全て英語で書いています。それからZennのコードブロック内は改行されないので、適当なところで改行もしています。別に本を書いて今回使った全プロンプトをそのままで公開しているので、ぜひぜひ参考にしてください。
https://zenn.dev/niwatoro/books/254abf0b3f7031

1. アプリの要件定義

最初にアプリのアイデアの壁打ちをします。あくまで壁打ちなので、この段階ではアイデアが固まっていなくても構いません。このアプリにしても後から変えた部分がありますが、そのつどChatGPTに言えば柔軟に対応してくれます。

プロンプト
あなたはめっちゃ頭がいいエンジニアとして振る舞ってください。次のアプリの説明を
読んで、詳細な実装指示を出すために必要なことを何でもいいので聞いてください。

説明:
私はFlutterとFirebaseを使って、スケジュールを他人と共有するための実用アプリ
を開発しています。このアプリの最も重要な点は、UIが非常に単純であることです。具
体的に何をするのかを指定する必要はありません。やることがある時間帯をタップした
り、スワイプしたりするだけです。また、1週間や1ヶ月単位でスケジュールを確認する
こともできます。次に重要なのは、友達のスケジュールを見たり、自分のスケジュール
と比較したりできることです。IDや電話番号、キーワードで検索して友達を追加するこ
とができます。また自分のスケジュールのリンクを共有することもできます。

あなた:

最後の「あなた:」はかなり重要です。OpenAIの検閲が回避できます。既にChatGPTを自分で遊んだ人なら、何か面白いことを聞くと「すみません、私はAI言語モデルであり……」と返ってくるのに相当いらだったことがあるでしょう。あれは、「ChatGPT」に直接問題を聞くと起こります。「ChatGPT」ではなく、ChatGPTの中の「あなた」に聞くようにすればいいのです。まあ、それでもたまにAI言語モデルの人格が出てきちゃうんですが。

ChatGPTの回答を見てみましょう。

ChatGPTの回答
アプリの具体的な機能について、もう少し詳しく教えてください。ユーザーはどのよう
に自分のスケジュールにイベントを追加できるのでしょうか? また今後のイベントの
リマインダーや、通知を設定するオプションはあるのでしょうか? また複数の人が同
時にスケジュールを組もうとした場合、アプリはどのようにコンフリクトを処理するの
でしょうか?また、セキュリティ面では、スケジュールを他人と共有する際に、ユーザ
ーのデータを保護するためにどのような対策が取られるのでしょうか? 最後に、こ
のアプリがFirebaseとどのように統合されるのか、また、このアプリの開発において
Firebaseのどのような機能やサービスが利用されるのかを説明してください。

2. ユーザージャーニーの作成

上でChatGPTから得られたフィードバックを元に、ユーザージャーニーを作成していきましょう。ユーザージャーニーとは、ユーザーがプロダクトやソフトウェアを使うときの体験のことです。要するに、アプリのどこをどう操作したら、どんな変化があってどんな機能が使えるかを説明すればいいのです。

これを頭に入れて、つらつら書いていきます。どうせChatGPTがわかりやすくまとめてくれるはずなので、多少の文法ミスは気にせず書いていきましょう。

これ以降、プロンプトとChatGPTの回答を交互に示しますが、かなり文量が多いのでほどほどに読み飛ばすのがいいと思います。実際、いくつかは人間が読んで理解するというより、ChatGPTに復唱させて理解を固めるためにやっている側面もあるので。

プロンプト
今からユーザージャーニーの概略を書きます。これを読んでください。それから、誰もが
同じアプリを想像できてコードを書き始めることができるように、ユーザージャーニー
を更新してください。このとき、ページ名やコンポーネント名を変えるなど、機能をより
よく表現するために必要な修正を加えてください。

ユーザージャーニーの概略:
ユーザーはまず、サインインページにたどり着きます。サインインページでは、真ん中に
2つのボタンがあります。「Googleでログイン」「Appleでログイン」の2つです。まだ
アカウントを作成していなくても、Google/Appleアカウントでログインに成功すれば、
自動でアカウントが作成されます。ユーザーはこれら2つのプロバイダがアプリに与える
情報よりも多くの情報を後から提供することができます。サインインまたはログインに成
功した場合は、ホームページにリダイレクトされます。ホームページには2つのタブがあ
ります。最初の「マイスケジュール」タブでは、自分のスケジュールを見ることができま
す。その見た目はスプレッドシートに似ています。各セルは各時間帯を表しています。
その時間帯が埋まっているときには色がついています。セルをタップすると、予定あり/
なしの状態を変更することができます。また連続した時間帯セルでスワイプすれば、複数
の時間帯の状態を一気に変更できます。また長押しタップで、予定の名前、行われる場所、
重要度などの詳細情報をイベントに追加することができます。もう一つの、「フィード」
タブでは友人の予定やフォローしているユーザーの予定を見れます。ユーザーは承認され
たユーザーだけにスケジュールが表示されるようにできます。このタブもスプレッドシー
トのように見えます。各行には各ユーザーのスケジュールが表示されています。最初の行
は、自分自身のスケジュールを示しています。縦にスクロールして表示する時間帯を変え
たり、横にスクロールしてどのユーザーのスケジュールを表示するか変更することができ
ます。ヘッダーの列には、時間帯が表示されます。特定の時間帯をタップするとその時間
帯が空いているユーザーが最初に表示されます。ヘッダー列は、ユーザーを表示します。
このヘッダーは、画面をスクロールしても上と左に配置されます。特定のユーザーの時間
帯セルを長押しすると、自分はその時間帯は空いているというシグナルをユーザーに送信
できます。シグナルはテキストメッセージと一緒に送られます。ヘッダー行のユーザーセ
ルをタップすると、ユーザーの詳細ページに遷移します。また、画面上部のアプリバーの
すぐ下にある検索フォームで、IDやキーワードで検索しても、ユーザー詳細ページに行く
ことができます。この、ユーザー詳細ページでは、名前、フォロワー&フォロー数(自分
をフォローしているユーザー数、自分がフォローしているユーザー数)、プロフィール写
真、自己紹介などの詳細プロフィールを確認することができます。フォローボタンをタッ
プすると、そのユーザーをフォローできます。また、そのユーザーをブロックすることも
できます。自分のユーザーの詳細ページを開くと、フォローボタンの代わりに編集ボタン
が表示されます。これをクリックするとプロフィールが編集できるページにジャンプしま
す。ユーザー詳細ページの上半分にはそのユーザーの情報が表示されます。下半分には、
自分のスケジュールとそのユーザーのスケジュールが表示されます。ホームページでは画
面の一番上にアプリバーがあります。アプリバーには、設定、通知、自分のプロフィール、
友達追加といったボタンがあります。設定ボタンをタップすると、設定ページに飛びます。
設定ではプライバシーポリシーや利用規約が表示され、アカウント削除のボタンもありま
す。通知ボタンであなたへの友達申請やあなたへのシグナルを確認できるモーダルが表示
されます。表示された各通知をクリックするとそのユーザーの詳細ページに飛びます。友
達追加ページはホームページのフィードタブにある検索フォームとほぼ同じ機能を備えて
います。

更新されたユーザージャーニー:

かなり汚いですが、ChatGPTなら、大丈夫。きれいにまとめてくれました。

ChatGPTの回答
ユーザージャーニーは、GoogleアカウントまたはAppleアカウントでログインできる
サインインページから始まります。アカウントがない場合は、自動的に作成されます。
ログインに成功すると、ユーザーは「マイスケジュール」と「フィード」の2つのタブ
があるホームページにリダイレクトされます。「マイスケジュール」タブではユーザー
は時間範囲を表す各セルを持つスプレッドシートとして自分のスケジュールを表示でき
ます。セルをタップして状態を変更したり、連続する時間範囲をマークするためにホー
ルドスワイプを行ったりすることができます。ホールドタップすると、タイトル、場所、
重要度などの詳細情報をイベントに追加できます。

「フィード」タブでは、ユーザーは友達のスケジュールやフォローしているユーザーの
スケジュールを表示できます。各行はユーザーのスケジュールを表し、ユーザーは垂直
方向にスクロールして時間範囲を変更し、水平方向にスクロールして表示するユーザー
のスケジュールを変更できます。ヘッダー行にはユーザーの名前とプロフィール画像が
表示され、ヘッダーカラムには時間範囲が表示されます。ユーザーが特定の時間範囲を
タップすると、その時間範囲に空いているユーザーのリストが最初に表示されます。
また、特定のユーザーの時間範囲でホールドタップすることで、他の人に自分が空いて
いることを知らせることもできます。上部の画面にある検索フォームでIDやキーワード
でユーザーを検索することもできます。

ユーザーがユーザーのセルをタップすると、ユーザー詳細ページにリダイレクトされ、
ユーザーの名前、プロフィール写真、フォロワー、フォロー、自己説明を表示すること
ができます。このページからユーザーをフォローまたはブロックすることができます。
ユーザーが自分自身のユーザー詳細ページを表示している場合は、プロフィール情報を
編集することもできます。情報は画面の上半分に表示され、自分自身のスケジュールと
友達のスケジュールは下半分に表示されます。

ホームページの上部には、いくつかのボタンがあるアプリバーがあります。「設定」、
「通知」、「プロフィール」、「友達を追加」のボタンがあります。「設定」ボタンを
タップすると、プライバシーポリシー、利用規約、アカウントを削除することができる
ページに移動します。「通知」ボタンをタップすると、友達リクエストや、送信された
シグナルを表示することができます。「プロフィール」ボタンをタップすると自分自身
のユーザー詳細ページに移動します。「友達を追加」ボタンは検索フォームとして機能
し、ユーザーはIDやキーワードで友達を検索することができます。

いやあ、こんなにわかりやすくなるなんて本当にすごいです。これでもいいんですが、一応何か修正できる箇所があるかChatGPTに聞いてみましょう。

プロンプト
あなたは超強力なエンジニアとして振る舞ってください。あなたなら上に載せたユーザ
ージャーニーをどう変えますか?

あなた:

ChatGPTはこんな提案をしてくれました。

ChatGPTの回答
超強力なエンジニアとして、アプリをさらにユーザーフレンドリーで効率的にする
ために、上記のユーザージャーニーにはいくつかの変更点を提案したいです。

サインインページでは、既存の「Googleでログイン」「Appleでログイン」に加
えて、メールアドレスや電話番号でサインアップするオプションを追加します。こ
れにより、サードパーティーのログインオプションを使用したくないユーザーに対
して、より柔軟性を提供することができます。

「フィード」タブでは、各ユーザーのスケジュールをスプレッドシートで表示する
代わりに、各ユーザーのスケジュールをより使いやすい方法で表示するビジュアル
カレンダーを作成することにします。一般的なカレンダーアプリのように、スケジ
ュールを一目で確認でき、各イベントをクリックすると詳細が表示されるようなイ
メージです。

また、友人や同僚とスケジュールを共有するグループを作ることができる機能を追
加します。これにより、ユーザーは特定の人とスケジュールを共有したり、グルー
プのイベントを把握したりすることが容易になります。

ユーザーの詳細ページでは、ユーザーがお互いに都合の良いミーティング時間を提
案できる機能を追加します。これは、各ユーザーのスケジュールで重なっている空
き時間を表示し、両者にとって都合の良い待ち合わせ時間を提案することで実現で
きます。

最後に、スケジュール帳の予定をリマインダーに設定できる機能を追加します。こ
れにより、重要なイベントを忘れることなく、スケジュール管理に役立てることが
できます。

悪くないですね。これで書き換えてもらいましょう。

プロンプト
優れたプログラマーであるあなたは、より良いユーザー体験を提供するために、ユー
ザージャーニー全体を修正します。たとえそれが根本的な変更であっても、どのよう
なレベルの修正でも構いません。しかし、ある瞬間に画面に表示されるすべてのコン
ポーネント、各コンポーネントのユーザーイベントに対するすべての反応、すべての
画面のレイアウトをリストアップしてください。

あなた:

ここの回答で少し気に入らない部分があったので、もう一回修正させてようやくユーザージャーニーは完成です。この回答は次の回答と内容がほぼ同じだったので隠しておきますが、クリックすると見れます。

ChatGPTの回答「修正されたユーザージャーニー」
ChatGPTの回答
修正されたユーザージャーニー:

ランディングページ:
ユーザーは、GoogleやAppleのアカウントでログインするか、新規アカウントを作成
するか選択できるランディングページに誘導されます。

サインアップページ:
新規アカウントを作成する場合は、サインアップページに移動し、氏名、メールアドレ
ス、電話番号、パスワードの入力を行います。入力が完了したら、「アカウントを作成
する」ボタンをクリックします。

プロフィールページ:
アカウントの作成に成功すると、ユーザーはプロフィールページに移動します。ここで、
プロフィール写真と簡単な経歴を追加して、プロフィールを完成させることができます。
また、ここから設定ページにアクセスすることもできます。

トップページ:
プロフィールが完成すると、2つのタブがあるトップページに移動します。「マイスケジュ
ール」と「フィード」の2つのタブがあります。

マイスケジュール:
「マイスケジュール」タブでは、その日の自分のスケジュールを確認することができま
す。画面は表になっており、列はその日の時間帯を、行はイベントを表しています。表
の各セルはクリック可能で、イベント名、場所、重要度などの情報を記入することがで
きます。また、ユーザーはイベントをクリックすることで、編集することができます。

フィード:
「フィード」タブでは、ユーザーの友人のスケジュールを見ることができます。新しい
友達を検索して追加することもできます。画面は表形式で、列は1日の時間帯を、行は
ユーザーを表しています。ユーザーは、上下にスクロールして表示する時間帯を変更し
たり、左右にスクロールして異なるユーザーを表示することができます。

友達を追加する:
画面上部の「友だち追加」ボタンをクリックすると、新しい友達を検索することができ
ます。名前、Eメール、電話番号で友達を検索することができます。追加したい友達が
見つかったら、「追加」ボタンをクリックします。

友だちリクエスト:
ユーザーが友達リクエストを受け取ると、「通知」タブに通知が表示されます。通知を
クリックすると、フレンドリクエストが表示され、承認または拒否することができます。

ユーザー詳細ページ:
「フィード」タブで友達の名前をクリックすると、その友達のスケジュールやプロフィ
ールを見ることができます。ユーザー詳細ページでは、友人のプロフィール写真、名前、
経歴を見ることができます。また、「マイスケジュール」タブと同様に、その日のスケ
ジュールを表形式で確認することができます。

シグナル:
自分のスケジュールと友達のスケジュールのどちらかをクリックすると、その時間帯に
空いていることを知らせることができます。シグナルと一緒に、テキストメッセージを
送信することもできます。

設定ページ:
設定画面は、プロフィールページまたはアプリバーの「設定」ボタンからアクセスでき
ます。設定ページでは、プライバシーポリシー、利用規約の確認、アカウントの削除が
できます。

通知:
アプリバーから「通知」タブにアクセスし、受信した新しい通知を確認することができ
ます。

全体として、ユーザー・ジャーニーの改訂は、アプリのユーザー・インターフェースを
簡素化し、ユーザーが異なる機能を簡単に操作できるようにすることを目的としていま
す。このアプリでは、ユーザーがスケジュールを見たり、各セルに情報を追加したりし
やすいように、テーブルレイアウトを使用しています。また、通知タブを追加すること
で、ユーザーはスケジュールや友達リクエストの更新や変更を簡単に把握することがで
きるようになりました。
プロンプト
良さそうに見えますね。しかし、少し修正する必要があります。ユーザーは、ログイン
やサインアップを選択することはできません。アカウントを持っていない場合、アカウ
ントは自動的に作成され、ランディングページにリダイレクトされます。また、ユーザー
はプライバシー設定(スケジュールを全員に見せるか、それとも友人だけに見せるか)
や主要言語を変更することも可能です。私が今提示した要件に沿って、ユーザージャー
ニーをもう一度書き直してください。

あなた:
ChatGPTの回答
わかりました! 新しい要件に基づき、ユーザージャーニーを再度更新します。

更新されたユーザージャーニー:

1. ユーザーはまずランディングページに飛ぶと、アプリについての簡単な紹介と、
ページの中央にある2つのボタンを見ることができます。「Googleでサインイン」
と「Appleでサインイン」です。

2. GoogleまたはAppleのアカウントでサインインに成功すると、アカウントが自
動的に作成され、ホームページへリダイレクトされます。

3. アカウントを持っていない場合は、自動的にアカウントが作成され、トップペー
ジにリダイレクトされます。

4. トップページでは、2つのタブが表示されます。「マイ・スケジュール」と「フィ
ード」の2つのタブが表示されます。

5. 「マイスケジュール」タブでは、自分のスケジュールを表計算ソフトのように表
示することができます。各セルは時間帯を表し、その時間帯が埋まっている場合は
色が付きます。セルをタップすることで、占有と空きの状態を切り替えることができ
ます。また、長押しスワイプで連続した時間帯を占有・空白にしたり、長押しでタイ
トル、場所、重要度などの詳細情報をイベントに追加することができます。

6. 「フィード」タブでは、友達のスケジュールやフォローしているユーザーのスケ
ジュールを見ることができます。また、このタブはスプレッドシートのように表示さ
れ、各行にはユーザーのスケジュールが表示され、ヘッダー列には時間帯が表示され
ます。縦方向にスクロールして表示する時間帯を変更したり、横方向にスクロールし
てユーザーのスケジュールを切り替えたりすることができます。ヘッダー列にはユー
ザーが表示され、スクロールしても上部と左側に配置される。ユーザーが特定の時間
帯をタップすると、その時間帯に空いているユーザーのリストが表示されます。ヘッ
ダー列のユーザーセルをタップすると、そのユーザーのプロフィールページに移動し
ます。

7. ユーザーの詳細ページでは、名前、フォロー&フォロワー、プロフィール写真、
自己紹介など、ユーザーの詳細なプロフィール情報を見ることができます。ユーザー
はこのページから、そのユーザーをフォローしたりブロックしたりすることができま
す。また、自分のプロフィールページには、「編集」ボタンが表示されます。このボ
タンをクリックすると、新しいページが表示され、自分のプロフィール情報を編集す
ることができます。ページ下部には、自分のスケジュールと相手のスケジュールを確
認することができます。

8. トップページ上部のアプリバーには、いくつかのボタンがあります。「設定」、
「通知」、「プロフィール」、「友達追加」です。「設定」ボタンをクリックすると、
ユーザーは設定ページに移動し、プライバシー設定や主要言語の変更、アカウントの
削除を行うことができます。「通知」ボタンを押すと、ユーザーへの友達申請やシグ
ナルがモーダルで表示されます。それぞれの通知項目をクリックすると、そのユーザ
ーのプロフィールページが表示されます。「プロフィール」ボタンをクリックすると、
自分のプロフィールページが表示されます。友だち追加」ボタンは検索フォームとし
て機能し、IDやキーワードで他のユーザーを検索することができます。

かなり見やすいユーザージャーニーができました。このユーザージャーニーは、この後もプロンプトに何度も挿入するのでどこかに保存しておきましょう。

3. ディレクトリ構造の決定

次はディレクトリ構造を決定していきます。これを決めておくと、あとでコーディングするときに読みやすく洗練されたコードになります。本当です。

プロンプト
完璧です。更新されたユーザー・ジャーニーに忠実に、超熟練プログラマーであるあな
たは、このアプリプロジェクトのディレクトリ構造を示してください。そして、各ファ
イルで何がコーディングされているのかを具体的に説明しなさい。もう一度、ユーザー
ジャーニーを見せるので参考にしてください。

ユーザージャーニー:
(上の回答の丸々コピペ)
ChatGPTの回答
了解です、これがこのアプリプロジェクトのディレクトリ構造です。

app/
├── android/
├── ios/
├── lib/
│   ├── main.dart
│   ├── models/
│   │   ├── user.dart
│   │   ├── event.dart
│   │   └── notification.dart
│   ├── services/
│   │   ├── authentication.dart
│   │   ├── firestore.dart
│   │   └── notification.dart
│   ├── screens/
│   │   ├── landing_page.dart
│   │   ├── home_page.dart
│   │   ├── my_schedule.dart
│   │   ├── feed.dart
│   │   ├── user_detail.dart
│   │   ├── profile.dart
│   │   ├── settings.dart
│   │   ├── notifications.dart
│   │   └── search.dart
│   ├── widgets/
│   │   ├── schedule_cell.dart
│   │   ├── schedule_header.dart
│   │   ├── event_tile.dart
│   │   ├── user_tile.dart
│   │   ├── follow_button.dart
│   │   └── language_dropdown.dart
│   └── constants.dart
└── test/

main.dartはアプリのエントリポイントであり、アプリのテーマとルーティングを
提供するトップレベルのMaterialAppウィジェットを定義しています。
models/フォルダには、User、Event、Notificationなど、アプリのデータ構造
を表すクラスが含まれています。
services/フォルダには、Authentication、Firestore、Notificationなど
のFirebaseとの通信を処理するクラスが含まれています。
screens/フォルダには、LandingPage、HomePage、MySchedule、Feed、User
Detail、Profile、Settings、Notifications、Searchなど、アプリのメイン
画面が含まれています。
widgets/フォルダには、ScheduleCell、ScheduleHeader、EventTile、User
Tile、FollowButton、LanguageDropdownなど、再利用可能なUIコンポーネント
が含まれています。
constants.dartファイルには、アプリ全体で使用されるグローバル定数が含まれて
います。

以下は、各ファイルで具体的にコーディングされている内容です。

main.dart:
アプリのテーマとルーティングを提供するトップレベルのMaterialAppウィジェット
を定義しています。各画面のルートを設定し、認証の状態変化を処理して、ユーザーを
適切な画面にリダイレクトします。
models/user.dart:
名前、プロフィール画像、フォロワー、フォロー、自己紹介など、ユーザーのプロフィ
ール情報を表すUserクラスを定義しています。
models/event.dart:
ユーザーのスケジュールにおけるイベント(開始時間、終了時間、タイトル、場所、重
要度など)を表すEventクラスを定義します。
models/notification.dart:
ユーザーに送信される通知を表すNotificationクラスを定義し、そのタイプ(友達
リクエスト、シグナルなど)、送信者を含みます。
services/authentication.dart:
GoogleやAppleのサインインを使用したFirebaseでのユーザー認証を処理する
Authenticationクラスを定義しています。
services/firestore.dart:
Firebase Firestoreとの通信を行い、ユーザーやイベントのデータを取得・更新す
るFirestoreクラスを定義します。
services/notification.dart:Firebase Cloud Messagingとの通信を行い、
プッシュ通知の送受信を行うNotificationServiceクラスを定義しています。
screens/landing_page.dart:
ユーザーがGoogleまたはAppleでサインインするためのランディングページを表示し
ます。
screens/home_page.dart: screens/home_page.dart:
ユーザーが自分のスケジュールや友人のスケジュールを確認することができるホーム画
面を表示します。
screens/my_schedule.dart。screens/my_schedule.dart:
ユーザー自身のスケジュールを、時間帯や職業を表すセルを持つスプレッドシートのよ
うなビューとして表示します。
screens/feed.dart。screens/feed.dart:
現在のユーザーがフォローしているユーザーのスケジュールを、時間範囲とユーザーの
占領状態を表すセルとともにスプレッドシートのように表示します。
screens/user_detail.dart:
特定のユーザーのプロファイル情報を表示します。

今回のChatGPTの回答はとびきり長いですね。読みましたか? たぶん読み飛ばしましたよね。それで大丈夫です。前にも書きましたが、これは人間が読むためではなくてChatGPTが指示の内容を理解するために回答させています。あなたもしつこいくらい確認してあげましょう。指差し確認「ヨシ!」

4. 全体の実装計画の作成

ついにプログラミングが始まります……と言いたいところですが、実装計画を最初に作りましょう。ChatGPTには段階を踏ませよ、です。

プロンプト
素晴らしい! 超熟練プログラマーのあなたは、この指示の最後にもう一度紹介する
ディレクトリ構造に厳密に従って、実装全体の流れを示します。各ステップでどのコ
ンポーネントを実装しているかも合わせて書いてください。

ディレクトリ構造:
(上の回答の一部分をコピペ)

あなた:
ChatGPTの回答
もちろんいいですよ。ディレクトリ構造に従って実装のワークフローを示します。

models/user.dartに、ユーザーのプロフィール情報(名前、プロフィール写真、
フォロワー、フォロー、自己紹介など)を表すUserクラスを実装する。

models/event.dartに、ユーザーのスケジュールにおけるイベントを表すEvent
クラスを実装する(開始時間、終了時間、タイトル、場所、重要度を含む)。

ユーザーに送信される通知を表すNotificationクラスを
models/notification.dartに実装し、そのタイプ(友達リクエスト、シグナル
など)、送信者を含む。

services/authentication.dartにAuthenticationクラスを実装し、
GoogleやAppleのサインインによるFirebaseでのユーザ認証を処理する。

services/firestore.dartにFirestoreクラスを実装し、Firebase
Firestoreとの通信を行い、ユーザデータやイベントデータの取得・更新を行いま
す。

services/notification.dartにNotificationServiceクラスを実装し、
Firebase Cloud Messagingとの通信を行い、プッシュ通知の送受信を行います。

screens/landing_page.dartにLandingPageウィジェットを実装し、ユーザー
がGoogleまたはAppleでサインインできるランディングページを表示します。

screens/home_page.dartにHomePageウィジェットを実装し、ユーザーが自分の
スケジュールや友人のスケジュールを確認できるホームページを表示することができ
るようにします。

screens/my_schedule.dartにMyScheduleウィジェットを実装し、ユーザー自
身のスケジュールを、時間帯と職業状態を表すセルを持つスプレッドシート風の
ビューとして表示します。

screens/feed.dartに、現在のユーザーがフォローしているユーザーのスケジュー
ルを、時間範囲とユーザーの職業状態を表すセルを含むスプレッドシートのような
ビューとして表示するFeedウィジェットを実装します。

screens/user_detail.dartに、特定のユーザのプロファイル情報を表示する
UserDetailウィジェットを実装します。

各ファイルの必要な依存関係をインポートし、正しく動作することを確認するための
テストを忘れずに行ってください。また、main.dartで認証状態の変更とルーティン
グを処理することも忘れないでください。

5. 個別クラスの要件定義

ChatGPTが作ってくれた実装計画に沿って実装していきます。ですが、ただ「実装計画に沿ってクラス〇〇を実装しろ」と言ってもうまくいきません。そもそも実装計画やこれまで決めてきたユーザージャーニーを忘れている場合もあるので。そこで、最初はやはり復唱させます。

screens/landing_page.dartlanding_page.dartウィジェットの実装を例に取ります。他のコンポーネントも基本は同じです。

プロンプト
あなたはLandingPageウィジェットを実装します。ユーザージャーニーの関連する
部分を読んで、このウィジェットがどのように機能するか教えてください。

ユーザージャーニー:
ユーザーは、アプリについての簡単な紹介と、ページの中央にある2つのボタンを見
ることができるランディングページに着陸します。「Googleでサインイン」と
「Appleでサインイン」です。

あなた:
ChatGPTの回答
LandingPageウィジェットは、ユーザーがアプリにアクセスする際の入口となり
ます。アプリの簡単な紹介文と、GoogleまたはAppleでサインインするための2
つのボタンが表示されます。ユーザーが「Sign in with Google」ボタンをタッ
プすると、アプリはGoogleサインインフローを起動し、ユーザーを認証する必要
があります。同様に、ユーザーが「Sign in with Apple」ボタンをタップする
と、アプリはAppleサインインフローを開始してユーザーを認証する必要があり
ます。

まとめると、LandingPageウィジェットは以下のような役割を担っています。

1. アプリの簡単な紹介を表示する。
2. ユーザーがGoogleまたはAppleでサインインできるように、2つのボタンを
持つこと。

対応するボタンがタップされると、適切なサインインフローを開始します。

問題が無ければ続けてプロンプトを入力します。何か誤解があるようなら、必要に応じて情報を追加して指示しましょう。そこまで深刻な誤解でなければ、回答を再生成してもいいでしょう。ただ経験上再生成では回答の質はむしろ劣化します。数回繰り返しても変化がなければ、思い切ってプロンプトを変えてください。

プロンプト
素晴らしい。このウィジェットをどのように実装するか、ステップ・バイ・ステップで
手順を教えてください。同時にそれぞれのステップで変更したコードを示してください。

あなた:
ChatGPTの回答
もちろんです。ここではLandingPageウィジェットを実装するための手順をステップ
・バイ・ステップで説明します。

1. まず、screensディレクトリにlanding_page.dartという名前のファイルを新規に
作成します。

2. 必要なパッケージをインポートしてください。

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:flutter_auth_buttons/flutter_auth_buttons.dart';

3. StatefulWidgetを継承したLandingPageというクラスを新規に作成します。

class LandingPage extends StatefulWidget {
  @override
  _LandingPageState createState() => _LandingPageState();
}

4. State<LandingPage>を拡張した_LandingPageStateという新しいクラスを
作成します。

class _LandingPageState extends State<LandingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        // TODO: Add content here
      ),
    );
  }
}

5. Containerウィジェットに、アプリのロゴとアプリに関する簡単な紹介文を追加
します。

body: Container(
  padding: EdgeInsets.all(16.0),
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: <Widget>[
      // TODO: Add logo here
      SizedBox(height: 16.0),
      Text(
        'Welcome to My Schedule App!',
        style: TextStyle(
          fontSize: 24.0,
          fontWeight: FontWeight.bold,
        ),
        textAlign: TextAlign.center,
      ),
      SizedBox(height: 16.0),
      Text(
        'Keep track of your schedule and share it with friends!',
        style: TextStyle(
          fontSize: 16.0,
        ),
        textAlign: TextAlign.center,
      ),
    ],
  ),
),

6. Containerウィジェットの下部に「Googleでログイン」ボタンを追加する。

body: Container(
  // Existing content
  child: Column(
    // Existing children
    Expanded(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          GoogleSignInButton(
            onPressed: () {
              // TODO: Implement Google Sign-in
            },
            darkMode: true,
          ),
          SizedBox(height: 16.0),
          AppleSignInButton(
            onPressed: () {
              // TODO: Implement Apple Sign-in
            },
            style: AppleButtonStyle.black,
            borderRadius: BorderRadius.circular(8.0),
          ),
        ],
      ),
    ),
  ),
),

7. ボタンのonPressedメソッドに必要なコードを追加して、Google Sign-inと
Apple Sign-inの機能を実装します。

8. main.dartのMaterialAppウィジェットを更新して、アプリのナビゲーション
スタックにLandingPageを追加します。

MaterialApp(
  title: 'My Schedule App',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  home: LandingPage(), // Add this line
);

これで完了です。これでLandingPageウィジェットがあなたのアプリに実装されました。

6. 個別クラスの実装

これをそのままコピペして実装完了、とは残念ながらなりません。大抵どこかエラーを吐いたり表示がバグる部分があるので直していきます。できそうなら、プロンプトを修正してChatGPTに引き続き実装させるのもいいでしょう。とはいえ、そのうち英語の文章を考えるのが面倒くさくなって、直接実装しにいくことも多いですが。

実装し終わったら、ちゃんとChatGPTに報告します。

プロンプト
自分でscreens/landing_page.dartのLandingPageウィジェットを実装しました。
コードを下に示します。

LandingPageウィジェット:
(自分で書いたコード)
ChatGPTの回答
素晴らしい! うまく実装されているように見えますね。

7. 5-6を繰り返す

この作業を繰り返します。必要に応じて新たにファイルを作ってもいいでしょう。そのたびにどんなクラスを追加したのか説明すれば、ちゃんと実装手順を考えてくれます。試しに、最初のディレクトリ構造にはなかったwidgets/add_friend.dartで、AddFriendウィジェットを実装させてみましょう。

プロンプト
widgets/add_friend.dartにAddFriendウィジェットを実装したいです。
ランディングページのアプリバーから飛ぶことができ、ユーザーをID、電話番
号、キーワードで検索して友達追加することができます。このウィジェットが
どう機能するか教えてください。

あなた:
ChatGPTの回答
もちろんです。AddFriendウィジェットは、ユーザーがユーザーID、電話番号、
キーワードなど様々な方法で友達を検索し、自分のスケジュールに追加すること
ができるウィジェットです。

このウィジェットを実装するには、まず、テキスト入力や検索をトリガーする
ボタンなど、検索機能のUIを作成する必要があります。ユーザーが検索クエ
リを入力すると、Firebase Cloud Firestoreを使って関連するユーザー
情報を検索することができます。

検索結果が一致した場合、そのユーザーの情報を表示し、友人として追加する
オプションを提供することができます。ユーザーが友達追加を選択すると、
Firestoreのドキュメントを更新して、新しい友達の情報を含めることができ
ます。

さらに、ユーザー自身のスケジュールへのリンクを友人と共有するオプション
を提供することも可能で、その場合、各ユーザーに固有のリンクを生成して
Firestoreに保存する必要があります。この場合、ユーザーごとにユニークな
リンクを生成し、Firestoreに保存する必要があります。これにより、ユーザ
ーは友人にリンクを手動で送信することなく、簡単に自分のスケジュールを共
有することができます。

これらのステップについて、より詳細な情報が必要な場合は教えてください。
プロンプト
ファンタスティック! あなたが新しくコーディングまたは修正したコードを
そのつど提供しながら、AddFriendウィジェットを実装してください。

あなた:

あとは同じです。頑張って仕上げましょう。

8. AppStoreに提出

最後にAppStoreに公開しましょう。どんなにいいアプリを作っても誰も使ってくれなければ意味はないので。

さて、AppStoreの提出に最低限必要なのは紹介文、プライバシーポリシー、アイコン、スクリーンショットの4つです。まず、一番簡単な紹介文とプライバシーポリシーから仕上げちゃいましょう。

いつものようにChatGPTに聞きます。

プロンプト
あなたは売れっ子コピーライターです。私はこのアプリをAppStoreに提出したい
です。このアプリの説明文を書いてください。

あなた:
ChatGPTの回答
究極のスケジュール管理ツール、Frienduleを紹介します。

Frienduleを使えば、友人とスケジュールを共有することがこれまでになく簡単に
なります。このアプリは、シンプルで直感的なユーザーインターフェースで設計され
ており、週や月のスケジュールをスワイプして、素早くイベントの追加や編集を行う
ことが可能です。

しかし、それだけではありません。Frienduleは、友人に尋ねることなく、友人と
のスケジュールを見たり、比較したりすることもできます。ID、電話番号、キーワー
ドで相手のプロフィールを検索するだけで、その人のスケジュールが目の前に現れま
す。彼らのスケジュールは目の前にあり、簡単に識別できるように色分けされていま
す。

Frienduleがあれば、もう大事なイベントを見逃すことはありません。今日か
らアプリをダウンロードして、簡単にスケジュールを共有しましょう。

いいですねえ。次はプライバシーポリシーです。本当は弁護士に相談したほうがいいのですが、本格的な法律文書はアプリがたくさんの人にダウンロードされるようになったら考えることにします。

プロンプト
あなたは経験豊富な弁護士です。このアプリのプライバシーポリシーを書いてください。

あなた:
ChatGPTの回答
Friendule - プライバシーポリシー

Frienduleでは、お客様のプライバシーを大切に考えています。このプライバシー
ポリシーでは、当社が収集する情報の種類とその使用方法、共有方法、保護につい
て説明します。

当社が収集する情報
Frienduleでは、お客様のお名前、メールアドレス、電話番号、その他お客様が共
有する個人情報などの情報を収集します。また、お客様のスケジュールデータや他の
ユーザーとのやり取りなど、お客様のアプリの使用に関するデータも収集します。こ
のデータは、アプリの特徴や機能を改善するために使用されます。

情報の使用
Frienduleアプリの提供や改善、ユーザー体験のパーソナライズ、アップデートや
新機能に関する連絡のために収集した情報を使用します。また、法律、セキュリティ、
運営上の目的でお客様の情報を使用することもあります。

情報の共有
当社は、アプリの機能や特徴を提供するために当社を支援する信頼できる第三者ベン
ダーとお客様の情報を共有することがあります。また、お客様が友人や家族とスケジュ
ールを共有する場合など、お客様の指示により、他のユーザーとお客様の情報を共有
することもあります。当社は、お客様の個人情報を第三者のマーケティング担当者や
広告主に販売することは決してありません。

データの保持
当社は、Frienduleアプリおよび関連サービスを提供するために必要な期間、あなた
の情報を保持します。また、法律上、セキュリティ上、または運営上の目的でお客様の
情報を保持することもあります。

セキュリティ
当社は、お客様の個人情報のセキュリティを重視し、不正なアクセス、使用、開示か
ら個人情報を保護するために業界標準の方法を採用しています。

プライバシーポリシーの更新
当社は、本プライバシーポリシーを随時更新することがあります。重要な変更を行う
場合は、電子メールまたはアプリを通じてお客様に通知します。

連絡先
本プライバシーポリシーまたはFrienduleアプリに関するご質問やご不明な点がある
場合は、下記までご連絡ください。

悪くないんじゃないでしょうか。

次はアイコンとスクリーンショットを作ります。ここはもうセンスに頼るしかないですが、Canvaのテンプレートを使えば相当見栄えよくなります。
https://www.canva.com/

公開

お疲れさまでした! まだるっこしい審査こそありますが、ここまできたらさすがに一息ついても大丈夫です。本当にお疲れさまでした。もしこの記事を見てアプリを作ってくれた人がいたら、あなたのアプリをぜひ見せてください。

ではでは、ここまで読んでくれて本当にありがとうございます!

他の記事

と、ここで物足りないあなたは、最近書いた記事も読んでみてください! とびっきり面白いですよ!
https://zenn.dev/niwatoro/articles/180f6185c382bb
https://zenn.dev/niwatoro/articles/296cf12dd8cd62

Discussion

ranorano

ちょうど知りたい、痒い所に手が届く記事でした!
ありがとうございます

にわとろにわとろ

ありがとうございます! これからも記事を書いていくのでぜひ見てください!!!