Store 截圖
目的
製作能提升轉換率、忠於應用程式本身,且符合商店所有尺寸規格的截圖。這些截圖由腳本產生,因此當 UI 變更時,可在幾分鐘內重新生成。
先決條件
- 一個 UI 已為此版本定案的建置。
- 應用程式中有一個擷取工具(Flutter golden/integration tests、XCUITest、Espresso/Compose 截圖測試或 Fastlane snapshot),能夠使用確定性的示範資料渲染畫面。
- Node.js 18+ 和 Chrome/Chromium 用於渲染(在
scripts/目錄下執行npm i)。 - 用於上傳的 API 憑證(
accounts-and-tax)。
原則
- 真實擷取,非模擬圖。 邊框內的每個手機畫面都必須是已發布應用程式的實際擷取。重新繪製或「美化」的 UI 會誤導使用者(違反指南 2.3)且容易過時。
- 數字必須與應用程式一致。 如果畫面顯示「1,850 步」或「12 分鐘」,應用程式必須為示範資料產生完全相同的數字。請在測試工具中產生示範資料,並在同一個測試中進行斷言。
- 如果截圖顯示了應用程式沒有的功能,請修正其中一個。 要麼實作該功能,要麼變更畫面。切勿發布有此落差的內容。
- 畫面中不得出現其他平台。 iOS 畫面上不得有 Android 狀態/導覽列,Play 商店畫面上不得有 Apple UI 或「App Store」字樣(違反指南 2.3.10)。
- 在所有語言和所有裝置上保持相同的畫面順序。
裝置矩陣
包含邏輯尺寸和 API 識別碼的完整表格:references/device-matrix.md。摘要(請參閱 Apple 截圖規格 和 Play 預覽素材):
| 尺寸 | 像素 (直向) | 必填? |
|---|---|---|
| iPhone 大型動態島 (6.9") | 1320×2868 (也支援 1290×2796、1260×2736) | 建議主要組合 |
| iPhone 中型動態島 | 1206×2622 或 1179×2556 | 至少需要一張截圖 |
| iPhone Duo 外螢幕 | 1398×2034 | 從 2027 年 4 月起,針對使用 iOS 27.1 SDK 或更新版本建置的應用程式為必填;會顯示「針對 iPhone Duo 最佳化」標章 |
| iPhone Duo 內螢幕 | 2007×2853 | 與外螢幕相同 |
| iPad 13" | 2064×2752 (或 2048×2732) | 僅在應用程式支援 iPad 時才需要(僅限 iPhone 的應用程式不需要) |
| Play 手機 | 例如 1080×1920 或 1080×2160 (短邊 320–3840 px,長邊 ≤ 2× 短邊) | 至少 2 張才能發布;建議至少 4 張且解析度 ≥ 1080 px |
| Play 7" 和 10" 平板 | 1080–7680 px,9:16 或 16:9 | 如果應用程式支援平板則建議使用 |
| Play 特色圖 | 1024×500 | 必填 |
| Play 圖示 | 512×512,32 位元 PNG | 必填 |
Apple:每個尺寸最多 10 張;PNG 或 JPEG;不可包含 Alpha 色版或透明色。Play:每種裝置類型最多 8 張;JPEG 或 24 位元 PNG(無 Alpha 色版)。
App Store 產品頁面創意素材(較新的 App Store Connect,「頁首與搜尋結果」標籤):
- 頁首:產品頁面頂部的一張寬圖,尺寸為 3840×1646 或 5244×2950。非必填(不提供仍可通過審核)。
- 搜尋結果:尺寸為 5244×2950、3840×2560 或 1920×1280;如果未提供,則使用截圖和預覽。
- 可透過版本頁面或「素材庫」(上傳創意素材)上傳,然後使用「瀏覽素材」選取。上傳至素材庫的素材可留待日後使用。
- 設計說明:商店會將其圖示、名稱和「取得」按鈕重疊顯示在頁首的一部分上,因此請在主控台預覽中檢查結果。
- 這些尺寸在版本處於「等待審查」狀態時會被鎖定。請在提交之前新增它們。
步驟
1. 規劃故事(需審核故事板)
撰寫一個包含 5-8 個畫面的故事板:一個標題(≤ 6 個詞)、一行輔助說明文字、以及一個對應的擷取畫面。可選的「全景」佈局(由附帶的範本實作):畫面是單一寬畫布的一部分,因此形狀會跨畫面邊緣連續。無論採用何種佈局,任何顯示的優惠(免費啟用、試用)都必須屬實。
2. 擷取真實畫面
以目標裝置的邏輯尺寸 × 像素比例擷取每個畫面,確保文字和佈局與該裝置顯示的完全一致。Flutter 範例(widget/golden test):
// 6.9" iPhone:440 x 956 logical points @3x = 1320 x 2868 px
tester.view.physicalSize = const Size(1320, 2868);
tester.view.devicePixelRatio = 3.0;
await tester.pumpWidget(App(demo: DemoData.storeShots(locale: 'en')));
await tester.pumpAndSettle();
expect(find.text('1,850 steps'), findsOneWidget); // 標題中的數字是真實的
await expectLater(find.byType(App), matchesGoldenFile('captures/en/iphone69/01_home.png'));
- 在測試中載入字型(否則測試字型會顯示為方塊)。
- 使用固定的時鐘、固定的示範資料,且不依賴網路。
- 隱藏除錯橫幅;將狀態列設定為乾淨狀態(或將其裁切掉,不繪製任何狀態列)。
- 分別為每個語言環境進行擷取;切勿在地區化的畫面上放置英文 UI。
3. 合成畫面
範本:templates/panorama.html,渲染器:scripts/render.mjs。
cd scripts && npm i
node render.mjs ../templates/frames.example.json out/
渲染器會將所有畫面放置在同一個畫布上(寬度 = 畫面數量 × 單一畫面寬度),載入擷取的畫面,等待字型載入,然後以精確的像素大小為每個畫面切片(針對組態中的每個裝置)進行截圖。它也會渲染 1024×500 的特色圖。
4. 檢查
node check-images.mjs out/
檢查失敗的情況包括:該裝置資料夾的尺寸錯誤、存在 Alpha 色版(PNG 色彩類型 4/6 或 tRNS 區塊)、檔案超過 10 個(Apple)/ 8 個(Play)、編號不連續。然後以 100% 縮放比例檢視每張圖片:檢查是否有文字被截斷、其他平台的 UI、佔位符字串、過時的數字。
5. 透過 API 上傳(取代現有截圖集前需經審核)
- App Store Connect — scripts/upload-asc.mjs:找到可編輯的
appStoreVersion→ 其appStoreVersionLocalizations→ 對應screenshotDisplayType的appScreenshotSets→ 刪除舊的截圖 → 保留 (POST /v1/appScreenshots,包含fileName、fileSize) → 從uploadOperations上傳各區塊 → 提交 (PATCH,設定uploaded: true和 MD5sourceFileChecksum) → 在該組合的appScreenshots關聯上設定順序。文件:Uploading assets。 - Google Play — scripts/upload-play.mjs:
edits.insert→ 針對每個語言和圖片類型執行edits.images.deleteall→ 依序執行edits.images.upload(phoneScreenshots、sevenInchScreenshots、tenInchScreenshots、featureGraphic) →edits.commit。文件:edits.images.upload。
兩個腳本預設皆為乾執行模式;設定 DRY_RUN=0 以寫入實際資料。
6. 回讀確認
列出每個語言和裝置(兩個 API)上傳的素材,並比對本機資料夾中的數量和順序。Apple 非同步處理上傳;請等到每個素材都回報 COMPLETE 傳遞狀態。
需要人工審核的決策點
故事板和標題、最終視覺方向、取代現有的截圖集、提交 Play 編輯。
驗證
check-images.mjs通過;每個必要的 Apple 尺寸至少有一張圖片;Play 有手機截圖和特色圖。- 回讀的順序相符;沒有失敗的素材狀態。
- 畫面中的每個數字和功能都已與建置版本進行比對。
常見陷阱
- 僅上傳 6.9" 尺寸,遺漏了必填的中型動態島尺寸。
- 匯出的 PNG 包含 Alpha 色版(常見於設計工具和具有透明背景的無頭瀏覽器——務必設定不透明的主體背景)。
- 在 Play 上使用 6.9" 的 1320×2868 圖片:其長寬比超過 Play 的 2:1 限制;請渲染 Play 專用的尺寸。
- 為僅限 iPhone 的應用程式製作 iPad 截圖(不需要)——或者當應用程式確實在 iPad 上執行時卻缺少 iPad 截圖。
- 畫面顯示了應用程式沒有的設定列或結果。
- 標題已翻譯,但擷取的畫面仍顯示英文。