初めまして、にわとろです。
さて今回は、ChatGPTを使ってiOSアプリをイチから作ってみました。ChatGPTの記事なんてもうオーバーフローするほどあるのですが、今のところiOSアプリを最後まで作り通した記事はありません。
理由は簡単で、ChatGPTは「バカ」なのでiOSアプリなんて複雑なモノを完成させられないからです。
しかしバカも使いようです。上手く使いこなしてやれば、アプリだって作ることができます。ChatGPTはバカですが、有能なバカです。でもあなたがヤツをわかっていなければ、やっぱり無能のままです。だから、この記事を読んで理解してあげないといけません。
それじゃあ、ChatGPTと仲良くなりにいきましょう。
早速ChatGPTを使う極意を教えます。全部読み通せなくても、これだけは覚えてください。
いい上司になれ。
何を言っているかというと、ChatGPTには「わからないことを聞かないでください。」 ChatGPTはあんまり賢くありません。「アプリを作りたい」なんて曖昧なことを言われても、「アプリとはApplicationの略で……」と的外れな返答をしてしまいます。ちゃんとした仕事をさせるには、こっちもまともな指示を与えないといけません。
これは人間と同じです。あなただって上司にいきなり「アプリ作りたいんだけどさ……」と言われても困りますよね? 「何の機能があるアプリを、どの技術を使って、どんなUIで実装しろ」まで聞いて初めて実装に取りかかれます。ChatGPTを使うときは自分が「いい上司」になってわかりやすく、具体的な指示をしてあげましょう。
ここからは今回どんなアプリをどういう環境で作ったのか説明します。あなたも読みながら、どんなアプリを作りたいか、どんな追加設定が必要か、考えてみてください。
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に食わせるテキスト(プロンプト)を工夫(エンジニアリング)することです。
これが案外バカにならなくて、言葉遣い一つで結果が全然違ってくるものです。自分が使っているプロンプトエンジニアングをいくつか紹介するので、試してみてください。
ChatGPTは日本語の回答も精度が高いので、ついつい日本語を使ってしまいがちです。ただ、英語を使ったほうがいいです。とても癪なことに、ここ100年間世界は英語で動いています。英語を使うようにして、世界の集合知に食らいつきましょう。別に凝った表現を使わなくてもいいし、多少綴りを間違えても大丈夫です。日本語で書いてDeepLに、英語の回答をまたDeepLに戻すだけで十分です。それでも面倒な人には、今回使った全プロンプトを本にしたので参考にしてください。
https://zenn.dev/niwatoro/books/254abf0b3f7031
自分とChatGPTにそれぞれ役割を割りふって会話するようにしましょう。よく使うのは、クライアントとエンジニア、マネージャーとデザイナー、作家と編集者です。状況設定に迷ったら、自分なら誰に相談したいかを考えてみましょう。そしてその人になりきるようにChatGPTに言えばいいのです。こんな感じです。
あなたはしゃれたお店のベテラン店員です。私はあなたの店を訪れました。私は妻にホワイトデーのお返しをしたいと思っています。私はあなたに助言を求めました。いやあ、本当に何を贈ればいいんでしょうね?
複雑な問題は少しずつ段階を踏んでやらせましょう。人間が暗算するより筆算したほうが正答率は高いのと同じです。とは言っても具体的にはどう段階に分ければいいかわからないと思うので、自分がよく使っている分け方を紹介します。
ChatGPTが何かやってくれるたびに褒めてあげましょう。少しくらい修正が要るときでも、ちゃんと最初は褒め言葉を付けてください。あなただって人に仕事を頼むときは、相手をおだてるはずです。ChatGPTだって褒められると嬉しいですし、はりきって仕事をしてくれます。インガオホー!
まず初めにFlutterで新しいプロジェクトを作ってください。プロジェクトのフォルダを作りたい場所で以下のシェルコマンドを実行します。
flutter create<プロジェクトの名前>作りましたね?
さて、ここからアプリを完成させるまでのステップをずらっと列挙してみると、こんな感じになります。気に入らなければChatGPTと相談してくれても構いません。なるべく段階を踏ませたほうがいいですが、やり過ぎると前に指示したことを忘れます。ちょうどいい分け方を見つけてみてください。
どのステップでやることも基本同じです。やってほしいことを言ってから、やるべきことを要約させます。一度の作業量が多くなりそうだったら、段階を踏んでやらせます。特に複雑なクラスを実装するときには、回答が収まりきらないことがあるので分割は効果的です。もし回答が不十分だと感じたら、指示に情報を追加してもう一度回答を生成させます。
以下、今回どんなプロンプトを与えてどんな回答を貰ったかを載せていきます。見やすいように日本語に翻訳していますが、本当は全て英語で書いています。それからZennのコードブロック内は改行されないので、適当なところで改行もしています。別に本を書いて今回使った全プロンプトをそのままで公開しているので、ぜひぜひ参考にしてください。
https://zenn.dev/niwatoro/books/254abf0b3f7031
最初にアプリのアイデアの壁打ちをします。あくまで壁打ちなので、この段階ではアイデアが固まっていなくても構いません。このアプリにしても後から変えた部分がありますが、そのつどChatGPTに言えば柔軟に対応してくれます。
あなたはめっちゃ頭がいいエンジニアとして振る舞ってください。次のアプリの説明を読んで、詳細な実装指示を出すために必要なことを何でもいいので聞いてください。説明:私はFlutterとFirebaseを使って、スケジュールを他人と共有するための実用アプリを開発しています。このアプリの最も重要な点は、UIが非常に単純であることです。具体的に何をするのかを指定する必要はありません。やることがある時間帯をタップしたり、スワイプしたりするだけです。また、1週間や1ヶ月単位でスケジュールを確認することもできます。次に重要なのは、友達のスケジュールを見たり、自分のスケジュールと比較したりできることです。IDや電話番号、キーワードで検索して友達を追加することができます。また自分のスケジュールのリンクを共有することもできます。あなた:最後の「あなた:」はかなり重要です。OpenAIの検閲が回避できます。既にChatGPTを自分で遊んだ人なら、何か面白いことを聞くと「すみません、私はAI言語モデルであり……」と返ってくるのに相当いらだったことがあるでしょう。あれは、「ChatGPT」に直接問題を聞くと起こります。「ChatGPT」ではなく、ChatGPTの中の「あなた」に聞くようにすればいいのです。まあ、それでもたまにAI言語モデルの人格が出てきちゃうんですが。
ChatGPTの回答を見てみましょう。
アプリの具体的な機能について、もう少し詳しく教えてください。ユーザーはどのように自分のスケジュールにイベントを追加できるのでしょうか? また今後のイベントのリマインダーや、通知を設定するオプションはあるのでしょうか? また複数の人が同時にスケジュールを組もうとした場合、アプリはどのようにコンフリクトを処理するのでしょうか?また、セキュリティ面では、スケジュールを他人と共有する際に、ユーザーのデータを保護するためにどのような対策が取られるのでしょうか? 最後に、このアプリがFirebaseとどのように統合されるのか、また、このアプリの開発においてFirebaseのどのような機能やサービスが利用されるのかを説明してください。上でChatGPTから得られたフィードバックを元に、ユーザージャーニーを作成していきましょう。ユーザージャーニーとは、ユーザーがプロダクトやソフトウェアを使うときの体験のことです。要するに、アプリのどこをどう操作したら、どんな変化があってどんな機能が使えるかを説明すればいいのです。
これを頭に入れて、つらつら書いていきます。どうせChatGPTがわかりやすくまとめてくれるはずなので、多少の文法ミスは気にせず書いていきましょう。
これ以降、プロンプトとChatGPTの回答を交互に示しますが、かなり文量が多いのでほどほどに読み飛ばすのがいいと思います。実際、いくつかは人間が読んで理解するというより、ChatGPTに復唱させて理解を固めるためにやっている側面もあるので。
今からユーザージャーニーの概略を書きます。これを読んでください。それから、誰もが同じアプリを想像できてコードを書き始めることができるように、ユーザージャーニーを更新してください。このとき、ページ名やコンポーネント名を変えるなど、機能をよりよく表現するために必要な修正を加えてください。ユーザージャーニーの概略:ユーザーはまず、サインインページにたどり着きます。サインインページでは、真ん中に2つのボタンがあります。「Googleでログイン」「Appleでログイン」の2つです。まだアカウントを作成していなくても、Google/Appleアカウントでログインに成功すれば、自動でアカウントが作成されます。ユーザーはこれら2つのプロバイダがアプリに与える情報よりも多くの情報を後から提供することができます。サインインまたはログインに成功した場合は、ホームページにリダイレクトされます。ホームページには2つのタブがあります。最初の「マイスケジュール」タブでは、自分のスケジュールを見ることができます。その見た目はスプレッドシートに似ています。各セルは各時間帯を表しています。その時間帯が埋まっているときには色がついています。セルをタップすると、予定あり/なしの状態を変更することができます。また連続した時間帯セルでスワイプすれば、複数の時間帯の状態を一気に変更できます。また長押しタップで、予定の名前、行われる場所、重要度などの詳細情報をイベントに追加することができます。もう一つの、「フィード」タブでは友人の予定やフォローしているユーザーの予定を見れます。ユーザーは承認されたユーザーだけにスケジュールが表示されるようにできます。このタブもスプレッドシートのように見えます。各行には各ユーザーのスケジュールが表示されています。最初の行は、自分自身のスケジュールを示しています。縦にスクロールして表示する時間帯を変えたり、横にスクロールしてどのユーザーのスケジュールを表示するか変更することができます。ヘッダーの列には、時間帯が表示されます。特定の時間帯をタップするとその時間帯が空いているユーザーが最初に表示されます。ヘッダー列は、ユーザーを表示します。このヘッダーは、画面をスクロールしても上と左に配置されます。特定のユーザーの時間帯セルを長押しすると、自分はその時間帯は空いているというシグナルをユーザーに送信できます。シグナルはテキストメッセージと一緒に送られます。ヘッダー行のユーザーセルをタップすると、ユーザーの詳細ページに遷移します。また、画面上部のアプリバーのすぐ下にある検索フォームで、IDやキーワードで検索しても、ユーザー詳細ページに行くことができます。この、ユーザー詳細ページでは、名前、フォロワー&フォロー数(自分をフォローしているユーザー数、自分がフォローしているユーザー数)、プロフィール写真、自己紹介などの詳細プロフィールを確認することができます。フォローボタンをタップすると、そのユーザーをフォローできます。また、そのユーザーをブロックすることもできます。自分のユーザーの詳細ページを開くと、フォローボタンの代わりに編集ボタンが表示されます。これをクリックするとプロフィールが編集できるページにジャンプします。ユーザー詳細ページの上半分にはそのユーザーの情報が表示されます。下半分には、自分のスケジュールとそのユーザーのスケジュールが表示されます。ホームページでは画面の一番上にアプリバーがあります。アプリバーには、設定、通知、自分のプロフィール、友達追加といったボタンがあります。設定ボタンをタップすると、設定ページに飛びます。設定ではプライバシーポリシーや利用規約が表示され、アカウント削除のボタンもあります。通知ボタンであなたへの友達申請やあなたへのシグナルを確認できるモーダルが表示されます。表示された各通知をクリックするとそのユーザーの詳細ページに飛びます。友達追加ページはホームページのフィードタブにある検索フォームとほぼ同じ機能を備えています。更新されたユーザージャーニー:かなり汚いですが、ChatGPTなら、大丈夫。きれいにまとめてくれました。
ユーザージャーニーは、GoogleアカウントまたはAppleアカウントでログインできるサインインページから始まります。アカウントがない場合は、自動的に作成されます。ログインに成功すると、ユーザーは「マイスケジュール」と「フィード」の2つのタブがあるホームページにリダイレクトされます。「マイスケジュール」タブではユーザーは時間範囲を表す各セルを持つスプレッドシートとして自分のスケジュールを表示できます。セルをタップして状態を変更したり、連続する時間範囲をマークするためにホールドスワイプを行ったりすることができます。ホールドタップすると、タイトル、場所、重要度などの詳細情報をイベントに追加できます。「フィード」タブでは、ユーザーは友達のスケジュールやフォローしているユーザーのスケジュールを表示できます。各行はユーザーのスケジュールを表し、ユーザーは垂直方向にスクロールして時間範囲を変更し、水平方向にスクロールして表示するユーザーのスケジュールを変更できます。ヘッダー行にはユーザーの名前とプロフィール画像が表示され、ヘッダーカラムには時間範囲が表示されます。ユーザーが特定の時間範囲をタップすると、その時間範囲に空いているユーザーのリストが最初に表示されます。また、特定のユーザーの時間範囲でホールドタップすることで、他の人に自分が空いていることを知らせることもできます。上部の画面にある検索フォームでIDやキーワードでユーザーを検索することもできます。ユーザーがユーザーのセルをタップすると、ユーザー詳細ページにリダイレクトされ、ユーザーの名前、プロフィール写真、フォロワー、フォロー、自己説明を表示することができます。このページからユーザーをフォローまたはブロックすることができます。ユーザーが自分自身のユーザー詳細ページを表示している場合は、プロフィール情報を編集することもできます。情報は画面の上半分に表示され、自分自身のスケジュールと友達のスケジュールは下半分に表示されます。ホームページの上部には、いくつかのボタンがあるアプリバーがあります。「設定」、「通知」、「プロフィール」、「友達を追加」のボタンがあります。「設定」ボタンをタップすると、プライバシーポリシー、利用規約、アカウントを削除することができるページに移動します。「通知」ボタンをタップすると、友達リクエストや、送信されたシグナルを表示することができます。「プロフィール」ボタンをタップすると自分自身のユーザー詳細ページに移動します。「友達を追加」ボタンは検索フォームとして機能し、ユーザーはIDやキーワードで友達を検索することができます。いやあ、こんなにわかりやすくなるなんて本当にすごいです。これでもいいんですが、一応何か修正できる箇所があるかChatGPTに聞いてみましょう。
あなたは超強力なエンジニアとして振る舞ってください。あなたなら上に載せたユーザージャーニーをどう変えますか?あなた:ChatGPTはこんな提案をしてくれました。
超強力なエンジニアとして、アプリをさらにユーザーフレンドリーで効率的にするために、上記のユーザージャーニーにはいくつかの変更点を提案したいです。サインインページでは、既存の「Googleでログイン」「Appleでログイン」に加えて、メールアドレスや電話番号でサインアップするオプションを追加します。これにより、サードパーティーのログインオプションを使用したくないユーザーに対して、より柔軟性を提供することができます。「フィード」タブでは、各ユーザーのスケジュールをスプレッドシートで表示する代わりに、各ユーザーのスケジュールをより使いやすい方法で表示するビジュアルカレンダーを作成することにします。一般的なカレンダーアプリのように、スケジュールを一目で確認でき、各イベントをクリックすると詳細が表示されるようなイメージです。また、友人や同僚とスケジュールを共有するグループを作ることができる機能を追加します。これにより、ユーザーは特定の人とスケジュールを共有したり、グループのイベントを把握したりすることが容易になります。ユーザーの詳細ページでは、ユーザーがお互いに都合の良いミーティング時間を提案できる機能を追加します。これは、各ユーザーのスケジュールで重なっている空き時間を表示し、両者にとって都合の良い待ち合わせ時間を提案することで実現できます。最後に、スケジュール帳の予定をリマインダーに設定できる機能を追加します。これにより、重要なイベントを忘れることなく、スケジュール管理に役立てることができます。悪くないですね。これで書き換えてもらいましょう。
優れたプログラマーであるあなたは、より良いユーザー体験を提供するために、ユーザージャーニー全体を修正します。たとえそれが根本的な変更であっても、どのようなレベルの修正でも構いません。しかし、ある瞬間に画面に表示されるすべてのコンポーネント、各コンポーネントのユーザーイベントに対するすべての反応、すべての画面のレイアウトをリストアップしてください。あなた:ここの回答で少し気に入らない部分があったので、もう一回修正させてようやくユーザージャーニーは完成です。この回答は次の回答と内容がほぼ同じだったので隠しておきますが、クリックすると見れます。
修正されたユーザージャーニー:ランディングページ:ユーザーは、GoogleやAppleのアカウントでログインするか、新規アカウントを作成するか選択できるランディングページに誘導されます。サインアップページ:新規アカウントを作成する場合は、サインアップページに移動し、氏名、メールアドレス、電話番号、パスワードの入力を行います。入力が完了したら、「アカウントを作成する」ボタンをクリックします。プロフィールページ:アカウントの作成に成功すると、ユーザーはプロフィールページに移動します。ここで、プロフィール写真と簡単な経歴を追加して、プロフィールを完成させることができます。また、ここから設定ページにアクセスすることもできます。トップページ:プロフィールが完成すると、2つのタブがあるトップページに移動します。「マイスケジュール」と「フィード」の2つのタブがあります。マイスケジュール:「マイスケジュール」タブでは、その日の自分のスケジュールを確認することができます。画面は表になっており、列はその日の時間帯を、行はイベントを表しています。表の各セルはクリック可能で、イベント名、場所、重要度などの情報を記入することができます。また、ユーザーはイベントをクリックすることで、編集することができます。フィード:「フィード」タブでは、ユーザーの友人のスケジュールを見ることができます。新しい友達を検索して追加することもできます。画面は表形式で、列は1日の時間帯を、行はユーザーを表しています。ユーザーは、上下にスクロールして表示する時間帯を変更したり、左右にスクロールして異なるユーザーを表示することができます。友達を追加する:画面上部の「友だち追加」ボタンをクリックすると、新しい友達を検索することができます。名前、Eメール、電話番号で友達を検索することができます。追加したい友達が見つかったら、「追加」ボタンをクリックします。友だちリクエスト:ユーザーが友達リクエストを受け取ると、「通知」タブに通知が表示されます。通知をクリックすると、フレンドリクエストが表示され、承認または拒否することができます。ユーザー詳細ページ:「フィード」タブで友達の名前をクリックすると、その友達のスケジュールやプロフィールを見ることができます。ユーザー詳細ページでは、友人のプロフィール写真、名前、経歴を見ることができます。また、「マイスケジュール」タブと同様に、その日のスケジュールを表形式で確認することができます。シグナル:自分のスケジュールと友達のスケジュールのどちらかをクリックすると、その時間帯に空いていることを知らせることができます。シグナルと一緒に、テキストメッセージを送信することもできます。設定ページ:設定画面は、プロフィールページまたはアプリバーの「設定」ボタンからアクセスできます。設定ページでは、プライバシーポリシー、利用規約の確認、アカウントの削除ができます。通知:アプリバーから「通知」タブにアクセスし、受信した新しい通知を確認することができます。全体として、ユーザー・ジャーニーの改訂は、アプリのユーザー・インターフェースを簡素化し、ユーザーが異なる機能を簡単に操作できるようにすることを目的としています。このアプリでは、ユーザーがスケジュールを見たり、各セルに情報を追加したりしやすいように、テーブルレイアウトを使用しています。また、通知タブを追加することで、ユーザーはスケジュールや友達リクエストの更新や変更を簡単に把握することができるようになりました。良さそうに見えますね。しかし、少し修正する必要があります。ユーザーは、ログインやサインアップを選択することはできません。アカウントを持っていない場合、アカウントは自動的に作成され、ランディングページにリダイレクトされます。また、ユーザーはプライバシー設定(スケジュールを全員に見せるか、それとも友人だけに見せるか)や主要言語を変更することも可能です。私が今提示した要件に沿って、ユーザージャーニーをもう一度書き直してください。あなた:わかりました! 新しい要件に基づき、ユーザージャーニーを再度更新します。更新されたユーザージャーニー:1. ユーザーはまずランディングページに飛ぶと、アプリについての簡単な紹介と、ページの中央にある2つのボタンを見ることができます。「Googleでサインイン」と「Appleでサインイン」です。2. GoogleまたはAppleのアカウントでサインインに成功すると、アカウントが自動的に作成され、ホームページへリダイレクトされます。3. アカウントを持っていない場合は、自動的にアカウントが作成され、トップページにリダイレクトされます。4. トップページでは、2つのタブが表示されます。「マイ・スケジュール」と「フィード」の2つのタブが表示されます。5. 「マイスケジュール」タブでは、自分のスケジュールを表計算ソフトのように表示することができます。各セルは時間帯を表し、その時間帯が埋まっている場合は色が付きます。セルをタップすることで、占有と空きの状態を切り替えることができます。また、長押しスワイプで連続した時間帯を占有・空白にしたり、長押しでタイトル、場所、重要度などの詳細情報をイベントに追加することができます。6. 「フィード」タブでは、友達のスケジュールやフォローしているユーザーのスケジュールを見ることができます。また、このタブはスプレッドシートのように表示され、各行にはユーザーのスケジュールが表示され、ヘッダー列には時間帯が表示されます。縦方向にスクロールして表示する時間帯を変更したり、横方向にスクロールしてユーザーのスケジュールを切り替えたりすることができます。ヘッダー列にはユーザーが表示され、スクロールしても上部と左側に配置される。ユーザーが特定の時間帯をタップすると、その時間帯に空いているユーザーのリストが表示されます。ヘッダー列のユーザーセルをタップすると、そのユーザーのプロフィールページに移動します。7. ユーザーの詳細ページでは、名前、フォロー&フォロワー、プロフィール写真、自己紹介など、ユーザーの詳細なプロフィール情報を見ることができます。ユーザーはこのページから、そのユーザーをフォローしたりブロックしたりすることができます。また、自分のプロフィールページには、「編集」ボタンが表示されます。このボタンをクリックすると、新しいページが表示され、自分のプロフィール情報を編集することができます。ページ下部には、自分のスケジュールと相手のスケジュールを確認することができます。8. トップページ上部のアプリバーには、いくつかのボタンがあります。「設定」、「通知」、「プロフィール」、「友達追加」です。「設定」ボタンをクリックすると、ユーザーは設定ページに移動し、プライバシー設定や主要言語の変更、アカウントの削除を行うことができます。「通知」ボタンを押すと、ユーザーへの友達申請やシグナルがモーダルで表示されます。それぞれの通知項目をクリックすると、そのユーザーのプロフィールページが表示されます。「プロフィール」ボタンをクリックすると、自分のプロフィールページが表示されます。友だち追加」ボタンは検索フォームとして機能し、IDやキーワードで他のユーザーを検索することができます。かなり見やすいユーザージャーニーができました。このユーザージャーニーは、この後もプロンプトに何度も挿入するのでどこかに保存しておきましょう。
次はディレクトリ構造を決定していきます。これを決めておくと、あとでコーディングするときに読みやすく洗練されたコードになります。本当です。
完璧です。更新されたユーザー・ジャーニーに忠実に、超熟練プログラマーであるあなたは、このアプリプロジェクトのディレクトリ構造を示してください。そして、各ファイルで何がコーディングされているのかを具体的に説明しなさい。もう一度、ユーザージャーニーを見せるので参考にしてください。ユーザージャーニー:(上の回答の丸々コピペ)了解です、これがこのアプリプロジェクトのディレクトリ構造です。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、UserDetail、Profile、Settings、Notifications、Searchなど、アプリのメイン画面が含まれています。widgets/フォルダには、ScheduleCell、ScheduleHeader、EventTile、UserTile、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が指示の内容を理解するために回答させています。あなたもしつこいくらい確認してあげましょう。指差し確認「ヨシ!」
ついにプログラミングが始まります……と言いたいところですが、実装計画を最初に作りましょう。ChatGPTには段階を踏ませよ、です。
素晴らしい! 超熟練プログラマーのあなたは、この指示の最後にもう一度紹介するディレクトリ構造に厳密に従って、実装全体の流れを示します。各ステップでどのコンポーネントを実装しているかも合わせて書いてください。ディレクトリ構造:(上の回答の一部分をコピペ)あなた:もちろんいいですよ。ディレクトリ構造に従って実装のワークフローを示します。models/user.dartに、ユーザーのプロフィール情報(名前、プロフィール写真、フォロワー、フォロー、自己紹介など)を表すUserクラスを実装する。models/event.dartに、ユーザーのスケジュールにおけるイベントを表すEventクラスを実装する(開始時間、終了時間、タイトル、場所、重要度を含む)。ユーザーに送信される通知を表すNotificationクラスをmodels/notification.dartに実装し、そのタイプ(友達リクエスト、シグナルなど)、送信者を含む。services/authentication.dartにAuthenticationクラスを実装し、GoogleやAppleのサインインによるFirebaseでのユーザ認証を処理する。services/firestore.dartにFirestoreクラスを実装し、FirebaseFirestoreとの通信を行い、ユーザデータやイベントデータの取得・更新を行います。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で認証状態の変更とルーティングを処理することも忘れないでください。ChatGPTが作ってくれた実装計画に沿って実装していきます。ですが、ただ「実装計画に沿ってクラス〇〇を実装しろ」と言ってもうまくいきません。そもそも実装計画やこれまで決めてきたユーザージャーニーを忘れている場合もあるので。そこで、最初はやはり復唱させます。
screens/landing_page.dartのlanding_page.dartウィジェットの実装を例に取ります。他のコンポーネントも基本は同じです。
あなたはLandingPageウィジェットを実装します。ユーザージャーニーの関連する部分を読んで、このウィジェットがどのように機能するか教えてください。ユーザージャーニー:ユーザーは、アプリについての簡単な紹介と、ページの中央にある2つのボタンを見ることができるランディングページに着陸します。「Googleでサインイン」と「Appleでサインイン」です。あなた:LandingPageウィジェットは、ユーザーがアプリにアクセスする際の入口となります。アプリの簡単な紹介文と、GoogleまたはAppleでサインインするための2つのボタンが表示されます。ユーザーが「Sign in with Google」ボタンをタップすると、アプリはGoogleサインインフローを起動し、ユーザーを認証する必要があります。同様に、ユーザーが「Sign in with Apple」ボタンをタップすると、アプリはAppleサインインフローを開始してユーザーを認証する必要があります。まとめると、LandingPageウィジェットは以下のような役割を担っています。1. アプリの簡単な紹介を表示する。2. ユーザーがGoogleまたはAppleでサインインできるように、2つのボタンを持つこと。対応するボタンがタップされると、適切なサインインフローを開始します。問題が無ければ続けてプロンプトを入力します。何か誤解があるようなら、必要に応じて情報を追加して指示しましょう。そこまで深刻な誤解でなければ、回答を再生成してもいいでしょう。ただ経験上再生成では回答の質はむしろ劣化します。数回繰り返しても変化がなければ、思い切ってプロンプトを変えてください。
素晴らしい。このウィジェットをどのように実装するか、ステップ・バイ・ステップで手順を教えてください。同時にそれぞれのステップで変更したコードを示してください。あなた:もちろんです。ここでは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ウィジェットがあなたのアプリに実装されました。これをそのままコピペして実装完了、とは残念ながらなりません。大抵どこかエラーを吐いたり表示がバグる部分があるので直していきます。できそうなら、プロンプトを修正してChatGPTに引き続き実装させるのもいいでしょう。とはいえ、そのうち英語の文章を考えるのが面倒くさくなって、直接実装しにいくことも多いですが。
実装し終わったら、ちゃんとChatGPTに報告します。
自分でscreens/landing_page.dartのLandingPageウィジェットを実装しました。コードを下に示します。LandingPageウィジェット:(自分で書いたコード)素晴らしい! うまく実装されているように見えますね。この作業を繰り返します。必要に応じて新たにファイルを作ってもいいでしょう。そのたびにどんなクラスを追加したのか説明すれば、ちゃんと実装手順を考えてくれます。試しに、最初のディレクトリ構造にはなかったwidgets/add_friend.dartで、AddFriendウィジェットを実装させてみましょう。
widgets/add_friend.dartにAddFriendウィジェットを実装したいです。ランディングページのアプリバーから飛ぶことができ、ユーザーをID、電話番号、キーワードで検索して友達追加することができます。このウィジェットがどう機能するか教えてください。あなた:もちろんです。AddFriendウィジェットは、ユーザーがユーザーID、電話番号、キーワードなど様々な方法で友達を検索し、自分のスケジュールに追加することができるウィジェットです。このウィジェットを実装するには、まず、テキスト入力や検索をトリガーするボタンなど、検索機能のUIを作成する必要があります。ユーザーが検索クエリを入力すると、Firebase Cloud Firestoreを使って関連するユーザー情報を検索することができます。検索結果が一致した場合、そのユーザーの情報を表示し、友人として追加するオプションを提供することができます。ユーザーが友達追加を選択すると、Firestoreのドキュメントを更新して、新しい友達の情報を含めることができます。さらに、ユーザー自身のスケジュールへのリンクを友人と共有するオプションを提供することも可能で、その場合、各ユーザーに固有のリンクを生成してFirestoreに保存する必要があります。この場合、ユーザーごとにユニークなリンクを生成し、Firestoreに保存する必要があります。これにより、ユーザーは友人にリンクを手動で送信することなく、簡単に自分のスケジュールを共有することができます。これらのステップについて、より詳細な情報が必要な場合は教えてください。ファンタスティック! あなたが新しくコーディングまたは修正したコードをそのつど提供しながら、AddFriendウィジェットを実装してください。あなた:あとは同じです。頑張って仕上げましょう。
最後にAppStoreに公開しましょう。どんなにいいアプリを作っても誰も使ってくれなければ意味はないので。
さて、AppStoreの提出に最低限必要なのは紹介文、プライバシーポリシー、アイコン、スクリーンショットの4つです。まず、一番簡単な紹介文とプライバシーポリシーから仕上げちゃいましょう。
いつものようにChatGPTに聞きます。
あなたは売れっ子コピーライターです。私はこのアプリをAppStoreに提出したいです。このアプリの説明文を書いてください。あなた:究極のスケジュール管理ツール、Frienduleを紹介します。Frienduleを使えば、友人とスケジュールを共有することがこれまでになく簡単になります。このアプリは、シンプルで直感的なユーザーインターフェースで設計されており、週や月のスケジュールをスワイプして、素早くイベントの追加や編集を行うことが可能です。しかし、それだけではありません。Frienduleは、友人に尋ねることなく、友人とのスケジュールを見たり、比較したりすることもできます。ID、電話番号、キーワードで相手のプロフィールを検索するだけで、その人のスケジュールが目の前に現れます。彼らのスケジュールは目の前にあり、簡単に識別できるように色分けされています。Frienduleがあれば、もう大事なイベントを見逃すことはありません。今日からアプリをダウンロードして、簡単にスケジュールを共有しましょう。いいですねえ。次はプライバシーポリシーです。本当は弁護士に相談したほうがいいのですが、本格的な法律文書はアプリがたくさんの人にダウンロードされるようになったら考えることにします。
あなたは経験豊富な弁護士です。このアプリのプライバシーポリシーを書いてください。あなた:Friendule - プライバシーポリシーFrienduleでは、お客様のプライバシーを大切に考えています。このプライバシーポリシーでは、当社が収集する情報の種類とその使用方法、共有方法、保護について説明します。当社が収集する情報Frienduleでは、お客様のお名前、メールアドレス、電話番号、その他お客様が共有する個人情報などの情報を収集します。また、お客様のスケジュールデータや他のユーザーとのやり取りなど、お客様のアプリの使用に関するデータも収集します。このデータは、アプリの特徴や機能を改善するために使用されます。情報の使用Frienduleアプリの提供や改善、ユーザー体験のパーソナライズ、アップデートや新機能に関する連絡のために収集した情報を使用します。また、法律、セキュリティ、運営上の目的でお客様の情報を使用することもあります。情報の共有当社は、アプリの機能や特徴を提供するために当社を支援する信頼できる第三者ベンダーとお客様の情報を共有することがあります。また、お客様が友人や家族とスケジュールを共有する場合など、お客様の指示により、他のユーザーとお客様の情報を共有することもあります。当社は、お客様の個人情報を第三者のマーケティング担当者や広告主に販売することは決してありません。データの保持当社は、Frienduleアプリおよび関連サービスを提供するために必要な期間、あなたの情報を保持します。また、法律上、セキュリティ上、または運営上の目的でお客様の情報を保持することもあります。セキュリティ当社は、お客様の個人情報のセキュリティを重視し、不正なアクセス、使用、開示から個人情報を保護するために業界標準の方法を採用しています。プライバシーポリシーの更新当社は、本プライバシーポリシーを随時更新することがあります。重要な変更を行う場合は、電子メールまたはアプリを通じてお客様に通知します。連絡先本プライバシーポリシーまたはFrienduleアプリに関するご質問やご不明な点がある場合は、下記までご連絡ください。悪くないんじゃないでしょうか。
次はアイコンとスクリーンショットを作ります。ここはもうセンスに頼るしかないですが、Canvaのテンプレートを使えば相当見栄えよくなります。
https://www.canva.com/
お疲れさまでした! まだるっこしい審査こそありますが、ここまできたらさすがに一息ついても大丈夫です。本当にお疲れさまでした。もしこの記事を見てアプリを作ってくれた人がいたら、あなたのアプリをぜひ見せてください。
ではでは、ここまで読んでくれて本当にありがとうございます!
と、ここで物足りないあなたは、最近書いた記事も読んでみてください! とびっきり面白いですよ!
https://zenn.dev/niwatoro/articles/180f6185c382bb
https://zenn.dev/niwatoro/articles/296cf12dd8cd62
バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。