
// 簡報
推出應用程式就像開餐廳——你只有一次機會留下好的第一印象。倉促上架,遺漏要求、留有安全漏洞或性能欠佳,可以毀掉數月的開發成果,損害品牌聲譽。
我們見過無數應用程式因為創辦人跳過關鍵的上架前步驟,被應用商店拒絕,或收到毀滅性的差評。好消息是?只要準備充分,絕大部分上架失敗都完全可以避免。
這份全面的檢查清單涵蓋提交應用程式前需要核實的一切。按照這些步驟,確保順利上架、獲得好評,並從第一天起穩健增長。
01/05
商店要求與合規
應用商店元數據要求
iOS App Store
- 應用程式名稱(上限 30 個字符)
- 副標題(上限 30 個字符)
- 關鍵詞(上限 100 個字符)
- 描述(上限 4000 個字符)
- 截圖(6.5"、6.7"、12.9" 尺寸)
- 應用程式預覽影片(可選)
- 應用程式圖標(1024x1024px)
Google Play Store
- 應用程式標題(上限 50 個字符)
- 簡短描述(上限 80 個字符)
- 完整描述(上限 4000 個字符)
- 截圖(手機、平板、TV)
- 宣傳圖片(1024x500px)
- 應用程式圖標(512x512px)
- 內容分級問卷
法律文件檢查清單
- 私隱政策: 所有應用程式均須提供,並必須可透過 URL 存取
- 服務條款: 列明應用程式使用條款的法律協議
- 資料刪除政策: GDPR 合規及應用商店指引均有此要求
年齡分級與內容指引
重要:請如實準確填寫年齡分級問卷。分級不正確可能導致應用程式被下架或分發受限。
02/05
技術就緒
應用程式簽名與證書
signing_setup.sh
# iOS Certificate Setup
# 1. Create App ID in Apple Developer Console
# 2. Generate Distribution Certificate
# 3. Create Provisioning Profile for App Store
# Flutter iOS build configuration
flutter build ios --release --no-codesign
# Then sign in Xcode with proper certificates
# Android Signing Setup
# 1. Generate keystore file
keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
# 2. Configure android/key.properties
storePassword=your_store_password
keyPassword=your_key_password
keyAlias=key
storeFile=../key.jks
# 3. Update android/app/build.gradle
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}後端配置
- 環境變數: 將開發、預發佈及生產環境的配置分開管理
- API 端點: 核實所有端點均指向生產伺服器
- 數據庫遷移: 執行並測試所有生產數據庫遷移
API 安全檢查清單
- 所有 API 端點均已啟用 HTTPS
- 已實施 API 速率限制
- 身份驗證令牌已妥善保護
- 已啟用輸入驗證及清理
03/05
性能與安全
性能基準測試
性能目標
- 應用程式啟動時間:少於 3 秒
- 畫面切換:少於 300ms
- 記憶體佔用:少於 100MB
- 耗電量:影響輕微
- 網絡請求:少於 5 秒
安全審計
- 靜態資料加密
- 資料傳輸安全
- 身份驗證安全
- API 漏洞掃描
- 已啟用代碼混淆
錯誤處理與監控
main.dart
// Flutter error handling setup
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Firebase Crashlytics
await Firebase.initializeApp();
// Catch Flutter framework errors
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};
// Catch async errors
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(MyApp());
}
// Global error boundary
class ErrorBoundary extends StatelessWidget {
final Widget child;
const ErrorBoundary({required this.child});
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, widget) {
ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
return CustomErrorWidget(errorDetails: errorDetails);
};
return widget!;
},
home: child,
);
}
}04/05
測試與品質保證
跨裝置測試矩陣
iOS 測試
- iPhone SE(小屏幕)
- iPhone 15(標準)
- iPhone 15 Pro Max(大屏幕)
- iPad(平板佈局)
- iPad Pro(大尺寸平板)
- iOS 16、17、18 版本
Android 測試
- Samsung Galaxy S 系列
- Google Pixel 裝置
- OnePlus 旗艦型號
- 入門級 Android 裝置
- 平板形態裝置
- Android 12、13、14 版本
網絡與極端情況測試
- 網絡環境: 在 WiFi、4G、3G 及離線情景下進行測試
- 屏幕方向切換: 核實直向及橫向模式均正常運作
- 前後台切換: 測試應用程式進入後台及返回前台時的行為
用戶驗收測試
專業貼士:招募 10 至 20 位符合目標受眾的 beta 測試員。新鮮的目光往往能發現開發者埋首數月後忽略的問題。
05/05
分析與監控
必要的分析設定
analytics_service.dart
// Firebase Analytics setup
import 'package:firebase_analytics/firebase_analytics.dart';
class AnalyticsService {
static FirebaseAnalytics analytics = FirebaseAnalytics.instance;
// Track key user events
static Future<void> trackAppOpen() async {
await analytics.logAppOpen();
}
static Future<void> trackScreenView(String screenName) async {
await analytics.logScreenView(screenName: screenName);
}
static Future<void> trackUserAction(String action, Map<String, dynamic> parameters) async {
await analytics.logEvent(name: action, parameters: parameters);
}
static Future<void> trackPurchase(double value, String currency, String itemId) async {
await analytics.logPurchase(
currency: currency,
value: value,
parameters: {'item_id': itemId},
);
}
static Future<void> setUserProperties(String userId, Map<String, String> properties) async {
await analytics.setUserId(id: userId);
for (var entry in properties.entries) {
await analytics.setUserProperty(name: entry.key, value: entry.value);
}
}
}
// Usage in app
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
AnalyticsService.trackScreenView('home_screen');
}
void _onButtonPressed() {
AnalyticsService.trackUserAction('button_pressed', {
'button_name': 'get_started',
'screen': 'home',
});
}
}推送通知測試
- 在兩個平台上測試通知送達
- 核實從通知開啟的 deep link 正常運作
- 測試通知權限流程
付款流程核實
- 測試付款成功的情景
- 測試付款失敗的處理
- 核實收據驗證正常運作
須避免的常見陷阱
- 元數據缺失: 商店資料不完整會拖延審批
- 測試不足: 只在旗艦裝置上測試會遺漏問題
- 後端擴容: 開發伺服器無法承受上架後的流量
- 私隱疏忽: 缺少私隱政策會即時被拒
- 沒有錯誤監控: 看不見的問題就無法修復
- 時間表過急: 請為應用商店審核預留 2 至 7 天


