2026 年 8 月附註:這篇文章來自較早的版本,描述的是當時的方案架構。AlcoLog 在 v1.2.0 把 Pro 方案併入 Premium,所以現在只有一種付費方案。合併過程中沒有任何功能消失,原本使用 Pro 的人都已免費轉為 Premium。
如果你即將上架一款 v1.0 的 iOS App,裡面有訂閱、App 內購買項目、Apple Watch 配套 App、小工具,或任何和健康沾上邊的定位,那麼 App 審查的過程會比官方文件暗示的更難。這篇文章記錄了一次上架循環(五天內退件四次、五位審查人員、同一個版本),以及讓這個循環撐得過去的一些規律。我寫出來,是因為這段經歷是認真做獨立 App 時最少人記錄的部分之一,而有文件可查的版本(WWDC 講座、審查指南頁面、開發者論壇)和日常的實際情況並不相符。
如果你正卡在循環中間、想找能立刻用上的修正方法,可以直接跳到「送審前該先修好的事」和「值得理解的規律」。想了解來龍去脈的話,個人時間軸在後半段。
# 送審前該先修好的事
以下是四次退件中出現過的項目。如果事先修好,對一款有訂閱的敏感類別 v1.0 App 來說,大部分可能被退件的地方就都處理掉了。
# 訂閱付費牆上的價格顯示層級
Apple 的人機介面指南對訂閱價格的呈現方式講得很清楚:實際扣款金額必須是最醒目的價格元素。行銷直覺(讓折扣看起來像是賺到)在這裡是錯的,合規直覺(讓扣款金額成為版面上的主角)才是對的。
實際上的意思是:原價應該是最大、最粗的元素。首期優惠或折扣價應該比較小,並明確標示「首期:」。避免在小標籤上用百分比徽章(寫「上市優惠」,不要寫「25% OFF」)。各個審查人員對 3.1.2©「付款與訂閱」在這一點上的執行相當一致。
# 明確的資料刪除途徑
就算你的「帳號」只是一個選擇加入的匿名識別碼,Apple 的 5.1.1(v) 也要求提供有標示、看得見、立即生效的刪除途徑。把「關閉開關」當作隱含的刪除,從開發者的角度看似乎合規,但不符合目前的執行標準。
從第一個版本開始,就在隱私或設定畫面放一個明確的「刪除我的資料」按鈕,加上確認提示。確認周圍的說明文字描述的是實際的刪除行為,而不是你打算以後再改的暫定時程。
# 檢查 Info.plist 裡殘留的宣告
背景模式、背景擷取、位置權限、HealthKit 宣告,以及類似的 Info.plist 項目,可能在程式碼不斷迭代的過程中閒置好幾個月。當它們和實際功能對不上時,就會被標記出來。2.5.4「軟體需求」在這方面的執行很機械,也毫不含糊。
具體來說:每一個 UIBackgroundModes 項目都必須對應到真正會用到它的功能。如果你的 App 把「location」宣告為背景模式,但從來沒有使用持續的背景定位,而且設定了 allowsBackgroundLocationUpdates = false,就把這個宣告拿掉。區域監控並不需要它。檢查只要十分鐘,就能省下一輪退件。
# App Store 中繼資料裡要有可用的使用條款連結
App Store Connect 裡的隱私權政策欄位大家都知道,使用條款的要求就比較少人知道了。如果你使用 Apple 的標準 EULA,請在 App 描述中放上使用條款的連結。如果你使用自訂的 EULA,請把它加到 App Store Connect 的自訂 EULA 欄位。
條款頁面本身應該揭露所有付費產品,包括訂閱期間、價格和續訂方式。大多數團隊把這些資訊分散在不同頁面,或埋在隱私權政策裡。把它們整合成一個審查人員兩分鐘就能讀完的條款頁面。
# App 預覽影片:使用原始的螢幕錄影
3D 手機模型、裝置外框和風格化的行銷畫面,依 2.3.4「準確的中繼資料」由審查人員自行判斷。公開的指引頁面並沒有明確禁止裝置外框,但審查人員依據的內部訓練資料似乎有。原生解析度的純螢幕錄影,則毫無疑問是安全的。
行銷包裝留給你自己的網站、社群媒體和 Reddit。App 預覽欄位就放螢幕錄影。「精美模型預覽」和「原始螢幕錄影預覽」之間的轉換率差異很小,降低的風險卻很大。
# 在 App 審查備註中寫明 App 內購買項目的操作路徑
審查人員每款 App 的時間預算大約是 5 到 15 分鐘。他們不一定能找到這個版本附帶的每一個 App 內購買項目。如果你的內購項目要經由 App 裡不同的路徑才能找到(不同的付費牆、不同的卡片、較深的層級),請在 App 審查備註中,為每一個內購項目寫出逐步點選的操作路徑。
行得通的格式:
Premium 訂閱與終身版內購:「設定」分頁 > Premium 卡片 > 「取得 Premium」按鈕 > Premium 升級頁面 Pro 訂閱與終身版內購:「設定」分頁 > Pro 卡片 > 「取得 Pro」按鈕 消耗型小費罐項目:「設定」分頁 > 捲過方案卡片 > 小費罐卡片 > 「顯示小費選項」
這聽起來有點過頭。但它能避免一種特定的退件循環(2.1(b) 需要更多資訊),不然就要多花一天。
# 送審和對外承諾的上架日期之間要留緩衝
對一款有訂閱、屬於敏感類別的 v1.0 送審,從第一次送審到你對外承諾的上架日期,至少要預留七個日曆天。只要你回應得快,每一輪退件循環大約是 24 小時。對敏感類別的 v1.0 送審來說,四輪退件是實際可能發生的最壞情況。
如果你的上架日期已經對外承諾(設定了預購、排定了 App 內活動、訂好了行銷檔期、向記者推銷過),七天緩衝是最低限度,十天比較安心。少於七天,你就有可能因為一次程序性的退件而錯過日期。
# 值得理解的規律
以下是一些在循環裡觀察到、從官方文件看不出來的事。
# 每次退件找到的東西都不一樣
四次退件標記的項目完全沒有重疊。每一位審查人員都能看到前一位已經放行的每個畫面。第一位標記了中繼資料裡的 EULA 連結。第二位在同一個版本裡標記了三個不同的項目(背景模式、價格顯示、刪除按鈕)。第三位標記了一個行銷素材。第四位問了一個操作路徑的問題。
這不是錯誤,而是 App 審查結構本身的特性。審查似乎是以問題為單位,而不是以 App 為單位。審查人員在時間預算內找到第一個重大問題就會停下來。他們不需要做完整的稽核,系統也不會把前一位審查人員接受過的部分標為「先前已放行」。這個結構重視的是機構的處理量,而不是開發者的體驗。
這代表:你不可能從任何單一一次審查得到完整的稽核結果。你只能得到當下這位審查人員在時限內發現的問題,而且必須接受下一位審查人員可能在下一輪獨立找出其他任何問題。
# 每次退件的範圍往往比上一次小
這是一個大致的規律,不是保證。第一次退件通常比較實質(缺少某項必要條件、架構上的問題)。第二次仍然實質,但比較像清單檢查。第三次會偏向周邊的中繼資料。第四次有時根本不是退件,而是程序上的提問。
原因不是 App 每一輪都在「變好」,而是版本和中繼資料中可以審查的範圍,隨著先前被標記的項目修好、先前放行的項目不再列入範圍,而一輪一輪縮小。審查人員各自在消耗可檢查的清單範圍,所以越後面的審查能找到的東西就越少。
身在循環中時,這個規律讓人比較安心,但不要把它當成保證。後期的審查人員仍然可能找出前面的人漏掉的實質問題。
# 審查人員的仔細程度差異極大
同一個版本的四次審查,每位審查人員找到的問題差異相當大。一位找到三個項目,另一位找到一個周邊項目,第三位問的問題,只要在 App 第二個分頁裡點一張卡片就能找到答案。
你無法影響哪一位審查人員會拿到你這一輪的送審。為這種差異做好準備。不要以為下一輪會比上一輪更仔細或更寬鬆,它們是從一個分布很廣的母體裡獨立抽出的樣本。
# Beta 版 App 審查通過,不代表正式 App 審查會通過
這兩條流程由不同的團隊負責,標準也不同。同樣的功能在 Beta 版審查通過、在正式審查被標記,並不矛盾,那是兩個不同的審查流程。
如果你用 TestFlight 來確認能否通過正式審查,那你看的是錯誤的訊號。TestFlight 抓的是版本有效性和基本的合規問題,正式的 App 審查涵蓋完整的執行範圍。兩者不能互相替代。
# 敏感類別的審查重點會疊加
訂閱,尤其是有首期優惠價或試用的訂閱,會自動觸發 3.1.2 的審查。和健康相關的類別(酒精、健身、心理健康、睡眠)會讓審查人員注意 1.4.1 的醫療宣稱問題。涉及隱私的功能(位置、HealthKit、匿名識別碼)會觸發 5.1.1 的嚴格檢查。第一版的 v1.0 送審會觸發完整審查。和上架日期綁在一起的 App 內活動會觸發中繼資料的檢查。
每一項單獨來看都還應付得來,但它們是以倍數疊加的。一款屬於敏感類別、有訂閱、跨多個平台、還有 App 內活動的認真上架,會讓每一項同時啟動。一款沒有內購、只有單一畫面的免費工具,兩分鐘就審完了。你的審查經驗有多難,和你這次上架有多認真、範圍有多廣相關,而不是和你 App 的品質相關。
# 文件和實際執行不一定完全一致
一次退件引用的指引,可能沒有明確出現在所附連結的公開頁面上。審查人員依據的內部訓練資料和公開的審查指南有重疊,但不完全相同。如果你遇到和公開文件對不上的退件,可以禮貌地提出異議。有時候會被撤回,有時候不會。
提出異議時,請在解決方案中心以書面方式進行,用一段有條理的文字引用公開指引,並請對方說明具體適用的是哪一條。用字避免流露挫折感。審查人員是在時間預算內讀你的回覆,會被仔細閱讀的,是尊重這一點的回覆。
# 如何有建設性地回應退件
關於在解決方案中心往返溝通的一些實用建議。
# 能當天回覆就當天回覆
脫離循環最快的方法,就是讓循環持續往前走。你一回覆,每一輪退件的計時就重新開始。當天回覆,通常同一週就能解決;拖好幾天才回,循環就等比例拉長。
這需要你的團隊能快速推出修正。對獨立開發者來說,這通常代表送審後那幾天要把行程清空。送審期間不能當成背景工作來處理。
# 把所有修正整合在同一次重新送審
如果一次退件標記了三個項目,就把三個都修好再重新送審。不要回覆「三個修好兩個,第三個還在處理」。下一位審查人員會找出完全不同的項目,只修一部分的回覆只會讓佇列多出一輪。
# 附上驗證修正的螢幕錄影
對任何不簡單的修正,附上一段 30 秒的螢幕錄影,展示修正後的實際運作:刪除流程、修正後的價格顯示、新的操作路徑。如果審查人員不用自己點進去就能看到修正,下一輪就更有可能放行。
# 在回覆中請求完整審查
禮貌地請對方在這一輪一次提出所有剩下的疑慮,而不是分散到更多輪,這個要求是合理的。不一定有用,但偶爾有用。措辭很重要:「目前提出的每一個問題,我們都已迅速且誠懇地處理。懇請在這一輪依所有適用的指南進行完整審查,以減少後續的循環。」
這讓審查人員的下一次回覆,要嘛直接放行,要嘛列出所有剩下的疑慮。兩種結果都比再來一次單一問題的退件好。
# 把每一輪都當成獨立的
你會忍不住以為下一位審查人員讀過前一位的備註。他們大概沒有。每一則解決方案中心的回覆都應該能獨立成立,為沒看過先前對話的人總結這次送審的狀態。
這代表每一輪之間需要一點重複。對第一位審查人員有效的詳細 App 審查備註,應該為第三位審查人員重新附上或重新說明。不要假設機構有記憶。
# 個人時間軸
為了讓你了解來龍去脈,以下是那五天實際的樣子。
我在星期六下午送出第 22 版。這次送審包含 4 個自動續訂的訂閱、2 個非消耗型終身版內購項目、5 個消耗型小費罐項目、App 描述、截圖、App 預覽影片、一個和上架週綁在一起的 App 內活動,以及在 175 個國家設定、以上架日期為準的預購。
在那之前的六週,我有系統地排除每一個我能預料到的問題。App 審查備註已經寫好,用審查人員容易理解的方式,說明 App 裡最可能引起關注的部分。DSA 交易者資訊一週前就核准了。App 隱私權「營養標示」已經上線。Beta 版 App 審查已經通過好幾個版本。我覺得準備好了。
第 2 天,上午 5:15:第一次退件。3.1.2©。App Store 中繼資料裡缺少可用的使用條款連結。當天就推出修正(在 App 內的升級頁面加上條款連結、擴充條款頁面以揭露所有付費產品、更新 App 描述)。循環一天。
第 4 天,下午 4:03:第二次退件。一則訊息裡有三個項目。2.5.4(UIBackgroundModes 裡殘留一個不該存在的「location」項目)。3.1.2©(首期優惠價顯示得比實際扣款金額還醒目)。5.1.1(v)(關閉匿名識別碼的開關還不夠,需要一個有明確標示的刪除按鈕)。當天就推出修正(移除 Info.plist 項目、把價格層級反過來、加上一個有確認提示的「刪除匿名資料」按鈕)。循環一天。
第 5 天,下午 5:05:第三次退件。2.3.4「準確的中繼資料」。App 預覽影片用 3D 手機模型展示 App 的畫面。審查人員的備註指出內容沒有「充分展示 App 的實際使用情形」,並特別點名裝置外框。
難處在於:developer.apple.com/app-store/app-previews/ 的公開指引頁面並沒有明確禁止裝置外框。最接近的成文規則是「保持在 App 內」,舉的例子是從肩膀後方拍攝的畫面,以及和裝置的實體互動。兩者都不適用。
距離上架只剩四天,而且已經累積延誤四天,我決定取捨。移除 App 預覽影片,讓重新送審不再卡住。禮貌地詢問,如果有我漏掉的具體指南條款,能否重新考量。另外送出一段禮貌、有條理的文字,請對方在這一輪一次提出所有剩下的疑慮。App 預覽影片的移除維持原狀,重新考量的請求沒有得到直接回覆。
第 6 天,晚上 7:23:第四則訊息。2.1(b) 需要更多資訊。嚴格來說不是退件,而是暫停審查來提問。審查人員找不到這個版本附帶的其中兩個內購項目,問要去哪裡找。
他們附上的截圖正確顯示了第一個付費牆。第二個付費牆就在同一個設定畫面上,只要點一下審查人員已經成功點進去的那張卡片正下方的卡片就能看到。我在一小時內回覆,為全部 11 個內購項目寫出明確的逐步操作路徑。
第 7 天,晚上 8:30:核准。版本放行,預購啟動,上架週定在 5 月 11 日。
那五天很緊繃。回頭看,沒有一天是生死關頭,雖然身在循環中時並不這麼覺得。累積的延誤差點讓上架日期不保,但終究沒有。實際上架的產品,和送審前做好的完全一樣。沒有任何功能為了通過審查而被砍掉、修改或延後。
# 沒被標記的部分,同樣透露了很多
四次審查中,我花最多時間擔心的部分,一次都沒被標記。
習慣評分功能(一個 0 到 100 的分數,由六個加權面向的加分和扣分因素組成)。藥物追蹤功能(只有記錄,不提供任何建議)。隱私模式(沒有帳號、資料留在裝置上、選擇加入的匿名分享並附有明確的刪除功能)。寫入 HealthKit。這些部分,也就是 App 裡最可能引發健康宣稱或隱私疑慮的地方,在四次審查中一次都沒被標記。四位獨立的審查人員都看過,也都選擇不標記。
這對做敏感類別 App 的人的意義是:主動揭露的功夫是有用的。說明方法的 App 審查備註、App 內的免責聲明、謹慎的命名、App 描述裡保守的措辭。這些都不光鮮,但全部都促成了連續四位審查人員選擇不標記最有爭議的部分。18 歲以上的年齡分級、首次開啟時必須看過的免責聲明頁面、相關區域裡明確寫著「我們不提供醫療建議」的文字,全都發揮了作用。
被標記的反而是程序性和機械性的部分:價格顯示層級、背景模式宣告、中繼資料裡的連結、行銷素材的畫面構成、內購項目是否容易找到。App 的實質內容每一輪都通過了。
# 給獨立開發者的最後幾點
幾個上面放不太進去的觀察。
你在 App Store 看到的那些粗糙 App,並沒有得到比較寬鬆的待遇。它們是好幾年前標準比較低的時候通過的,或者根本沒有觸發你這次認真上架會觸發的審查重點。這個系統用低度審查來回報低投入、低風險的 App。你的投入和用心,正是你的審查比較難的原因之一。這不是在評價你 App 的品質。
這個系統的人力配置,本來就給不了你想要的體驗。App 審查是一個外包人員池。審查人員每天處理幾十款 App,每款只有幾分鐘。他們接受的訓練是把審查指南當成檢查清單,而不是熟悉每一款 App 的具體使用體驗。同理心的落差是結構性的,不是針對個人。
獨立開發者的經驗記錄,終究會帶來改變。過去十年,Apple 的 App 審查已經有了實質的改善。其中一部分可以追溯到獨立開發者持續記錄自己的經歷,形成累積的壓力。你個人的一次退件,不會讓任何一位審查人員重新受訓。但獨立開發者經驗有條理的累積,終究會推動機構層面的改變。
你多半能上架你做出來的產品。我擔心可能被砍掉的每一項功能,最後都完整上架了。四次退件的循環在發生當下感覺像是生死關頭。但只要我持續清楚地回應,並且把上架期限的緩衝留在手上,實際結果就會收斂到核准。
如果你現在正卡在循環中間,熬夜守著解決方案中心:上架會發生的。繼續回應。這個系統不是針對你。產品是你的。
這篇文章記錄的是 AlcoLog 的上架過程,這是一款 iOS 飲酒記錄 App。經歷上述循環之後,AlcoLog 將於 2026 年 5 月 11 日在 App Store 上架。App 可免費使用,另有選購的 Premium 方案,現已在 175 個國家開放預購。
如果你是 iOS 開發者,想交流 App 審查的經驗,r/iOSProgramming 和 Indie Hackers 上的獨立 iOS 社群是不錯的起點。我們每個人把遇到的狀況記錄得越具體,累積起來對下一個人就越有用。