壁紙アプリの更新告知を書いていた夜、日付の欄でふと手が止まりました。作業そのものは、あと 2 日で終わる見込みでした。それなのに「公開は来週です」と書いてよいのか、自信が持てなかったのです。
結局その日は、日付を空欄にしたまま保存しました。待ち時間は私の手の外にあり、見積もりに入れていなかったことに、そこで気づきました。
Rork でアプリが形になると、「あとは出すだけ」という気持ちになりやすいと思います。ですが、初めてストアに出す場合は、作る時間より待つ時間のほうが長くなることが珍しくありません。
最初にお伝えしたいのは、「1 週間でリリース」という約束は、条件がそろったときにだけ成り立つ、ということです。ここから、待たされる日数を内訳にして、自分の日付を逆算できるところまで書き残します。
待ち時間は 4 種類に分けると見えてきます
「審査が長い」とひとまとめにすると、どこで時間を使うのかが見えません。私は次の 4 つに分けて数えています。
| 待ち時間 | どちらの手の中か | 目安の取り方 |
|---|---|---|
| Apple Developer の登録承認 | Apple 側(個人か法人かで変わります) | 数日の幅を見込み、法人は長めに置きます |
| Google Play の非公開テスト | 自分(テスターを集める日数)と暦(連続日数) | 個人アカウントでは、公式ヘルプに定められた人数と連続日数があります |
| 初回審査(App Store) | Apple 側 | 多くは短くても、差し戻しの可能性を別に積みます |
| 初回審査(Google Play) | Google 側 | 初めてのアカウントは、通常より長く見ておきます |
数字は時期やアカウントの状態で変わります。ですので、表には日数を書かず「どの手の中か」を置きました。実際の日数は、見積もりの当日に、公式ヘルプで確かめていただければと思います。
見落としやすいのは、Google Play の 14 日です
個人で作る方がいちばん計算を外しやすいのは、ここだと感じています。個人の開発者アカウントでは、公開の前に、非公開テストを一定人数のテスターと一定の連続日数で回す条件が設けられています(人数と日数は公式ヘルプでご確認ください。私が把握している限りでは 12 人・連続 14 日です)。
この日数は、テスターが全員そろってから数え始めます。つまり、見積もりに入れるべきなのは 14 日だけではありません。
- テスターを集めるまでの日数(ここが一番ぶれます)
- そろってからの連続日数
- 途中で抜けた人を補う余裕
人が集まる速さは、自分の力ではどうにもなりません。私は、集める日数を「3 日から 3 週間」と幅で置くようにしています。
日付を逆算するスクリプト
「最短ならいつ、遅れたらいつ」を毎回手で足し算するのは、手が止まる原因になります。次のスクリプトに、待ち時間の最小値と最大値を入れておくだけで、2 本の道(iOS と Android)の日付を並べてくれます。
// release-eta.ts
// 目的: 「公開できる最短日」と「遅れた場合の日」を、待ち時間の幅から逆算します
// 実行: npx tsx release-eta.ts
// 日数はすべて私の見込みです。公式の保証値ではないので、当日に確かめて書き換えてください
type Wait = { label: string; min: number; max: number }; // 営業日ではなく暦日で数えます
const DAY = 86_400_000;
const addDays = (d: Date, n: number) => new Date(d.getTime() + n * DAY);
const fmt = (d: Date) => d.toISOString().slice(0, 10); // UTC 表記なので、最大で 1 日ずれます
function eta(start: Date, steps: Wait[], rejectBuffer = 0) {
const sum = (k: "min" | "max") => steps.reduce((a, s) => a + s[k], 0);
return {
earliest: addDays(start, sum("min")),
latest: addDays(start, sum("max") + rejectBuffer),
};
}
const start = new Date("2026-10-13"); // 作業を始める日(今日でも構いません)
// iOS の道: 登録承認 → 審査
const ios = eta(start, [
{ label: "Apple Developer 登録承認", min: 1, max: 7 },
{ label: "App Store 初回審査", min: 1, max: 4 },
], 3); // 差し戻しが 1 回あった場合の再提出分
// Android の道: テスター集め → 連続日数 → 審査
const android = eta(start, [
{ label: "テスターを集める", min: 3, max: 21 },
{ label: "非公開テストの連続日数", min: 14, max: 14 },
{ label: "Google Play 初回審査", min: 2, max: 7 },
], 3);
console.log("iOS 最短:", fmt(ios.earliest), " 遅れた場合:", fmt(ios.latest));
console.log("Android 最短:", fmt(android.earliest), " 遅れた場合:", fmt(android.latest));
// 両方出すなら、遅いほうの道が公開日を決めます
const both = new Date(Math.max(ios.latest.getTime(), android.latest.getTime()));
console.log("両方そろえて出せる日(遅れた場合):", fmt(both));この見積もりで 2026 年 10 月 13 日に始めた場合は、Android の道が先に重くなります。最短でも 19 日後、遅れた場合は 45 日後、つまり 6 週間を超えるところまで伸びる計算です。
数字そのものよりも、どちらの道が日付を決めているかが一目で分かることのほうが、役に立ちます。「1 週間」と書く前に、この出力を一度ご覧になってください。
差し戻しは「起きるもの」として 3 日だけ積みます
初めての審査では、一度で通らない可能性も見込んでおきたいところです。スクリプトの rejectBuffer に 3 日を入れているのは、修正して再提出し、もう一度待つ分の目安です。
差し戻しの理由は、アプリの出来そのものより、説明文やプライバシー情報、ログイン用のテストアカウントの不足といった「書類側」であることも少なくありません。ですので、審査に出す前に、審査担当の方が迷わず触れる状態になっているかを一度だけ見直します。
私は、この見直しに半日をあてています。半日を惜しんで 3 日を失うよりも、はるかに安く済むからです。
書き方を変えると、約束が軽くなります
見積もりが長くなっても、がっかりする必要はありません。伝え方を変えるだけで、約束はずいぶん軽くなります。
- 「◯日公開」ではなく「◯月の第 2 週から順次」と、幅で書く
- iOS と Android の日付を分けて書く(同時公開にこだわりすぎないこと)
- 待ち時間のあいだに、スクリーンショットや説明文など、自分の手で進められるものを前倒しする
公開の瞬間そのものを自分で決める方法は、別の記事(審査がいつ明けるか読めないなら、公開日は審査の外側で決めます)にまとめています。こちらは「いつ出せるか」を知る側、あちらは「出す瞬間を決める」側の話です。
バンドル ID のように、あとから変えられない値を決める作業も、待ち時間の前に済ませておきたい仕事です。最初のリリース前に決めておきたいアプリ ID の話も、あわせてご覧ください。
約束の日付は、相手の待ち時間まで足してから置きます
私が日付の欄で手を止めた夜から、線引きは一つだけ変わりました。
約束の日付は、自分の作業日数ではなく、相手の待ち時間まで足した日に置きます。
それ以来、告知文の日付は「遅れた場合」の列から選ぶようにしています。早く出せたときは、ただ嬉しいだけで済みます。
明日の最初の作業として、上のスクリプトに自分の始める日と、公式ヘルプで確かめた日数を入れて、一度だけ走らせてみてください。出てきた日付が、いまの「1 週間」とどれだけ離れているか。その差を知るところから、始めていただければと思います。