Skip to content
··2分で読めます

App Storeが承認した

2週間前,私はブログに「まだ開発中。まだ完成していない」と書いた。今日,DIALØGUE(ダイアログ)はApp Storeで公開されている。最後の40%が実際どんな作業だったか,正直に話す。

2週間前,私はブログの締めにこう書いた。「まだ開発中。まだ完成していない。娘に何を話せばいいか,まだわからない。」

App Storeに公開できたら続報を書く,と約束していた。あるいは審査落ちしたときも。「リジェクトされた話の方が面白いかもしれない」と書いた。その予感は正しかった。

DIALØGUE(ダイアログ) - AI Podcast Studio が今,App Storeで公開されている。 Swiftを一度も書いたことのない人間が Claude Code を使って作った,ネイティブの SwiftUI iOSアプリだ。どんなトピックやPDFからでも,完全にプロデュースされたポッドキャストエピソードを生成できる。今すぐダウンロードできる。

ただし,一発で通ったわけではない。正直に言うと,リジェクトされた話の方が承認された話より面白いと思っていた。それは本当だった。


Appleに最初の申請がリジェクトされたとき,何が起きたか?

最初の申請はリジェクトされた。ガイドライン2.1 — パフォーマンス:アプリの完成度。アプリ内購入が壊れていた。

Appleのレビューメッセージは丁寧だった。初めての申請だと気づいて,デベロッパープログラムへの参加を祝福してくれた上で,問題を明確に説明してくれた。レビュアーが購入しようとしたとき,IAPプロダクトがエラーになったのだ。

これが厄介なところで,購入フローは私のテストでは完璧に動いていた。問題はAppleのサンドボックス環境にあった。開発環境とも本番環境とも異なる振る舞いをするあの環境だ。StoreKitの設定はApp Store Connectと完全に同期している必要がある。私のはそうなっていなかった。ローカルのStoreKit設定ファイルを使ってテストしていたが,レビュアーは本物のサンドボックスを使っていた。

同日中に修正して再申請したら,通った。その後まもなく,v1.0.1のバグ修正アップデートも申請したが,これもスムーズに通過した。

申請回数は合計3回。リジェクト1回。そのリジェクトから,2回の承認より多くのことを学んだ。これってよくあるパターンじゃないかと思う。失敗の方が,成功よりもいつも多くを教えてくれる。


「最後の40%」は実際どんな作業だったか?

元の記事で,AIが60%まで連れて行ってくれて,残りの40%は完全に人間の仕事だと書いた。今はもう少し具体的に言える。gitのログがそれを証明してくれている。

コミット数16,変更ファイル数57,追加行数4,886行。 アプリはSwiftファイル69本から88本へ,コード行数は7,568行から11,459行に増えた。約4,000行の「磨き上げ」だ。

その16コミットに何が含まれていたか,大まかな順番で振り返ってみる。

最初から存在すべきだったテストスイート

最初のスキャフォールドにはテストがゼロだった。本当にゼロ。Claudeは69ファイルのプロダクションコードを生成したが,テストは1本もなかった。元の記事の直後に最初に書いた本格的なコミットで,ローカルのSupabaseインスタンスに対して動くユニットテスト176本とインテグレーションテスト19本を追加した。

テストを書いてすぐに,本物のバグがいくつも見つかった。存在しないデータベースカラムによるShowモデルのデコード失敗,トラックの終わりでAudioPlayerがリセットされない問題,ライブラリのリロード競合状態,作成ウィザードのnil UUID ガード漏れ。どれも,そのまま本番に出ていたらクラッシュしていたものばかりだ。

これは名前をつけておく価値のあるパターンだと思う。AIはテストのインフラを持たないコードを生成する。 テストが書けないわけではない——頼めばClaudeはちゃんと書いてくれる——でも,最初のスキャフォールドプロンプトはいつも「アプリを作って」であって,「テスト付きでアプリを作って」ではない。テストを書いたのは,テストなしでは出荷できないと私自身が判断したからだ。

DIALØGUE iOS app outline review screen showing 6 podcast segments with Approve and Give Feedback buttons in dark mode
アウトラインレビュー画面——AIが生成した音声を承認するか,フィードバックを送るかを選ぶステップ。

スタブ状態だったStudio機能の作り込み

もともとの「Studio」機能(定期配信番組の管理)はプレースホルダーに過ぎなかった。2コミット後,それは本物のプロダクトになった。テンプレートグリッドによる番組作成,ステータスバッジとアクションボタン付きのエピソード管理,編集・削除ワークフロー,タイムゾーンピッカー付きのスケジュール設定,ボイスカスタマイズシート。

その後,Studio Phase 2として,番組詳細画面のリデザイン,エピソードごとのリトライ・削除,クレジット残高チェック付きの手動エピソード生成を追加した。動作確認のためにXCUITestも8本新たに書いた。

これが「AIはコードベースを作ったが,プロダクトは作っていない」という意味だった。Studioの機能はコンパイルが通っていた。画面もレンダリングされていた。でも,実際にポッドキャストの定期配信番組を管理することはできなかった。

DIALØGUE iOS app showing 9 podcast format templates including Tech News Analysis, Deep Dive, and Investigative Comedy in a dark-mode grid layout
Tech News AnalysisからInvestigative Comedyまで,9種類のポッドキャスト形式。

オーディオプレイヤーの作り直し

元の記事では,ミニプレイヤーを削除したと書いた。あれは間違いだった。結局,もっと良いミニプレイヤーを作ることになった。最終的なデザインは,タブバーの上に常駐するミニプレイヤーバーで,進捗状況,スキップコントロール,再生・一時停止ボタンを備えている。タップするとシークスライダー,再生速度セレクター(0.5倍から2倍),トランスポートコントロール,そしてサウンドリングのアートワークアニメーションを含む「Now Playing」シートが展開される。

難しかったのはisSeekingという状態管理だった。これがないと,スライダーの位置とオーディオオブザーバーが競合して,ガクガクした動きになる。診断に1時間かかった1行の状態変数だ。

オフラインダウンロード機能も追加した。ライブラリのダウンロード済みエピソードには緑のアイコン,完了トースト通知,Now Playingに「Downloaded」ラベル,そしてスワイプでダウンロード削除。DownloadManagerのURLSessionデリゲートには,一時ファイルの競合状態があり,サイレントな失敗を引き起こしていた。コールバック内での同期ファイル移動で修正したが,コードレビューでは絶対に気づかないタイプのバグだ。

全レイヤーにわたるセキュリティ強化

これは少し衝撃的な作業だった。iOSアプリだけでなくフルスタック全体のセキュリティ監査を行ったところ,複数のレイヤーに渡って脆弱性が見つかった。過剰な権限を持つデータベース関数,認証のエッジケース,トークン検証の抜け,複数のバックエンドサービスでの入力バリデーション不足。

これらはiOSのSwiftコードの中にはなかった。iOSアプリが話しかけるバックエンドにあった。でも,iOSアプリを出荷するということは,スタック全体がユーザーのポケットに入ることを意味する。その事実が,あらゆるものへの要求水準を上げた。ウェブアプリとして「問題なく動いていた」コードが,Appleの審査を経て,人々が持ち歩くネイティブアプリに入ると思うと,受け入れられなくなった。

StoreKit:申請を落とした犯人

StoreKitのサンドボックステストは独自の世界で,まさにそれが最初の申請をリジェクトさせた。 サンドボックス環境は本番とは異なる動きをする。トランザクションが永遠に「pending」のままになることがある。XcodeのStoreKit設定ファイルは手動での同期が必要だ。コード上は完璧に動く購入フローが,サンドボックスでサイレントに失敗する原因をある晩中調べた結果,App Store Connectのプロダクトidに末尾のスペースが入っていたことがわかった。スペース1文字。

AppleのレビュアーがサンドボックスエラーにぶつかったのはStoreKitの設定がApp Store Connectと同期していなかったからで,私のローカルテストでは購入フローは完璧に動いていた。でも,レビュアーはローカルのStoreKit設定ファイルではなく,本物のサンドボックスを使っていた。同日中に修正したが,「自分のマシンでは動く」と「Appleの環境でも動く」のギャップが馬鹿にならないという完璧な実例だ。

購入の検証チェーンはそれ自体が1つのプロジェクトだった。iOSアプリはトランザクションのJWS(JSON Web Signature)表現をサーバーサイド関数に送り,Appleの署名済みレシートの完全な暗号チェーン検証を行う。デコードするだけでなく,実際のシグネチャ検証だ。これを正しく実装するために2コミット費やした。

プライバシーとApp Storeコンプライアンス

プライバシーとコンプライアンスは,法的な意味を持つフォームと意思決定とチェックボックスであり,AIにはそれを代わりに入力することはできない。 App Tracking Transparencyの申告,プライバシーの栄養表示ラベル,暗号化に関する輸出コンプライアンス(そう,HTTPSも対象に入る),コンテンツの権利,TurnstileのCaptcha統合。Claude CodeはSwiftを書けるが,あなたのデータ収集の実践が「Data Used to Track You」ラベルを必要とするかどうかは教えてくれない。

MFA完全実装とローカライズ

最初のMFA実装は壊れたスタブだった。空のファクターIDで,検証のみのフローだった。これを完全なTOTPライフサイクルとして書き直した。登録,QRコードスキャン(ネイティブのCoreImageで生成),検証,ステータス確認,無効化。これが,以前は存在しなかった394行のMFAView.swiftだ。

7言語へのローカライズでは,英語・スペイン語・フランス語・日本語・韓国語・ベトナム語・中国語に253のUI文字列を翻訳した。Claudeが翻訳を担当したが,出来はおおむね良かった。でも日本語での「おおむね良い」は,文法的には正しいのに機械が書いたように聞こえるボタンラベルが紛れ込んでいる可能性を意味する。スマートフォンの言語を切り替えて実際にアプリを使うことで,そういう箇所をいくつか発見した。これはAIにはまだできないテストだ。


DIALØGUE iOSアプリで何ができるか?

元のビルドストーリーを読んでいない方のために,DIALØGUE が何をするものかをまとめておく。

トピックを入力するか,PDFをアップロードすると,完全にリサーチされ,スクリプト化され,声が付いたポッドキャストエピソードが生成される。2人のAIホストがあなたのトピックについて自然な会話をする。本物のリサーチに裏付けられた対話だ。マイクは不要。

iOSアプリに含まれる機能:

  • 5ステップの作成ウィザード — トピック,フォーマット,カスタマイズ,アウトラインレビュー,スクリプトレビュー
  • 7言語30種類のAIボイス — 英語・スペイン語・フランス語・日本語・韓国語・ベトナム語・中国語
  • 9種類のポッドキャスト形式 — Tech News AnalysisからInvestigative Comedyまで
  • ロック画面コントロール付きオーディオ再生 — バックグラウンド再生もそのまま動く
  • Apple Sign-In,Google OAuth,メール認証
  • アプリ内購入 — サブスクリプションなし,クレジット制:4クレジット$4.99,9クレジット$9.99,18クレジット$19.99
  • Studio — 自動的に新しいエピソードを生成する定期番組の設定
  • PDFアップロード — 研究論文,レポート,書籍をソース素材として使用可能

本物のネイティブSwiftUIアプリだ。ウェブラッパーでも,React Nativeでもない。69本のSwiftファイルから始まったものが,195本のテストに裏付けられた88ファイル・11,459行のコードになった。出荷できたことを,心から誇りに思っている。

DIALØGUE iOS app library view showing podcast episodes with play buttons, duration, and dark mode UI
ライブラリ——生成したポッドキャストエピソードがすぐ聴ける状態で並んでいる。

最初の「磨き上げフェーズ」の見積もりはどれだけ外れていたか?

「アプリはまだ開発中で,最終的な磨き上げフェーズにある」と書いた。技術的には正しかったが,「磨き上げフェーズ」の大部分が実際には新規開発だったことを過小評価していた。

gitログを今見返すと,16コミットは「磨き上げ」とは呼べない。これは開発の第2フェーズだ。テストスイートだけで——ユニットテスト176本とインテグレーションテスト19本——それ自体が1つのプロジェクトだった。Studioはスタブから本格的な機能になった。オーディオプレイヤーは2度作り直された。セキュリティ強化は40以上のバックエンド関数に触れた。MFAはゼロから書き直した。

ミニプレイヤーを削除したという話についても,間違いだった。最終的にはNow Playingシート,スピードコントロール,ダウンロードインジケーターを備えた,より良いものを作ることになった。「削除する」という最初の判断は正しかった——最初のミニプレイヤーは出来が悪かった。でもコンセプトは正しかった。ただ,ちゃんと作る必要があっただけだ。

全体像が見えた今,正直な内訳はこうだと思う。AIが基盤を作る(60%),人間がプロダクトを作る(30%),そしてApp Store申請プロセスが残りの10%を教えてくれる。


DIALØGUEはEUで使えるか?

DIALØGUEは世界中で提供されているが,EUでの提供はAppleが処理中だ。 EUのデジタル市場法(DMA)は追加のコンプライアンス手順を要求する。代替決済手段の開示,特定のプライバシー文書,ビジネス登録の詳細。必要書類はすべて提出済みで,Appleが今レビュー中だ。近くEU各国でも提供される予定だ。

EU在住で待てない方は,ウェブアプリがすべての機能を備えた状態でどこからでも使える。


AIを使ったiOS開発はどれだけ速いか?

DIALØGUE iOSアプリは,最初のコミットからApp Store承認まで約2週間かかった。AIによるスキャフォールディングに1夜,人間によるプロダクト作業に2週間。 この表はずっと更新し続けているが,更新するたびに何かを教えてくれる。

プロジェクト複雑さ開発期間
DIALØGUE v1MVPポッドキャストジェネレーター約6ヶ月
STRAŦUMAIエージェント10体,フレームワーク11種,マルチテナント75日
サイトリデザインWordPressフロントエンドの刷新3日
DIALØGUE v2ウェブアプリの完全リビルド14日
ブログ移行WordPress → Next.js,490記事,Sydney RAG4日
DIALØGUE iOSネイティブiOSアプリ,Swift初体験約2週間(スキャフォールド:1夜)

DIALØGUE iOSのスキャフォールドから出荷までのギャップは約2週間。スキャフォールド自体は1夜。この比率——AIの作業1夜対人間の作業2週間——が,AI支援開発の現在地について,すべてを物語っている。

AIの担当部分はどんどん速くなっている。人間の担当部分はほぼ同じままだ。2週間前にそう書いたが,今もそれは変わっていない。


AIがコードを書く時代に,何のスキルが重要か?

元の記事では,正しいアドバイスをまだ探している段階だった。「シミュレーターを起動する人間になれ」が,当時の私が出せた最善の言葉だった。

実際に出荷を経験した今,もう少し具体的に言える気がする。

このアプリが存在するのは,AIにはできなかった3つのことのおかげだ。

  1. 私はプロダクトを使った。 テストしたのではなく,使った。ポッドキャストを作り,通勤中に聴いた。アウトラインレビュー画面にリサーチのソースを表示する必要があると気づいたのは,事実の出どころを自分が知りたいと思ったからだ。

  2. 正解のない判断を下した。 ミニプレイヤーを削除するか残すか?作成ウィザードのカスタマイズはどこまでが多すぎるか?Studio機能はタブにすべきかセクションにすべきか?これらはエンジニアリングの意思決定ではない。センスの問題だ。そしてセンスは,たくさんのプロダクトを——優れたものも酷いものも——使い込んで,何が正しく感じるかという直感を養うことで身につく。

  3. 人間のために設計されたシステムをナビゲートした。 App Store Connect,プライバシー申告,輸出コンプライアンス,スクリーンショット要件——これらは自動化できない。読み,文脈を理解し,法的・ビジネス的な意味合いについて判断を下すことが求められる。複雑な人間のシステムをナビゲートするというスキルは,なくならない。

だから,更新版のアドバイスはこうなるかもしれない。物事を深く使い込む習慣をつけ,品質にこだわることでセンスを磨き,シンプルには設計されていないシステムに向き合うことに慣れろ。

「批判的に考えることを学べ」より具体的だし,真実に近いと思う。それで十分かどうか,まだわからないけれど。


DIALØGUEをダウンロードするには?

アプリは無料でダウンロードできる。アプリ内でクレジットを購入する形式で,サブスクリプションはない。

App Storeでダウンロード

世界中で提供中。EUでの提供はAppleが処理中で,間もなく利用可能になる予定。ウェブアプリはどこからでも使える。


よくある質問

DIALØGUEはApp Storeで公開されていますか?

はい!DIALØGUE - AI Podcast Studio は2026年3月にApp Storeでリリースされた。無料ダウンロード,アプリ内クレジット購入制(4クレジット$4.99,9クレジット$9.99,18クレジット$19.99)。世界中で提供中。EUでの提供は申請済みで,Appleが処理中。

EUでは使えますか?

申請済みで,Appleが処理中。EUのデジタル市場法(DMA)が追加のコンプライアンス手順を要求しており,必要書類はすべて提出したのでAppleのレビューを待っている状態だ。近く利用可能になる予定。それまでの間,ウェブアプリがEUを含むどこからでも使える。

Appleにリジェクトされましたか?

された。最初の申請は,アプリ内購入の不具合(ガイドライン2.1:アプリの完成度)でリジェクトされた。StoreKitのサンドボックス設定がApp Store Connectと同期していなかったため,審査中に購入がエラーになった。同日中に修正して再申請したら通った。その後v1.0.1も通過。申請回数合計3回,リジェクト1回。そのリジェクトの方が,どちらの承認よりも多くを教えてくれた。

全体のプロセスにどのくらいかかりましたか?

元のブログ記事からApp Store承認まで約2週間。Claude Codeが1夜で69本のSwiftファイルをスキャフォールドした。残りの16コミットで,57ファイルに4,886行が追加された——テスト,Studio機能,オーディオプレイヤーのリデザイン,MFAの書き直し,セキュリティ強化,StoreKit検証,ローカライズ,そしてApp Store申請プロセスだ。アプリは88ファイル・11,459行・195テストの状態で出荷された。

最後の40%で最も大変だったことは何ですか?

StoreKitのサンドボックステストだ。「コードでは動く」と「Appleのトランザクションシステムで動く」のギャップは巨大だ。サンドボックスのトランザクションは本番とは異なる動きをし,プロダクトIDは完全に一致している必要があり(末尾のスペースまで),フィードバックのループが遅い——ユニットテストを走らせるように簡単に確認できない。

ウェブアプリは引き続き使えますか?

もちろん。podcast.chandlernguyen.com は同じ機能を持ち,どんなデバイスでも動く。iOSアプリにはApple Sign-In,ロック画面コントロール,オフラインダウンロードというネイティブならではの便利さがあるが,ポッドキャスト生成のコア体験はまったく同じだ。


娘に何を話せばいいか,まだ考えている。でも少なくとも今は,「人間の仕事こそが難しい部分だ」と言うとき,指差せる出荷済みアプリがある。


それでは,Chandler

続きを読む

私の歩み
つながる
言語
設定