關於 iOS 批量打包的總結


 

關於 iOS 批量打包的總結

如果你曾經試過做多 target 的項目,到了測試人員要測試包的時候,你就會明白什么叫“生不如死”。雖然 Xcode 打包很方便,但是當你機械重復打 N 次包的時候,就會覺得這純粹是浪費時間的工作。所以這時候自動化打包就顯得尤為重要(其實就算只有一個 target,就算使用 Xcode 打包很方便,也應該構建自動化打包,因為你可以節省大量時間)。

構建自動化打包腳本

xcodebuild

使用 xcodebuild -h 來看看 xcodebuild 到底是干啥的

這里我只截取了 usage 部分,option 部分太多沒有截取。

這里介紹幾條畢竟常用的命令

1. xcodebuild -list …

xcodebuild -list [[-project ]|[-workspace ]] [-json]

usage: 輸出 project 中的 targets 和 configurations,或者 workspace 中 schemes。
-project 和 -workspace 是輸出指定內容,不輸入默認輸出當前目錄下。-json 是以 json 格式輸出。

example:

 

2. xcodebuild -project …

xcodebuild [-project ] [[-target ]...|-alltargets] [-configuration ] [-arch ]... [-sdk [|]] [-showBuildSettings] [=]... []...

usage:

-project: 指定 project 名字,默認首個 project。

-target: 指定對應的 target ,默認首個 target。

-configuration: 選擇Debug 或 Release,默認 Release,當然如果你有自定義的配置的,就應該選你配置的,上面 -list 中有輸出。

-showBuildSettings: 顯示工程的配置。

=: 修改工程的配置文件。

buildaction ... : 如下,默認為 build

example:

  • $ xcodebuild -project 你的項目名字.xcodeproj -target 你的 target 名字 -configuration release

這行命令表示編譯 xx.xcodeproj 的 xx target。在 terminal 中會看到編譯過程,如果成功最后會輸出 ** BUILD SUCCEEDED **。最后會在當前目錄下生成 build/Release-iphoneos/xx.app

  • $ xcodebuild -project 你的項目名字.xcodeproj -target 你的 target 名字 -configuration release -showBuildSettings

這行命令使用 -showBuildSettings 是不會 build 項目的,只是輸出工程的配置。這里輸出的的內容有(內容過多,只截取部分)

如果要修改配置文件,就直接最命令最后加上你要修改的內容。
例如在這行命令最后加上指定證書

  • $ xcodebuild -project 你的項目名字.xcodeproj -target 你的 target 名字 -configuration release PROVISIONING_PROFILE="你證書的id"

其中的字段是上面 -showBuildSettings 顯示的字段,也可以看官網介紹

3. xcodebuild -workspace …

xcodebuild -workspace -scheme [-destination ]... [-configuration ] [-arch ]... [-sdk [|]] [-showBuildSettings] [=]... []...

除了 workspace 和 scheme 之外其余選項都和上條命令相同。

-workspace: 指定 workspace 名字,默認首個 workspace

-scheme: 指定對應的 scheme ,默認首個 scheme

4 . xcodebuild -exportArchive …

這里順便介紹一下 archive 命令,因為在下面使用 PackageApplication 會出一個警告說推薦使用 -exportArchive。所以我們就來嘗試一下使用 archive 來生成 app。

首先使用一下命令來生成 .xcarchive 文件
xcodebuild archive -workspace xx.xcworkspace -scheme xx -archivePath xx.xcarchive
可以看出添加上 archive 命令和最后加入 -archivePath 生成archivePath的路徑即可。
然后該路徑下會生成一個 xx.archivePath,里面包括三個文件,xx.app.dsym文件(可用於bugly等監控bug的平台),info.plist(保存打包的一些信息),還有我們的 xx.app 文件。

其次使用 -exportArchive 生成 ipa 包

xcodebuild -exportArchive -archivePath xx.xcarchive -exportPath xx -exportFormat ipa

-archivePath: xx.archivePath 的路徑

-exportPath: 輸出路徑

-exportFormat: 生成類型,這里選擇我們需要的 ipa

這樣就利用我們的 xcodebuild 命令來生成 ipa 包

xcrun

這里也使用 xcrun 來生成 ipa 包即可

xcrun -sdk iphoneos PackageApplication build/Release-iphoneos/xx.app -o ~/Desktop/xx.ipa

但是,在 macos10.12 和 Xcode8 的環境下會出現一個警告

warning: PackageApplication is deprecated, use xcodebuild -exportArchive instead.

說明 PackageApplication 已經被棄用了。

不過其實這一步可以幾乎等價於將 xx.app 放入一個 payload 的文件夾下然后壓縮文件夾為 xx.ipa,當然這樣做缺失一些信息,不過並不影響程序的運行。

初步小結

綜上,我們有兩種方法來生成我們需要的 ipa 包。

  1. 使用 xcodebuild 命令來編譯我們的項目生成 app,然后再用 xcrun 將 app 轉 ipa。
  2. 使用 xcodebuild archive 命令來直接生成我們需要的 ipa。

雖然現在網上幾乎都是使用 xcodebuild + xcrun 來來生成 ipa 包,不過既然官方說 PackageApplication is deprecated,那還是推薦使用第二種方法,一步到位。

自動化打包正式開始

這里從我工作室的一個項目切入,這個項目需要最終生成 18 個 ipa 包,但是他們幾乎是共用一套代碼的,不同的地方在於bundleName/bundleDisplayName/bundleid 等,以及一些資源文件的不同,例如 icon 等。所以可想而知如果選擇手動打包的痛苦,並且當你打包到一半發現某個地方錯了要重新打包 ……

這里說一下自動化打包1.0解決思路:

  1. 使用命令 defaults write 來修改項目中的 plist 文件,來達到修改 bundleName/bundleDisplayName/bundleid… 的目的。
  2. 使用命令 cp 來替換資源文件。
  3. 使用 xcodebuild -workspace .. 編譯出 app 包。
  4. 使用 xcrun ... 生成 ipa 。

這是我最開始想到的思路,最終運行時間大概為每個包2.5m(時間主要浪費在編譯),然后一套下來也要半個多小時。雖然比起手動打快了不少,但還是太慢了。畢竟自動化的目的不僅僅是自動,還要速度。

既然問題出在編譯上,那我的思路就往編譯一次多次使用這個方向上面思考。然后想到了既然只是資源文件和plist的不同,沒有涉及到代碼的更換(不過這個項目后期不同 app 會執行不同一套代碼,不過也有解決辦法),這里就出現了自動化打包2.0的版本。

  1. 使用 xcodebuild -workspace .. 編譯出 app 包。
  2. 使用命令 defaults write 來修改項目中的 plist 文件,來達到修改 bundleName/bundleDisplayName/bundleid… 的目的。
  3. 使用命令 cp 來替換資源文件。
  4. 重簽名 codesign -f -s "iPhone Distribution: xx co., LTD" --entitlements $Entitlements $ipaPath/Payload/YouXiaoYun.app
  5. 使用 xcrun ... 生成 ipa 。

和1.0大致相似,不過並不是每次生成 ipa 都需要編譯一次。而是編譯一次,然后直接修改 app 下內容,不過這里會出現簽名錯誤的問題,因為在編譯的最后會用證書幫 app 簽名,如果你直接替換資源然后就生成 ipa 的話會導致 ipa 無法安裝。

那這時候神奇的重簽名技術就出來(重簽名用在正途上的真少見…hhhh,關於重簽名的文章 google 一下就會很多),使用 codesign 命令就可以幫修改過資源的 app 重簽名。
最終使用2.0的時間基本是在5-6分鍾左右。果然能機器完成的工作絕對不要手動完成,從半天到30分鍾到最后的6分鍾,節省下來的時間可以讓你學習到更多。

上面說到如果不同 app 間會用到不同的代碼。例如 app A 里面的 title 叫 A 部門,app B 里面 title 又叫 B 部門,這樣就不會通過命令行直接修改到代碼,不過我想到的是維護一個 plist 文件,plist 文件可以這樣設計的,每個不同 app 的 bundleName 都設置字典的鍵,然后字典下就可以是你自定義的內容。然后每次啟動 app 就根據 bundleName 來尋找對應的字典,然后 title 就賦值為 plist 下 title 的值。如果不同代碼就根據 code1 里面的值來 switch 不同的代碼。

11228408-e1aa7e98b1d1edb6

最終代碼

以下是完整的腳本文件,部分信息需要自己替換。
以下腳本適用於一次打 N 個包,適用情況:

  1. 可以替換 bundle 信息
  2. 替換音頻圖片資源
  3. 可以執行不同代碼
  4. 生成相應的plist文件
  5. 上傳到蒲公英分發平台

當然也可以打一個包,適當刪除某些代碼即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM