Swift を一行も書かずに iOS アプリを公開した — 作るのに1週間、公開までに1か月
2026年7月18日、土曜日。家族でスケートに行って、帰りが遅くなった。今から夕飯を作るのも面倒だということで、そのままラーメン屋に寄った。
その車の中で、なんとなく思いついたアプリがあった。店に入って、注文して、出てくるまでの間。手持ち無沙汰でスマホを開いて、Claude にこう打った。
次のようなアプリを作りたい。
・写真を撮影、または選択 ・内容をできる限り絵文字に変換 ・保存、高画質は有料
これをクライアントで完結させたいけど現実的かな
命令ですらない。作れるかどうかの相談だった。
返ってきたのは「方式が2つある」という答えだった。ひとつは色を見て、近い色の絵文字に置き換える方式。もうひとつは写真に何が写っているかを認識して「犬だから🐶」と置き換える方式。前者は端末の中だけで軽く動く。後者はオンデバイスの機械学習が要って、アプリのサイズも実装の難易度も跳ね上がる。
私が思い描いていたのは後者だった。 実際に作ってもみた。だが精度が出ず、何より面白くなかった。いま App Store にあるのは前者のほうで、最初の相談で「重いほう」と言われた道は、試したうえで捨てている。
最初のコミットが入ったのは2日後の月曜、7月20日。そして8月20日に App Store で公開された。最初のコミットから、ちょうど1か月。
ただ、この1か月の内訳がこの記事の本題になる。アプリが動いて審査に出せる状態になったのは、着手から6日後の7月26日。そこからの25日は、出しては取り下げ、却下されては出し直し、を繰り返していた。
そして私は iOS 開発をやったことがない。Swift は一行も書いていないし、今も読めない。
なので、この記事では経緯だけでなく何をどう指示したかも実際の履歴から出す。読んで「これなら自分にもできそう」と思ってもらえたら、この記事は成功です。
写真を、絵文字で埋めるアプリ
Emotile。写真を絵文字のモザイクに変換する iOS アプリ。無料(アプリ内課金あり)、iOS 17以上。45言語に対応している。
App Store: https://apps.apple.com/app/id6794346554
サイト: https://emotile.app
やっていることは、この2枚を並べれば早い。


写真を選ぶと、色の近い絵文字を敷き詰めて1枚の絵にする。細かさを変えられるので、遠目で見ると写真、近づくと絵文字という状態を作れる。上の画像も、拡大すると一つひとつが絵文字になっているのが見える。
「かわいい」「たべもの」「顔と感情」のようにテーマごとの絵文字グループがあり、同じ写真でも選ぶグループで雰囲気が変わる。

おまけとして、作品の中に一度だけ「ラッキー絵文字」が混ざる。誰かに見せて一緒に探すためのもので、ウォーリーを探せに近い。
写真アプリの共有シートからも直接変換できる(アプリ本体とは別に、共有シート用の拡張機能を用意してある)。処理はすべて端末の中で完結していて、写真は外に送らない。
有料オプションは買い切りで、文字モード(漢字・ABC・ドット・古代文字・くさび形に変換)、カラーフィルター、高画質書き出し、フレームを外す、などがある。
iOS 開発はやったことがない
普段は業務で Kubernetes まわりを扱っている。仕事でも AI は使う。プライベートでも AI に Web アプリをいくつか作らせていた。その延長で、次はスマホアプリを作ってみようと思った。動機はそれだけで、アプリで何かを成し遂げたかったわけではない。
iOS の作法は知らない。Xcode もほとんど開いていない。
使った道具は7つ
利用したツールは以下の通り。
Mac mini(2023・M2 Pro・10コア・メモリ16GB) — 母艦。ビルドもテストもここで回す
VS Code — 画面として見ていたのは、ほぼこれだけ
Claude Code — 開発。VS Code の拡張機能と、iPhone アプリの両方から使う
Xcode — ビルドとテスト。GUI はほとんど触っていない(xcodebuild を叩くだけ)
SwiftLint — Swift の書き方の検査
iPhone 実機 — 動作確認。コマンド1本でインストールできる
Cloudflare Pages — 紹介サイトの置き場(無料枠)
普段いた画面は VS Code だった。Claude Code を VS Code の拡張機能として動かして、上がってくる差分を眺めるのが私の仕事。Swift は読めないので中身の是非は分からないが、どこが、どれくらい変わったかは見える。想定より広い範囲が書き換わっていたら、そこで止めて聞く。その程度のチェックはしていた。
そして、Xcode を開かなくていい形に倒したことが、この作り方では決定的だった。 GUI の操作は AI に頼めない。画面のどこを押したかは言葉にしないと伝わらないし、私はそもそもどこを押せばいいか知らない。
逆に、ビルドもテストも実機インストールもストア画像の生成も審査提出も全部コマンドで呼べるなら、AI がそのまま実行できる。早い段階で「Xcode の画面でやること」を減らす方向に倒したのはそのためで、結果として、私が Xcode を開いた回数は数えるほどしかない。
使う道具は最後まで変わらなかったが、その裏で動いていたモデルのほうは変わっている。 これも履歴に残っていたので数えた。AI 側のターン数(ツールの実行を含む)の内訳はこうなる。
Sonnet 5 — 22,861ターン(52.8%)
Opus 4.8 — 7,379ターン(17.0%)
Opus 5 — 6,725ターン(15.5%)
Fable 5 — 6,322ターン(14.6%)
合計 43,287ターン
打った指示は全部で1,349回(内訳は後述)。それに対して、AI 側は43,287ターン動いている。
指示1回あたり、平均32ターン。 ファイルを読む、書く、テストを流す、失敗を見て直す — その全部が1回の「お願いします」の内側にある。
意識してモデルを選び分けてはいない。期間中に既定が変わったり、使用量に応じて切り替わったりした結果がこの比率で、どれを使うかで悩んだ記憶は無い。7月は Opus と Fable、8月前半は Sonnet、後半はまた Opus が中心になっている。
正直に言うと、スマホからだと、いま何のモデルで動いているのかが確認しづらかった。 気づかないまま意図していないモデルで進めていたことが何度かある。今はテキストボックスの下にモデルが表示されるようになったので、意図せず違うモデルを使うことは減った。
これも結局、このあと何度も出てくることになる話と同じ形をしている。今どうなっているかが画面から見えないと、人はそのまま進んでしまう。
指示は1,349回、中央値45文字
どう指示していたかを、実際の履歴から出す。以下はすべて私が実際に打ったもの。読みやすいように誤字だけ直したが、言い回しと長さはいじっていない。
まず全体像。7/19 から 8/20 までで、私が打った指示は 1,349回。長さの中央値は45文字。半分以上が50文字以下だった。
つまり、丁寧な仕様書を先に書いて渡す、という進め方はしていない。変更ごとの設計は先に書かせたが、アプリ全体の仕様にあたる文書は実装したあとに、現状を整理するために書き起こしたもので、順番はむしろ逆だった。
まず相談する
とはいえ、記録の始まりは相談ですらなかった。Claude Code に対する記録上いちばん古い指示は、これだ。
これ xcode でビルドできるようにして。
ラーメン屋での相談の翌日。チャットの Claude に書かせた Swift のコードを、まだ何も分かっていない状態のまま、とりあえず動く形にするところから始めている。
アプリ名も、自分ひとりでは決めていない。
ついでにこのアプリを最終的には App Store で公開したいのですが、アプリ名は EmojiPhoto でよさそうですかね?
ここから最初のコミットまで、名前は4回変わっている。しかも全部、同じ日のうちに。
01:12 EmojiPhoto — 最初の案
01:15 Emojaic —「日本語だとエモザイクと読めそう。英語圏の人も読めそう?」
01:22 Emosaic に決定
15:03 やっぱり Emojaic
15:24 「やっぱり Emotile にしようかな」
16:30 Emotile で最初のコミット
最終的な名前が決まったのは、最初のコミットの1時間前だった。
英語圏の人に読めるか、日本語で違う意味に取られないか。この手の判断は自分では確信が持てない。そのまま聞いた。正解が無いのに、決めないと進まない。こういうときこそ、相談相手がいると速い。
相談 → 設計 → 実装、あとは「進めて」
いきなり「作って」とは言わない。まず相談して、方針が決まったら設計を書かせて、それから実装させる。有料プランの比較画面を作っていたとき、紹介サイト側にも同じものが要るかを相談した流れで。
とりあえずはwebにはいらないかな。将来的に必要になったら再検討。
それを踏まえて設計図お願いします
実装お願いします。
大きめのものは、設計をそのままファイルに残してもらった。あとで「なぜこうしたか」を AI 自身が読み返せるので、日をまたいでも話が巻き戻らない。1か月で設計・計画・裁定の文書が70本たまったのは、この頼み方をしていたから。
計画が文書に残っていると、続きは勝手に進む。 42回は「進めてください」「続きお願いします」「再開」だけだった。
分からないことは、そのまま聞く
私は iOS の作法を知らない。だから判断を丸ごと投げた。
同じ課金まわりの画面で、上がってきたデザインを見て。
ちょっとこのデザインは良くないと思いました。 Apple の UI パーツの使い方として正しい?
共有先ごとに投稿内容を変えたい、と相談していたとき。説明を読んで引っかかったところで。
呼び出し部分が共通化されてないということですよね。 その状態は適切?
「違和感がある」までは自分で言えるが、「何が正しいか」は言えない。 その切れ目でそのまま聞く。これが一番よく効いた型だった。
やってみて駄目だった、を避けたいときは、制約のほうを先に聞いた。写真アプリの共有シートから使う機能を、アプリ本体と同じ使い勝手にしたかったとき。
基本的にはアプリ単体で開いた時と同じことができるようにしたい。
もし、何かしらの制約があり実現できないことがあれば、リストアップしてください。
「できるところまでやって」ではなく「できないことを先に教えて」。 相手はたいていやろうとしてしまうので、こちらから聞かないと制約は出てこない。
機能を足していると、自分では気づけない粗も溜まる。定期的にこう投げていた。
このアプリ全体の実装をチェックして、改善点、よりよくなる部分を教えてほしい。
Apple が用意している機能で、使うとよりよくなりそうなのに使っていないものがあれば知りたい。
後者は初心者にはかなり効く。「使えるのに使っていない標準機能」は、知らない人間には絶対に出てこない。
感覚のまま言う
見た目の指摘は120回あった。全部こんな調子で、実装の言葉は出てこない。
紹介サイトを多言語にしていたとき、言語の切り替えを見て。
セレクトボックスについて、重ならなくなったけど少し窮屈に感じる。
同じくサイトの、SNS に貼ったときのカード画像を作り直させていたとき。
OG 画像ですが、今のデザインだと何なのか一瞬でわからない。 前はスマホが写っていたので、アプリだということがわかった。
出力画像に入るフレーム(アプリ名が乗る帯)を詰めていたとき。ここは2日かけている。
フレームのデザインを見直したい。 上と下のスペースが違いすぎてバランスが悪い。 なるべくフッター側を調整する方向でバランスをとりたい。
崩してはいけない条件があるときは、それだけ添える。出力を正方形にするのは自分の好みで、そこは動かしたくなかった。
しかし、上と横のスペースの比率が見た目に悪い。 出力の 1:1 を維持したまま改善する方法ってありそう?
気になったことと、外せない条件だけを言う。どう直すかは相手が出す。 この分担が、結局いちばん長く続いた。
バグ報告も同じで、再現手順を整えて書いたことはない。サイトの言語切り替えが2回目から効かなかったとき。
見た目はいい感じ。 ただ、一度変更するとリロードするまで、二度目はクリックしてもタップしても反応しない。
共有シートの画面で、絵文字グループを切り替えていたら落ちたとき。一度直したと言われたあとの再報告。
試しましたがまだ落ちますね。 絵文字グループを二つ順番に連打しました。
「連打したら落ちた」で通る。
気に入らなければ戻すのも、遠慮が要らない。上のフレーム調整の続きで、直させた翌朝に。
いや、やっぱりフレームのバランスは修正前のほうがいいかな。
作り直しのコストが低いので、迷ったら試して、駄目なら戻すほうが速い。ここが手で書いていたときとの一番の違いだと思う。
やめた機能から、一番気に入っている機能が出てきた
途中で「レシピ表示」という機能を作りかけていた。画像を構成する絵文字を、料理のレシピ風に一覧するもの。面白そうだったが、うまくまとまらなかった。
ちょっとレシピ表示はすぐに難しそうなので、一旦凍結で。
その代わり、一つだけの絵文字があったら、それを表示して、見つけたらラッキーがあるかも、くらいなメッセージと共に、フレームに表示したい。あくまでおまけ要素的な感じで、目立ちすぎないように。
これが「ラッキー絵文字」になった。いま一番気に入っている機能は、諦めた機能の代替案として出てきたものだった。
引き際を決めるのも、代わりに何を出すかも、AI からは出てこない。
レビューとマージも言葉で頼む
レビューとマージの依頼は74回。全部この形だった。
良さそうです。コードレビューエージェントでレビューして問題なければマージしてください
実機で確認したいときは「実機インストールして」(70回)、TestFlight に上げたいときは「テストフライトにプッシュして」(15回)。どちらもコマンドを一度作らせておけば、あとは日本語で呼べる。
どれくらい雑に打っていたか
誤字の総数は数えようがないので、雑さの代わりになる指標だけ数えた。
固有名詞や略語を小文字のまま打った(pr github ui apple ios …) — 135回(10%)
句点を打たずに送った短い指示 — 375回(28%)
実際の誤字はこんな調子だった。
「ふぉんと」(フォント)/「せっけい」(設計)/「けいかく」(計画)/「ドキュメン」(ドキュメント)/「用意してている」(用意している)/「わかりずらい」(わかりづらい)/「プライ橋ポリシー」 (プライバシーポリシー)
どれもそのまま通っている。 打ち直しも言い換えもしていない。変換をミスったまま送っても、文脈のほうで拾ってくれる。
この記事でいちばん「これなら自分にもできそう」と思ってほしいのは、たぶんここだ。 正しい言葉で正しく指示する必要は無い。スマホで片手で打った雑な日本語で足りる。
通勤電車と、寝かしつけの時間で作った
まとまった開発時間はほとんど無かった。
通勤電車の中 — スマホの Claude Code アプリ
子供の寝かしつけ中 — 同じくスマホ
早起きできた日の朝 — PC
夜は子供と一緒に寝てしまうので、腰を据えて向き合えるのは朝だけ。それ以外はスマホから指示を出して、あとは動いてもらう形になった。裏を返すと、スマホから指示を出すだけで進む状態を作れたから続いたとも言える。片手で指示が出せないなら、この作り方は成立しなかった。
実際の時間帯の分布はこうだった。
早朝(5〜8時) — 21%
日中(9〜17時) — 42%
夜(18〜22時) — 28%
深夜(23〜4時) — 9%
朝5時台からもう始まっていて、1時間あたりで最も多かったのは19時台。特定の時間にまとめて作業した形跡が無く、一日中こまぎれに散っている。スマホからでも投げられる形にしていたから、こうなったのだと思う。
日中が4割あるのは、指示の39%が土日に出ているため。
なお、どの指示を PC から出し、どれをスマホから出したかは履歴に残っていないので、その比率は出せなかった。
人間に残ったのは「これは何か」と「楽しいか」
コードは書いていない。やったのは、出来上がったものを自分で使って、楽しいかどうかを判断してフィードバックすることだけだった。これをひたすら繰り返した。
一番はっきりしているのが、絵文字タイルの色の扱い。
写真の色に寄せたければ、絵文字のグリフを再着色するのが手っ取り早い。実際そのほうが「元写真に似ている」出力になる。でもそれをやると、このアプリは絵文字を並べたものではなく、絵文字の形をした色の塊になる。
だから「絵文字タイルの色は絶対に変えない」を不変条件として決めた。色を寄せたいときは、絵文字を選ぶ前に元写真側へフィルターをかけて選択を誘導する。使える絵文字の色は限られているので再現には限界があるが、その限界をタイルの塗り替えで誤魔化さない。
これは技術の判断ではない。このアプリが何であるかの定義であって、AI には決められなかった。というより、頼めば「似せる」方向へ最適化してしまう。アイコンの良し悪しも、どの絵文字をセットに入れるかも同じだった。正解が外に無いものは渡せない。
機能を足すのと同じだけの時間を、踏み外さない仕組みに使った
1か月のうち、機能追加と同じくらいの時間を「AI が踏み外さないようにする仕組み」に使っている。
起点は、最初のコミットを作る数時間前に出したこの指示だった。
設計するにあたり、以下のことを
ui/ux がアップルの標準アプリから逸脱しない 10代が楽しめる、sns に投稿したくなる マルチ言語、ただし言語がわからなくても使える
この辺りのルールはドキュメントに整理して、今後アプリの変更でも守れるように。
最後の一行が効いた。 判断基準をその場の会話で終わらせず、文書にして残させる。以降このアプリで何かを決めるときは、毎回そこに照らすことになった。
リポジトリの CLAUDE.md に不変条件を書く(色を塗り替えない、など)
テストを8,847行書かせる
UI に出す言葉を用語集にまとめ、違反をスクリプトで検査する
ソース中の日本語リテラル全件に、対応45言語ぶんの文言が揃っているかを機械で照合する
アーキテクチャ違反(依存の向きが逆)を検出するテストを置く
日本語・英語以外の訳は、原文を見ていない別のエージェントに訳し戻させて照合する
デバッグ用の課金トグルが出荷バイナリに混入していないかをリリース前に自動検査する
正直に書くと、これらも全部 AI に作らせている。私がやったのは「ここが壊れると困る」と言うことだけ。ただ、この一言を言うか言わないかの差はかなり大きかった。この仕組みが無い状態で機能を足していくと、3日前に直したはずのものが静かに戻る。
1か月で、603コミットとテスト8,847行
期間 — 2026-07-20 着手 → 2026-08-20 公開(31日)
コミット — 603
マージした PR — 80
Swift ファイル — 172
本体+拡張の行数 — 22,031
テストの行数 — 8,847
docs — 152本(設計・計画・裁定 70/言語別の翻訳QA 62/恒久ルール 18/その他 2)
対応言語 — 45(うちストア掲載情報は34)
私が打った指示 — 1,349回(中央値45文字)
人間が書いた Swift — 0行
先に断っておくと、行数もコミット数も質の指標ではない。「AI に書かせると量が増える」という指摘はそのとおりで、この数字だけで何かを主張するつもりはない。意味があるとしたら比率のほうだと思う。本体と拡張で22,031行に対して、テストが8,847行、docs が152本。時間は、機能を増やすことと同じくらい「壊れていないと言えること」に消えた。
公開までの25日 — 審査は始まっていなかった
作ること自体はサクサク進んだ。詰まったのは公開の手続きだけで、しかも詰まり方が想像と違った。
まず全体の流れ。経過は最初の提出(7/26)からの日数。
7/18 — ラーメン屋で「現実的かな」と相談
7/20 — 最初のコミット
7/26 — v1.0.0 を提出。着手から6日。Waiting for Review に入る(0日)
7/31 — 銀行口座を登録(5日)
8/02 — 税務フォームを登録。v1.0.0 を取り下げて v1.1.0 を提出(7日)
8/07 — v1.1.0 を取り下げ、v1.2.0 を提出(12日)
8/14 — 課金アイテムが提出に含まれていないと判明。取り下げて v1.3.0 を提出。その日のうちに Guideline 2.1(情報不足)で却下(19日)
8/16 — 指摘に返信したうえで、あらためて再提出(21日)
8/19 — 審査中に規約が改定されていたと判明。同意する(24日)
8/20 — 公開(25日)
提出したバージョンは4つ。うち3回は承認される前に自分で取り下げている(v1.3.0 は却下されたあとに出し直しているので、提出の操作としては5回になる)。
止めていたのは、契約と税務だった
App Store Connect の Waiting for Review は待ち行列であって、審査そのものではない。実際に審査されているのは In Review のほうだけ。ここまでは知っていた。
知らなかったのは、契約や税務がブロックしている場合、Waiting for Review のまま何十日でも止まるということ。エラーも通知も出ない。画面の上では「混んでいるだけ」と「止まっている」が区別できない。
私の場合、ブロック要因は5つあった。4つは提出した時点ですでに潜んでいて、5つ目は審査の途中で降ってきた。
有料 App 契約が Active になっていない — 署名しただけでは有効にならない。税務フォームと銀行情報が全部揃って初めて Active になる。1つでも欠けると契約全体が止まる(Apple のヘルプ「View agreements status」には、まさにこの状態を表す Pending User Info(署名したが必要な情報が未提出のため有効でない) というステータスが載っている)
米国の税務フォームが未提出 — 所在地に関係なく必須(Provide tax information)
銀行情報が未登録 — 口座名義人の住所が契約側の住所と完全一致していないと弾かれる(Enter banking information)
初回の課金アイテムを審査に出していない
Apple Developer Program License Agreement の改定に未同意 — これだけは審査の途中で発生した
ブロッカーは1件ずつ、間を空けて出てきた。 提出から5日後、7日後、19日後、24日後(5件のうち「有料 App 契約が Active でない」は税務と銀行が揃えば解ける親要因なので、見つけた日は4日)。見つけて直して、また待って、また別の1件が出てくる。その間ずっと画面は Waiting for Reviewのままだった。
高くついたのは、原因が5件あったこと自体ではない。1件見つけては直して、また数日待つ、を繰り返したことのほうだった。1件見つけた時点で「原因が分かった」と思い込み、同じ層に他の地雷が埋まっていないかを確認しなかった。待ちを含む工程でこれをやると、支払いは 待ち時間 × 要因数 に化ける。
しかも最後の1件は、待っている間に新しく増えたものだった。最初に全部洗い出していても防げなかった種類の足止めが、ひとつ混ざっている。
そして最後の1件に気づいたのは 公開の前日だった。同意したその日のうちに審査は通り、翌日には公開されている。25日待った理由の最後のひとつは、バナーを1回押していなかったことだった。
「できるだけ早めに登録してください」
税務フォームで一番つまずいたのは、この一行だった。
画面には「できるだけ早めに登録してください」としか書かれていなかった。 必須だとは読めない。任意の推奨事項だと思って後回しにした。
ところが Apple のヘルプページ Provide tax information には、こう書いてある。
All developers must complete a US tax form to comply with the Paid Apps Agreement.
must である。所在地は関係ない。そして提出できるのは有料 App 契約に署名したあとなので、順番も決まっている。
つまり必須だという情報は公開されていた。 私が見ていた入力画面の側に「早めに」としか書かれていなかっただけだった。「早めに」には締切が無く、急かされているだけに読める。「無いと止まる」は前提条件。同じ手続きが、場所によって別の強さで書かれていた。 契約が揃うまでの7日は、その差から来ている。
初回リリースだけ、コマンドで完結しない
v1.2.0 を出した時点で、リリース手順はコマンド化していた。検証してストア画像を撮り直してバージョンを上げて PR を出すところまでが1コマンド、タグを打ってアップロードして審査提出するところまでがもう1コマンド。
それでも v1.2.0 は7日間動かなかった。原因は、初回の課金アイテムが提出に含まれていなかったこと。アプリが一度も公開されていない間は、バージョン番号に関わらず「初回」として扱われ、課金アイテムは Web の画面から手で紐付ける必要がある。 API にはこの経路が無い。自動化した手順からこの一手だけが抜け落ちていた。
v1.3.0 では先に Web で紐付けてから出した。今度は審査に入った。
人とやり取りできていたので、動いていると思っていた
8/14 に v1.3.0 を出し直したところ、その日のうちに審査から Guideline 2.1(情報不足)で却下された。アプリの説明が足りない、という趣旨だったので、不備を直して審査メモに回答を書き、返信した。
ここまでは確かに動いていた。 担当者から指摘が来て、こちらが答える。ラリーが成立している。相手が反応しているのだから、止まっているはずがない。そう思った。
ところが進まない。返信は会話であって、審査の列に戻る手続きではなかった。 返信とは別に、もう一度審査に出す操作が要る。私は返信した時点で「対応済み」だと思っていた。2日後にそれに気づいて、あらためて提出し直した。
それでも進まなかった。審査をしている間に、規約が改定されていた。 新しい版に同意するまで先へ進まない。提出した時点では無かった条件が、待っている間に増えていたことになる。
気づいたのは 8/19、PC で App Store Connect を開いたときだった。例によって、iPhone のアプリにも API にも警告は出ていない。 しかも同意する場所は App Store Connect ですらなく、developer.apple.com 側のバナーだった。同意したその日のうちに、審査は完了している。
ここが一番タチが悪かったと思う。直前まで人とやり取りできていたことが、かえって「進んでいる」という誤解を強くした。 会話の経路と、審査を進める経路は別だった。そして後者だけが、何も言わずに止まっていた。
どれも、Web の画面にしか出ていなかった
銀行情報も、税務フォームも、課金アイテムの紐付けも、規約の改定も、全部 PC の Web で気づいた。 それまでは iPhone の App Store Connect アプリと API で状況を見ていた。どちらにも警告は出ず、「提出済み・審査待ち」としか表示されない。開発をスマホで進められたのは良かったが、手続きだけはスマホから見えなかった。
手抜きをしたつもりはなく、見られるものは全部見ているつもりだった。
ところが App Store Connect API には契約ステータスを取るエンドポイントが無い。/v1/agreements は非推奨で、新しいバージョンでは削除されている。代わりに 403 を踏むかどうかで間接的に推測するしかなく、しかもその 403 は強制が始まってからしか出ない。Web の画面には警告が出ているのに、同じ時点で API は 200 を返す。
つまり API が全部緑でも契約はブロックしていることがある。契約ステータスの正本は、Web の App Store Connect > Business > Agreements だけだった。
自動化できる範囲が、いつのまにか確認すべき範囲そのものを定義してしまっていた。次からは提出前チェックリストに「App Store Connect の Business タブ」と「developer.apple.com のバナー」を目で見る、という行を明示的に置く。人間の目でしか見えない場所を、タスクとして名指ししておかないと、また同じことをやる。
待っている間、機能を足し続けていた
審査が進まない間は手が空く。7/26 から公開までの25日で、動画のモザイク化、Metal を使ったリアルタイム処理、ライブ撮影、共有拡張の機能同等化、45言語対応、UI 文言の用語集整備、といったものが入った。7/26 の v1.0.0 と、公開された v1.3.0 は、もう別のアプリと言っていい。
ただし動画とライブ撮影は、いまも App Store 版には出していない。作ったが、出す判断をまだしていない。
これが良かったのかは分からない。待ち時間を機能で埋めるのは、本来は順番が逆だと思う。ただ、止まっている理由が分からない状態で待つよりは、手を動かしているほうが精神衛生上よかった。
かかった費用は $224
Claude Max(1か月) — $110
Apple Developer Program(年額・今回新規登録) — $99
emotile.app ドメイン(Cloudflare Registrar・1年) — $15
Cloudflare Pages(サイトのホスティング) — $0(無料枠)
合計 $224
API で全部読めるようにしてほしい
これだけは書いておきたい。
App Store Connect の情報を、API で全部読めるようにしてほしい。
契約のステータス、税務フォームの提出状況、銀行情報の不備、初回の課金アイテムの紐付け、規約改定への同意。今回私を25日止めたものは、全部 Web の画面にしか無かった。API は正常を返し続けていた。
AI に開発を任せる作り方が普通になっていくなら、エージェントが読めない情報は存在しないのと同じになる。人間が画面を目で見て回らないと分からない状態が残っている限り、そこが必ずボトルネックになる。実際そうなった。
まとめ
動くものができるまで1週間。そこから公開まで25日。その大半は、審査が「始まっていなかった」時間だった
提出したバージョンは4つ、取り下げ3回。ブロッカーは5件。4件は最初から潜んでいて、1件は待っている間に増えた
詰まった箇所はどれも同じ形だった。「やった」と「進んでいる」が画面で区別できない(契約の不備・返信だけで再審査に出していない・API は正常を返す)
Swift は一行も書いていないし、今も読めない。それでも公開できた
人間に残ったのは「これは何であるか」を決めることと、「楽しいか」を判断すること
指示は1,349回、中央値45文字。仕様書は先に渡すものではなく、実装したあとに現状を整理して書き起こすものだった
効いたのは Xcode の画面を開かなくて済む形に倒したこと。コマンドで呼べるものは AI がそのまま実行できる
iOS 開発を知らなくても、通勤電車と寝かしつけの時間で、アプリは公開できる。詰まるとしたらコードではなく、たぶん App Store Connect 側の公開作業 — 契約や審査のほうです。
Emotile(App Store・無料): https://apps.apple.com/app/id6794346554
サイト: https://emotile.app
参考(すべて Apple の公式ヘルプ)
View agreements status — 契約ステータスの一覧。Pending User Info の意味はここ
Sign and update agreements — 有料 App 契約の署名(Account Holder のみ)
Provide tax information — 米国税務フォームが必須である旨
Enter banking information — 銀行情報の登録
