見出し画像

CodexとClaude Codeで初のiOSアプリを公開——コードの外側まで作り込んだら、iOS開発ハーネスになった

2026年8月23日、iOSゲーム「星環庭園」をリリースしました。

指で円を描くと宇宙塵が集まり、惑星や恒星系が育っていく、横画面の宇宙シミュレーションゲームです。条件がそろえば、ブラックホールや銀河も生まれます。

星環庭園をApp Storeで見る

初めてのiOS個人開発でした。

アプリを作るのと同じくらい試したかったのが、CodexやClaude Codeへ同じ注意を繰り返さなくても、開発、テスト、公開準備が進む環境づくりでした。

Apple待ちだと思っていたら、必要書類の案内メールを見落とした「私待ち」でした。そんな詰まりを、その場の修正で終わらせず、次は少し楽に通れる仕組みへ変えていった記録です。

ゲームの設計をリポジトリへ入れた7月19日から、App Storeで公開した8月23日まで約5週間。その少し前に開発基盤を作り始めた期間を含めると、約6週間の記録です。

出遅れた気がして、まずCodexを触り始めた

昨年度は仕事で大きなプロジェクトに関わり、AIエージェントを腰を据えて試せない時期が続きました。周囲ではAIを使った開発の話が増えている。自分は少し出遅れているかもしれない。そんな気持ちもあり、2026年5月ごろからCodexを使い始めました。

5月は、小さな試作を重ねながら使い方を探っていた時期です。今回の開発基盤と星環庭園へ本格的に着手したのは7月でした。

GitHubとつなぎ、WebページやiOSアプリを試作するうちに、気になったことがあります。

AIはかなり広い範囲を進めてくれます。ただし、同じ目的を伝えても、毎回まったく同じ手順を選ぶとは限りません。

人が横で見ながら、「mainへ直接書かないで」「勝手にマージしないで」「Appleへ送る前に止まって」と何度も伝え続けるのは、たぶん長続きしません。

それなら、AIが動いてよい範囲と、人が判断する場所を、先に仕組みとして決めておけばよいのではないか。

この考えを、7月から実際の開発環境へ落としていきました。

科学館で見た惑星づくりが、星環庭園の種になった

題材に選んだのはゲームです。もともとゲーム開発に興味があり、少し前に訪れた科学館で、惑星を作る展示で楽しそうに遊ぶ子どもたちを見ました。

子どものころに感じた宇宙へのわくわくを、大人も気軽に触れる形にできないか。

そこから、画面を指で円状になぞると塵が集まり、天体が育っていく遊びを考えました。完成形を当てるゲームというより、自分で作った恒星系を眺め、思いどおりにならなければ残った天体と塵からまた育てるゲームです。

最初の公開版では、アカウント、広告、トラッキング、アプリ内課金を入れませんでした。遊びの核を小さく保ち、初めてのApp Store公開で何が必要になるのかを、一通り経験することを優先しました。

同じ注意を二度言わない仕組みから始めた

アプリ本体より少し先に作り始めたのが、全体のルールを置く場所です。私はこれをGovernance Hubと呼んでいます。

変更は専用のブランチで進め、自動チェックを通す。AIがPull Request(変更内容を人に確認してもらうための提案)を準備しても、マージは人が行う。Appleなど外部サービスへ何かを書き込むときも、確認なしでは先へ進まない。最初に決めたのは、このあたりでした。

こうした約束を会話だけに置かず、設定ファイルや自動チェックへ移しました。AIの「守りました」より、実際の差分と検査結果を見たかったからです。

最初から完成形が見えていたわけではありません。同じ修正や注意を二度頼んだら、「次から自動で守れる形にできないか」と考える。その繰り返しで増えていきました。

規約と問い合わせ先を作ったら、3+N構成になった

App Storeへ公開するには、アプリ本体のほかに、プライバシーポリシーやサポートページを利用者が開けるURLとして用意する必要があります。

ひな型をコピーして終わりにはしませんでした。Appleや公的機関の資料を確認し、書籍も読みながら自分で勉強しました。そのうえで、星環庭園にはないアカウントや広告、課金まで書かないよう、実装と文章を照合しました。

公開先にはCloudflare Pagesを使いました。一つの共通リポジトリ内に、アプリごとのページを分けて置いています。

問い合わせはGoogle Formsで受け、回答をGoogle Sheetsへ集めます。フォームやApps Scriptも、全アプリ分を一つの共通リポジトリで管理しました。最初の権限承認など、Googleの画面で行う操作は人が担当します。

こうして、全アプリが共有する三つのリポジトリと、アプリごとの独立したリポジトリに分かれました。

  • AIのルール、台帳、検証を管理するGovernance Hub

  • プライバシーポリシー、利用規約、サポートページを公開する共通Web

  • Google Forms、Sheets、Apps Scriptを管理する共通の問い合わせ基盤

  • アプリごとに一つずつ増えるiOSリポジトリ

共有する3リポジトリに、アプリ数Nのリポジトリを足すので「3+N」です。共通部分は一か所で直し、製品コードとリリース履歴はアプリごとに分けます。

3+Nに分けたら、次は「どこまで進んだ?」で迷った

3+Nに分けると、今度は「どこまで終わったか」が見えにくくなりました。会話の履歴をさかのぼらないと、次に触るリポジトリすら分からないことがあります。

そこで、作業中の変更、マージ済みのPull Request、テストや実機確認の結果を、一つの進行記録にまとめました。途中で止まっても、確認できた地点へ戻れます。

コードを並行して直すときは、作業フォルダを分けられるGitのworktreeを使います。同じリポジトリでも、アプリの実装と開発基盤の改善が混ざりません。

ただし、何でも並行にはしません。Appleへの書き込みや同じ進行状態の更新は、一つずつ順番に実行します。

Pull Requestのマージ、実機での確認、規約やプライバシーに関する判断、App Reviewへの提出とリリース。ここは人が画面を見て決めます。

AIには、機械だけで確かめられるところを次の判断地点まで進めてもらう。人が決める場所まで来たら、必要な材料をそろえて止まってもらう。この分け方は、あとでApp Store申請を作り込むときにも、そのまま使えました。

Apple待ちだと思っていたら、私待ちだった

開発環境が整っても、Apple Developer Programの手続きは別です。

登録後、審査が進むのをしばらく待っていました。初めてなので、時間がかかるものだと思っていたのです。

一週間ほどしてWeb版の受信箱を開き直すと、本人確認書類をアップロードする案内が残っていました。普段のメールアプリでは見落としていたのです。

Apple待ちではありません。私待ちでした。

書類を提出すると手続きが進み、開発者登録は無事に完了しました。次の自分に残すメモは、「Apple待ちだと思ったら、登録メールをWeb版でも見直す」です。

開発者登録が終わり、次はビルドをTestFlightへ届ける準備に進みました。

GitHub Actionsの利用枠から、手元のMacへ移った

iOSアプリをTestFlightへ届けるには、MacとXcodeでビルドし、署名した成果物をAppleへアップロードします。

当初は、GitHub Actionsが用意するmacOS環境を使っていました。自分のMacを起動しておく必要がなく、毎回きれいな環境で動くので便利です。

ところが、ある日、処理がコードを一行も実行せずに止まりました。テストの失敗ではありません。プライベートリポジトリで使うGitHub-hosted Actionsの利用枠と、設定していた予算上限に達していました。

そこで、手元のMacをGitHub Actionsの実行先にするセルフホストRunnerへ移しました。OSに依存しない検査はGitHub側へ残し、Xcode、署名、TestFlightなどMacが必要な仕事だけを担当させています。

次に悩んだのは、証明書やApp Store Connectの接続情報をどこへ置くかでした。アプリごとに同じ秘密情報を複製すると、登録も更新も増えます。

現在は秘密情報を配信用Mac側へ集約し、AI、Git、通常のログには値を出しません。同じ情報をアプリごとに登録する作業もなくなりました。

セルフホストに移した後も、片方のRunnerは動くのに、もう片方はGitHub上でOfflineになることがありました。ログインし直し、Macを再起動して、アプリごとに異なるフォルダ構成や起動方法を確認しました。手元のMacを使う以上、電源やログイン状態まで運用の一部になります。

ルールを増やしすぎると、今度はAIが迷った

Mac側の実行環境が落ち着くと、次に詰まったのは、AIへ読ませるルールの量でした。問題を仕組みに変えるたび、当然ながらルールも増えていきます。

禁止事項、アプリ開発、デザイン、TestFlight、規約、公開ページ、問い合わせ。すべてを毎回読ませると、AIが一度に扱える情報量、いわゆるコンテキストを圧迫します。目の前の作業と関係のない説明に、判断が引っ張られることもありました。

そこで、常に読むのは短い停止ルールだけにしました。詳しい手順は、App Storeの作業ならApp Store用、規約なら規約用というように、必要なときだけ段階的に読みます。

自分だけで原因を絞れないときは、Claude CodeやChatGPTの上位モデルにも相談できるようにしました。秘密情報を除いた必要最小限の抜粋だけを送り、返ってきた助言は手元のコードとテスト、公式資料で確かめます。

自動化を増やすことと同じくらい、AIに何を読ませないか、外部のAIへ何を送らないかが重要でした。

App Store Connectは、設定画面が一か所ではなかった

App Store Connectへアプリを登録したら、説明文とスクリーンショットを入れれば終わる。最初は、そのくらいに考えていました。

新しいアプリを登録する画面だけでも、入力項目はかなりあります。そこでAppleの公式資料を参照しながら、CodexがWeb画面を操作して入力できるようにしました。最後の確認と登録は私が行い、その後の情報取得や説明文の準備には公開APIを使います。

実際には、年齢区分や価格・配信地域だけでは終わりません。データ収集や暗号化に関する申告、対応端末、App Review用の情報まで、設定画面がいくつにも分かれています。

画面を開いては、「これは必要?」「日本だけならどちら?」「空欄でいい?」とCodexへ聞きました。同じ確認を次のアプリでも繰り返す未来が、かなり具体的に見えます。

APIで読める項目はAppleの現在値を取得し、希望値との差を表示する。APIから確認できない項目には、App Store Connectでどのページを開き、何を設定するかを書く。

これらを大まかなページごとに並べた「最終提出チェックシート」を作りました。説明文や審査メモの下書き、スクリーンショット更新などはAIが準備できます。連絡先、申告内容の最終判断、ビルド選択、審査への追加、提出、リリースは人が画面で確認します。

スクリーンショットは、成功した分を消したくなかった

App Store用のスクリーンショットを連続で更新したとき、途中で処理が止まりました。

一部はAppleへ届き、残りは未完了。ここで最初からやり直すと、成功済みの画像まで消したり、重複して送ったりする恐れがあります。

更新前の画像をローカルへ退避し、Apple側の現在値を読み直す。すでに目的の画像がそろっていれば再利用し、不足分だけを送る。結果が分からない操作はすぐ再送せず、まず読み取りで確認する。

途中まで成功した状態を記録し、安全に続きから再開する仕組みを作りました。システム設計の言葉でいえば、「擬似トランザクション」に近い考え方です。ただ、やりたいことは単純でした。

通った画像は、そのまま使いたい。

初回審査では、7項目の回答を求められた

星環庭園の初回App Reviewでは、Appleから追加情報を求められました。

求められたのは、次の7項目です。

  1. 実機で撮影した、起動から主要機能までの操作動画

  2. 提出前にテストした端末とOS

  3. アプリの機能、対象者、解決する課題、提供する価値

  4. 初期設定と主要機能への入り方。必要ならログイン情報やサンプルファイル

  5. 中心機能で利用する外部サービスやツール

  6. 地域による機能や内容の違い。または、全地域で同じであること

  7. 規制業種や保護された第三者素材への該当有無。該当する場合は権限を示す資料

これは、すべてのアプリで一律に「7項目が必須」という意味ではありません。今回、Guideline 2.1の追加情報としてAppleから具体的に求められた内容です。

星環庭園にはログインも課金もありません。それでも、ないものは「該当なし」と書かなければ審査側には伝わりません。

審査メモには、誰が遊ぶゲームなのか、円を描くと何が起きるのかを書きました。外部サービスへ接続しないこと、進行状況は端末内だけに保存すること、特別な設定やサンプルファイルは不要なことも、App Store ConnectのReview Notesへ明記しています。

App Review用の実機動画は、MP4のままでは添付できなかった

7項目のうち、最初に求められたのが、実機でアプリの流れを見せる操作動画でした。iPhone 17、iOS 26.6、Build 80で、起動から通常の遊び方までを撮影。iPhoneの写真アプリから取り出したMP4をApp Reviewへ添付したところ、しばらく「処理中」と表示された後、エラーになりました。

MP4なのに、MP4として素直に通ってくれません。

元動画を残し、映像をH.264、音声をAACへ変換したコピーを作ると、今回は添付できました。これは今回の回復策であり、Appleがすべての審査動画へ一律に求める形式だとは考えていません。

動画と回答、Review Notesをそろえて再申請。その後、承認されました。

最初の提出から再申請後の承認までは、このアプリでは4日でした。これは星環庭園での一例であり、機能構成や審査状況によって期間は変わります。

この経験から、次回用の初回提出テンプレートに7つの観点を加えました。

後から振り返ると、これが開発ハーネスだった

ここまで作ってきたのは、AIが動ける範囲を決め、作業を分け、失敗しても途中から再開できる外枠でした。ルール、自動チェック、worktree、進行記録、人の承認。この外枠を「開発ハーネス」と呼びます。

私にとってのAI駆動開発は、AIにコードを多く書かせることだけではありませんでした。細かく指示しなくても進める場所と、人が判断するまで止まる場所を、開発の流れとして組み立てていく。その部分に、思っていた以上の時間を使いました。

エラーが出ると面倒なのは変わりません。ただ、直した内容が次のアプリにも残るので、同じ場所で繰り返し困ることは少しずつ減りました。

これから初めてiOSアプリを出す方へ

今回公開したのは、アカウントも課金もサーバー通信もない、小さなゲームです。それでも、コードの外側には想像以上に多くの作業がありました。

今回の経験から、初回申請の前に確認しておくとよいと感じたのは次の点です。

  • アプリ本体だけでなく、プライバシーポリシー、サポートページ、問い合わせ先の公開方法を早めに決める

  • Apple Developerの案内メールと、App Store Connectの契約状態を見落とさない

  • 少なくとも初回登録はApple公式Webで内容を確認する。今回はCodexのブラウザ操作で入力を補助した

  • GitHub-hosted macOSを多く使う場合は、Actionsの利用量と予算上限を確認する

  • TestFlightで、提出するものと同じビルドを実機確認する

  • App Review Notesには、審査担当者が迷う設定、操作手順、外部サービス、地域差、該当しない機能まで具体的に書く

  • 独特なジェスチャーや機器依存がある場合は、起動から主要操作までの実機動画を先に用意する

  • 最後のビルド選択、申告、提出、リリースは、人が画面で読み直す

この仕組みがあっても、次のアプリを短期間で出せるとはまだ言えません。アカウント、通信、課金、ユーザー投稿などが加われば、必要な設計と確認も増えます。

ただ、どの画面を確認するのか、どこまでAIへ任せるのか、失敗したらどこから再開するのかは、以前よりずっと明確になりました。

詳しい仕組みは、今後の記事で少しずつ

今後は、今回触れきれなかった仕組みをテーマごとに書く予定です。3+Nとworktree、Mac Runnerでの秘密情報の扱い、AIへ毎回読ませる情報を減らした方法、App Store Connect更新の回復処理などが候補です。

公開版はバージョン0.1.0、Build 80で、日本のApp Storeから入手できます。

星環庭園をApp Storeで見る

指で円を描くところから始まる小さな宇宙を、よければ触ってみてください。

次回、開発ハーネスの中身について

続編の記事では前回は詳しく触れなかった開発環境の設計をまとめました。
3+Nのリポジトリ構成、人の承認を残した理由、Macの役割分離、App Store Connect更新の回復処理などを、実際に詰まった場面と一緒に紹介しています。

CodexとClaude Codeで作ったiOS開発ハーネスの設計書——3+N構成からApp Store公開まで

参考にした公式情報

※ Apple、GitHub、App Store Connectの画面や仕様は変わることがあります。この記事は2026年8月時点の公式情報と、星環庭園で実際に経験した内容をもとにしています。

いいなと思ったら応援しよう!