關於 iOS 批量打包的總結

 

關於 iOS 批量打包的總結

若是你曾經試過作多 target 的項目,到了測試人員要測試包的時候,你就會明白什麼叫「生不如死」。雖然 Xcode 打包很方便,可是當你機械重複打 N 次包的時候,就會以爲這純粹是浪費時間的工做。因此這時候自動化打包就顯得尤其重要(其實就算只有一個 target,就算使用 Xcode 打包很方便,也應該構建自動化打包,由於你能夠節省大量時間)。html

構建自動化打包腳本

xcodebuild

使用 xcodebuild -h 來看看 xcodebuild 究竟是幹啥的ios

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

這裏介紹幾條畢竟經常使用的命令github

1. xcodebuild -list …

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

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

example:api

 

2. xcodebuild -project …

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

usage:xcode

-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. 上傳到蒲公英分發平臺

固然也能夠打一個包,適當刪除某些代碼便可。

相關文章
相關標籤/搜索