Try   HackMD

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.xmlandroid:label="XXXX" 設置 APP 的顯示名稱
    • IOS: 用 Xcode 開啟檔案 ios/Runner.xcworkspace,點擊左側 Runner,在 identity 裡面的 Display Name 設置 APP 的顯示名稱
  • 設置需要的權限
  • 設定應用程式執行所需 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 區塊下面添加一段設置內容
如下:

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-hdpidrawable-mdpidrawable-xhdpidrawable-xxhdpidrawable-xxxhdpi

  2. 設置 splash 畫面
    android/app/src/main/res/drawable/launch_background.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 檔案內容

  1. 設置 splash 畫面的背景顏色參數
    android/app/src/main/res/values/colors.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>
  1. 使用安卓模擬器開啟 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] # 看到這邊就表示創建完成了
    

    附上 二位國家代碼查詢網站 (感謝谷歌大神🙏)

  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 進行發布設置即可