--- tags: Flutter --- # Flutter 之發布 APP 到商店中 在完成一個可完整使用的應用程式後 就可以開始進行發布的動作了 發布一個 APP 的程序主要如下: 1. 測試與優化性能 2. 確認 APP 的配置 ## 測試與優化性能 ### 測試 - 在安卓模擬器與 IOS 模擬器中測試 - 這邊要注意有些功能在模擬器中無法進行測試,比如 IOS 模擬器就無法拍照等等 - 連結真實設備進行測試(如有平板或不同尺寸、不同新舊版本的設備,盡可能都拿來測試一輪) - 確認樣式是否有問題 - 按鈕放置在畫面正下方時,於 IOS 設備上是否會被切邊 - 當文字長度過長時是否會自動換行或出現 overflow 的警告 - 確認運行狀況是否良好 - 速度是否夠快、會不會卡頓 - 是否有出現任何功能上的錯誤 ### 優化 - 可以使用 const 宣告不被重構的內容一律都加上 const - 較大的小部件可嘗試進行有意義的拆分,讓小部件盡可能的縮小 ## 確認 APP 配置 - 確認 APP 的 ID 是否為唯一值,更改方式有以下幾種 1. 在創建 flutter 項目,通過指令設定 ID 前綴: `flutter create appname --org com.{yourname or companyname}` 2. IOS 開啟 Xcode 到 `Signing & Capabilities` 中重設 Bundle identifier 3. android 開啟&更改以下檔案: - `android/app/build.gradle` => `defaultConfig` 更改 `applicationId` - `android/app/src/debug/AndroidManifest.xml` 更改 `package="..."` - `android/app/src/main/AndroidManifest.xml` 更改 `package="..."` - `android/app/src/main/kotlin/com/example/flutter_meals_app/MainActivity.kt` 更改 package - `android/app/src/profile/AndroidManifest.xml` 更改 `package="..."` - 設置 APP 的顯示名稱 - android: 開啟檔案 `android/app/src/main/AndroidManifest.xml` 於 `android:label="XXXX"` 設置 APP 的顯示名稱 - IOS: 用 Xcode 開啟檔案 `ios/Runner.xcworkspace`,點擊左側 `Runner`,在 identity 裡面的 Display Name 設置 APP 的顯示名稱 - 設置需要的權限 - 開啟檔案 `android/app/src/main/AndroidManifest.xml` 於 `manifest` 標籤中添加需要的權限: - 需要擁有網路連線:`<uses-permission android:name="android.permission.INTERNET"/>` - 所有權限清單:https://developer.android.com/reference/android/Manifest.permission - 設定應用程式執行所需 API 級別 - 開啟檔案 `android/app/build.gradle` 更改 `defaultConfig` 中的內容: 1. `minSdkVersion`: 指定應用程序設計運行的最低 API 級別,假設你的設備低於此級別,商店就不會讓你安裝應用 2. `targetSdkVersion`: 指定應用程序設計運行的目標 API 級別,默認值通常就是正確的不需要更改 - 確認第三方服務的設置是否完善,比如各種服務的 key 或 rules 等等 ## 為應用程式加上圖標與初始畫面 ### 設置圖標 #### 安裝及使用 flutter_launcher_icons 安裝方式: 開啟項目中的 pubspec.yaml 檔案, 於 dev_dependencies 處添加 flutter_launcher_icons: ^0.13.1 > 通常透過指令安裝的 package 會被放置在 dependencies 中 > 而放置在 dev_dependencies 中的 package,則表示只會在開發模式下使用 設置方式: 開啟項目中的 pubspec.yaml 檔案, 於 dev_dependencies 區塊下面添加一段設置內容 如下: ```yaml= dev_dependencies: flutter_lints: ^2.0.1 flutter_test: sdk: flutter flutter_launcher_icons: ^0.13.1 flutter_launcher_icons: # 設置 flutter_launcher_icons 套件內容 android: true # 告知 flutter_launcher_icons 要創建安卓的圖標 ios: true # 告知 flutter_launcher_icons 要創建 IOS 的圖標 image_path: "assets/images/icon.png" # 設定圖標檔案(開圖尺寸 432x432px 內容尺寸 230x230px) adaptive_icon_background: "#ffffff" # 針對安卓設置圖標背景顏色(也可以是一張圖片),假設安卓手機有套用主題,則可以自適應產生新的圖標 adaptive_icon_foreground: "assets/images/icon_adaptive.png" # 針對安卓設置無背景的圖標檔案,自適應圖標(開圖尺寸 432x432px 內容尺寸 164x164px) remove_alpha_ios: true # 針對 IOS 設置移除透明度 ``` 接著於終端機開啟項目, 執行命令 `https://pub.dev/packages/flutter_launcher_icons` 即可 最後就可以開啟 IOS 與安卓模擬器確認是否有成功顯示圖標囉! ### 設置初始畫面 #### Android 1. 製作要用的 splash_icon: 用剛才製作的 icon 另外生成一個 1024x1024px 的大小 將圖片存為 `splash_icon.png` 檔案 並放置到以下五個資料夾中: `drawable-hdpi` 、 `drawable-mdpi` 、 `drawable-xhdpi` 、 `drawable-xxhdpi` 、 `drawable-xxxhdpi` 2. 設置 splash 畫面 將 `android/app/src/main/res/drawable/launch_background.xml` 檔案更改為: ```xml= <?xml version="1.0" encoding="utf-8"?> <!-- Modify this file to customize your launch splash screen --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <!-- 新增一個 item --> <color android:color="@color/splash_background" /> <!-- 新增這行,設置 splash 畫面的背景色為顏色參數 splash_background --> </item> <!-- You can insert your own image assets here --> <item> <!-- 註解打開 --> <bitmap android:gravity="center" android:src="@mipmap/launch_image" /> <!-- @mipmap/launch_image 改為 @drawable/splash_icon --> </item> </layer-list> ``` 接著將檔案內容全部拷貝,覆蓋原本的 `android/app/src/main/res/drawable-v21/launch_background.xml` 檔案內容 3. 設置 splash 畫面的背景顏色參數 將 `android/app/src/main/res/values/colors.xml` 檔案更改為: ```xml= <?xml version="1.0" encoding="utf-8"?> <resources> <color name="ic_launcher_background">#8BC34A</color> <color name="splash_background">#8BC34A</color> <!-- 新增這行,設置新的顏色參數 splash_background --> </resources> ``` 4. 使用安卓模擬器開啟 APP 確認是否正確顯示 splash 畫面(如果看不到,請先在模擬器中將自己的 APP 解除安裝再重新啟動) #### IOS 1. 製作要用的 splash_icon: 用剛才製作的 icon 生成: 512x512px 大小的圖片,存為 `splash_icon3x.png` 檔案 256x256px 大小的圖片,存為 `splash_icon2x.png` 檔案 64x64px 大小的圖片,存為 `splash_icon1x.png` 檔案 2. 上傳 icon 用 Xcode 開啟專案項目中的 ios/Runner.xcworkspace 開啟 Runner/Runner/Assets,點選 LaunchImage 將剛才製作的三個檔案依照檔名分別對應上傳至 1x 、 2x 、 3x 中 3. 連結真實 iPhone 進行測試 將 iPhone 連結你的電腦 於 Xcode 中選取你的 iPhone 裝置 點擊左上角的播放鍵進行編譯並啟動 APP 即可看到 splash 畫面 ## 正式發佈 APP 到商店中 ### Google Play 首先要為應用程式設置簽名,步驟如下: 1. 創建&上傳 keystore 於專案項目中執行指令: `keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload` 接著回答問題: ``` Enter keystore password: # 設置密碼 Re-enter new password: #再次輸入密碼 Enter the distinguished name. Provide a single dot (.) to leave a sub-component empty or press ENTER to use the default value in braces. What is your first and last name? # 輸入姓名 [Unknown]: Xuan Wang What is the name of your organizational unit? # 輸入職位名稱 [Unknown]: Front-end Developer What is the name of your organization? # 輸入公司或組織名稱 [Unknown]: What is the name of your City or Locality? # 所在城市或地區 [Unknown]: Taoyuan What is the name of your State or Province? # 所在州或省 [Unknown]: Taiwan What is the two-letter country code for this unit? # 輸入二位國家代碼 [Unknown]: TW Is CN=Xuan Wang, OU=Front-end Developer, O=Unknown, L=Taoyuan, ST=Taiwan, C=TW correct? # 確認資訊是否都正確,如無誤就輸入 y 進行創建;如需修改則輸入 n 會重新再問一次問題 [no]: y Generating 2,048 bit RSA key pair and self-signed certificate (SHA384withRSA) with a validity of 10,000 days for: CN=Xuan Wang, OU=Front-end Developer, O=Unknown, L=Taoyuan, ST=Taiwan, C=TW [Storing /Users/{username}/upload-keystore.jks] # 看到這邊就表示創建完成了 ``` >附上 [二位國家代碼查詢網站](https://payroll.nsysu.edu.tw/pay/rcxf_COUCODE.php?s_ENGNAME=&s_COU=) (感謝谷歌大神🙏) 2. 於 APP 中引用 keystore 創建檔案 /android/key.properties 並放入以下內容: ``` storePassword=<password from previous step> # 這邊改為稍早設置的密碼 keyPassword=<password from previous step> # 這邊再次填入密碼 keyAlias=upload storeFile=<location of the key store file, such as /Users/<user name>/upload-keystore.jks> # 這邊改為你存放 .jks 檔案的完整路徑 ``` >這邊要注意如有使用 GitHub 等儲存原始碼,請於 .gitignore 中確保加入: >`**/android/key.properties` 3. 配置 keystore 更新檔案 /android/app/build.gradel 首先在 `android { ... }` 的前一行加入以下內容: ``` def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { ... } ``` 接著往下找到內容: ``` buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, // so `flutter run --release` works. signingConfig signingConfigs.debug } } ``` 將整段用下方內容完全取代掉: ``` signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] } } buildTypes { release { signingConfig signingConfigs.release } } ``` 完成上述步驟後,發布應用程式時就會自動進行簽名了。 接著請先於項目中執行指令: `flutter clean` 清除所有緩存,確保正確執行到稍早配置的 keystore 然後執行指令: `flutter build appbundle` 建立發布應用程序用的 app bundle 最後進入 Google Play Console 網站,註冊成為開發者帳號(需支付 25 美金) 點擊建立應用程式,並按照一系列的說明進行資訊的填寫以及設置 接著可於左側選單點擊測試,選擇其中一種測試方式, 上傳你的 app bundle 檔案,檔案路徑為你的項目目錄中的: `/build/app/outputs/bundle/release/app-release.aab` ### App Store 1. 登入蘋果開發者帳號,並於此頁面新增 App IDs:https://developer.apple.com/account/resources/identifiers/list 2. 登入 App Store Connect:https://appstoreconnect.apple.com/login 3. 點擊我的 APP => 點擊+號新增 => 勾選 IOS、填入資訊 4. 開啟 Xcode 確認 Bundle ID 與應用程式名稱是否符合剛才填入的資訊內容 5. 開啟終端機輸入: `flutter build ios` 6. 終端機跑完後,將 Xcode 關閉再用 Xcode 重新打開 ios/Runner.xcworkspace 7. 於選單列點擊 Prouct>Scheme>Runner 、 Prouct>Destination>Any iOS Device 、 Prouct>Archive 8. Archive 跑完後會開啟新視窗,可進行驗證與分發,這邊點分發後回到 App Store Connect 進行發布設置即可