iOS批量自動打包和部署(Ⅱ)
網上有大把的文章講了自動打包,其實無非就是那幾條命令,但是我覺得有必要繼續瞭解一下一個app包(即應用)的組成和app可執行檔案的構建過程。這個裡面非常複雜,也參考了一些文章,僅將自己瞭解的大概梳理出來備忘。
應用的構建過程和組成
想象一下平時的打包過程,在Xcode中選擇對應的appid,bundleid,還要選擇正確的配置檔案(provisioning profile),然後點選run
,我們看到Xcode上面有內容在不斷的更新,正如猜想的,更新的內容實際就是app包編譯的過程。
這個過程大概經過了:配置(編譯器確定當前系統環境)-> 確定標準庫和標頭檔案的位置->確定依賴關係->標頭檔案預編譯(precompilation)
對於iOS的包來講,在構建完成之後還會自動呼叫codesign
命令進行簽名,這個時候我們之前選擇的bundleid啊,配置檔案啊等等就排上用場了。經過簽名後的應用是個相對來講安全的應用,通過簽名確保了包的來源合法,也能確保包的內容是否被修改過(理論知識上篇已講過)。最後的包的本質實際上是一個Mach-O格式的二進位制可執行檔案(簽名的資料就在這個二進位制檔案中)和一些資原始檔。
Mach-O可執行檔案
Mach是一種作業系統核心。它的大致歷史是:Mach核心被NeXT公司的NeXTSTEP作業系統使用,NeXT是喬布斯蘋果被趕出蘋果後建立的公司。1996年,喬布斯將NeXTSTEP帶回蘋果,成為了OS X的核心基礎。在Mach上,一種可執行的檔案格是就是Mach-O(Mach Object file format)。iOS是從OS X演變而來,所以同樣支援Mach-O格式的可執行檔案。
搞iOS的肯定知道ipa包,它實際上就是一個zip壓縮包,可以用mac自帶的歸檔解壓工具進行解壓。解壓之後會有一個Payload
資料夾,其中有個XXX.app
這樣的.app
檔案,它實際上是資料夾,它裡面除了有個各種資源、圖片等,還有個和包名相同的檔案——這個就是二進位制可執行檔案。可以用file
命令檢視檔案型別,下圖是微信包的截圖:
從上面看是支援arm7和arm64兩種處理器架構的通用程式包,裡面的格式是Mach-O。將微信的可執行檔案WeChat
用Sublime開啟,二進位制開始部分如下:
開頭的4個位元組是cafebabe,這被稱為“魔數”,反映檔案的型別。查了下相關文章,OS X上還有如下幾個標識:
cafebabe
feedface
feadfacf
還有一個格式,就是以#!開頭的指令碼
cafebabe就是跨處理器架構的通用格式,feedface和feedfacf則分別是某一處理器架構下的Mach-O格式,指令碼的就很常見了,比如#!/bin/bash開頭的shell指令碼。
Mach-O可執行檔案包含頭部資訊和載入命令。才疏學淺,這部分也沒有深入瞭解,本篇也無法繼續深入講這塊了。
其他資原始檔
解壓後的包中除了可執行檔案還有其他資原始檔,圖片啊,plist啊等等。蘋果對安全確實重視,這些資原始檔其實大多數也是需要被設定簽名的,可以見到的是包中還有一個_CodeSignature
資料夾,這個資料夾中的CodeResources
檔案中儲存了被簽名的程式包中所有需要被簽名檔案的簽名。更詳細的介紹參見《程式碼簽名探析》,從這些細節不難看出蘋果對於安全的重視。
自動打包
蘋果自帶的xcodebuild命令列工具就可以打包,但是這裡我更加推薦facebook出品的xctool,xctool的初衷就是要替代蘋果的xcodebuild,它們的命令引數都是一樣的,相比較xcodebuild,xctool有以下特點:
1.相比較xcodebuild輸出的log雜亂,xctool更有結構
2.xctool有人性化的顏色輸出
3.facebook聲稱xctool更快,據說能快2、3倍
4.完全用Ojbective-C實現
當然xctool只支援Xcode6及以上,並且Xcode Command Line Tools
安裝好。
xctool
xctool是可以使用homebrew安裝的,或者下原始碼然後執行 xctool.sh
指令碼,homebrew安裝命令如下:
brew install xctool
實戰
接下來是實戰篇,按照我的設想,如果想要實現自動化,需要攻克幾個點:
1.自動打包
2.重新簽名
3.分發部署
其中,自動打包是基礎,打包完之後可以根據母包重新簽名生成相似的包,生成的包可以自動部署。只要攻克這三個點就能實現全自動化,當然就需要寫指令碼了,帶著這個性質我參考了一些文章並且在網上找到了一些指令碼。最終,驗證了這些東西都是實際可行的。但,下面的實戰用到的指令碼,一部分是網上找的,一部分是同事寫的,當時雖然逐個研究了但是卻沒有精力在這個上,這部分的工作最後是同事做的。
為了講的更清楚,新建了一個專案PackageExample
(Demo已上傳到這裡),並且使用了CocoaPods(實驗起見僅引用了AFNetworking),專案的證書是dev狀態的。PackageExample
專案在我機器上的路徑和目錄如下截圖:
和PackageExample
同目錄的還有PackageShell
,裡面的buildipa.sh
為編譯指令碼,由於最後的目標是要做成可以隨意配置的,所以還有一個PackageConfig
資料夾,裡面有配置檔案packageExample.mobileprovision
和packageExample.plist
,配置檔案主要用來簽名,plist檔案的內容為可配置的,例如裡面有app_Prefix、app_Name、app_ID等資訊。Package
資料夾為打的包的存放的地方。
完整的編譯指令碼如下:
#!/bin/sh
#從plist檔案中讀取ipa包名和配置檔名
profile_Name=`/usr/libexec/PlistBuddy -c "print profile_Name" ./PackageConfig/packageExample.plist`
ipa_Name=`/usr/libexec/PlistBuddy -c "print app_Name" ./PackageConfig/packageExample.plist`
#進入工程目錄
cd ../PackageExample
echo "go to packageExample workspace path"
#報名時根據時間戳命名的,所以這裡有用到
buildTime=$(date +%Y%m%d%H%M)
profile="${profile_Name}"
echo $profile $ipa_Name
#一下方法主要是建立打包的路徑和最後匯出的ipa的路徑
if [ ! -d "../PackageShell/Package" ]; then
mkdir ../PackageShell/Package
fi
if [ ! -d "../PackageShell/Package/ArchiveProduction" ]; then
mkdir ../PackageShell/Package/ArchiveProduction
fi
if [ ! -d "../PackageShell/Package/ArchiveProduction/QA" ]; then
mkdir ../PackageShell/Package/ArchiveProduction/QA
echo "Create ArchiveProduction path"
fi
if [ ! -d "../PackageShell/Package/ipa" ]; then
mkdir ../PackageShell/Package/ipa
fi
if [ ! -d "../PackageShell/Package/ipa/QA" ]; then
mkdir ../PackageShell/Package/ipa/QA
echo "Create ipa path"
fi
buildConfiguration="QA"
buildPath="../PackageShell/Package/ArchiveProduction/QA/${ipa_Name}_${buildTime}.xcarchive"
ipaName="../PackageShell/Package/ipa/QA/${ipa_Name}_${buildTime}.ipa"
#先進行clean操作
xctool -workspace PackageExample.xcworkspace -scheme PackageExample -configuration ${buildConfiguration} clean
#打包的命令
xctool -workspace PackageExample.xcworkspace -scheme PackageExample -configuration ${buildConfiguration} archive -archivePath ${buildPath}
#匯出ipa包的命令,
xcodebuild -exportArchive -exportFormat IPA -archivePath ${buildPath} -exportPath ${ipaName} -exportProvisioningProfile "$profile"
做一些解釋,指令碼的開頭有PlistBuddy
命令,它是Mac下一個用來讀寫plist檔案的工具,在/usr/libexec/下。xctool -workspace PackageExample.xcworkspace -scheme PackageExample -configuration
${buildConfiguration} clean
,由於專案是workspace,所以這裡必須要對應,如果是project則是project,clean的目的是進行清理快取等。xctool -workspace PackageExample.xcworkspace -scheme PackageExample -configuration ${buildConfiguration} archive -archivePath
${buildPath}
,archive
命令主要用來打包,最後包的格式為xcarchive
。可以進入這個包裡,目錄結構如圖:
主要是產生了 dsYM
和 .app
檔案,並且可以看到的是它是已經經過簽名的。雖然從命令中沒有指定profile,但是我看到編譯的log輸出有以下這段:
由Sign PackageExample.app
,推測這步是進行簽名了,至於為什麼命令中沒有指定也可以編譯那是因為在Xcode中進行過手動設定(?:猜測是)。最後一步匯入ipa主要用xcodebuild
命令,至少在當時我找到的是這個命令而不是xctool。經過匯出的ipa包,簡單點的,可以郵件群發給同事進行測試。
小結
至此,差不多介紹完自動打包的一種方案。但其實還可以延伸,主要反映在兩點上:
1.雖然能夠成功打一個包,但是本系列文章第一篇開始部分中提到的,如何快速複製兩個很相似但又不同的包?
2.匯出來的ipa包,用郵件群發是否仍然麻煩,能否繼續實現自動化?
上面的兩點實際上都能很好的解決,也就是前面說到的要攻克2.重新簽名
和 3.分發部署
,下篇文章會介紹我的解決思路,裡面涉及重新簽名和一些上傳工具。
相關推薦
iOS批量自動打包和部署(Ⅱ)
網上有大把的文章講了自動打包,其實無非就是那幾條命令,但是我覺得有必要繼續瞭解一下一個app包(即應用)的組成和app可執行檔案的構建過程。這個裡面非常複雜,也參考了一些文章,僅將自己瞭解的大概梳理出來備忘。 應用的構建過程和組成 想象一下平時的打包過程,在Xcode中選擇對應的appid,bundle
iOS批量自動打包和部署(I)
如果你遇到這樣的一項需求:專案的程式碼沒有變動,只是icon和介面改動,然後要打成很多的包,發往AppleStore。就像喜馬拉雅的各種小版本那樣,像牛皮鮮一樣汙染在AppleStore之上。那麼問題來了,成十上百的包,僅僅只是icon的圖示變了,程式碼都一樣,難道要人工在那打成十上百次嗎?答案當然是否定
Jenkins + SVN + Batch Command (專案的自動打包和部署)
Jenkins + SVN 需求:將SVN上的指定專案(如: com.cr.dt)打成jar,併發布發到指定目錄(如: d\export2)。 SVN上的指定專案在Eclipse中顯示的目錄結構如下: E:\...\COM.CR.DT │ .classpath │ .
部署指令碼3:批量自動關閉和自動重啟
批量自動關閉stop和自動重啟start #!/bin/sh #author:wenjin.li #:Title:fashion tomcat #:Synopsis: #:Data:2018-01-12 14:35:32 #:Version:1.2 #divi
基於Jenkins 實現php專案的自動化測試、自動打包和自動部署
本篇博文宅鳥將在上篇: 基於Jenkins 搭建持續整合環境 的基礎上,繼續介紹Jenkins結合php專案實現自動化測試和自動部署。廢話不再多說,直接上幹活。 宅鳥所使用的server為Ubuntu 要實現在jenkins中實現php的自動化測試,首先需要Jenkins伺服器上安裝ph
基於Jenkins 實現php專案的自動化測試、自動打包和自動部署(-)
基於Jenkins 實現php專案的自動化測試、自動打包和自動部署(一) 身在創業公司,碰到任何問題,都得擼起袖子加油幹: 隨著專案團隊的不斷擴大,專案因為人員的參差不齊導致各種各樣的問題。於是引入jenkins持續整合。 廢話不多說,先普及基礎概念
Window系統下用Ant實現Java項目的自動構建和部署
echo 驗證 TP 地址 apach ava build 部署 系統環境變量 Step 1: 從官網下載Ant包,官網地址http://ant.apache.org/ Step 2: 解壓好了,去配置用戶自定義環境變量【或者系統環境變量】 Step 3:驗證一下自己環境是
個人站點升級持續集成,自動構建和部署
lock 快的 標識 mar 根目錄 OS 執行 連接 path 前言 利用markdown+Hexo寫文章,整體體驗已經很棒。在寫作過程中,節省了我不少時間。 但是,美中不足的,就是發布的時候,需要手動輸入命令,build好文件,再用scp部署到服務器上。 本文,用於記錄
使用Maven多環境配置打包和部署
基本每個專案都會有開發環境(本地環境)、開發整合環境、測試環境、預釋出環境、正式環境。 最少也有開發環境(本地環境)、測試環境、生產環境3個環境,每個環境的配置是不一樣的,如果每次打包都手動修改配置檔案,工作量大且容易出錯。 所以這個時候就可以考慮使用mav
SpringBoot入門(23)--springBoot打包和部署
1、打包 進入到專案根目錄下 輸入命令 Mvn clean package 拷貝依賴maven命令: mvn clean package dependency:copy-dependencies 建立一個新的資料夾xxx/lib 把所有的依賴及工程拷貝到
使用Docker快速打包和部署執行Disconf
Docker-Disconf Docker-Disconf是本人學習Docker後,嘗試使用Docker解決Disconf打包和執行問題的作品。Disconf是分散式配置管理平臺(Distributed Configuration Management Platform)的
編寫shell命令實現IOS的自動打包
開發過程中,需要這樣的需求: App的兩個執行環境,一個是測試環境,一個是釋出環境,兩個環境的伺服器Api是不同的。每次,編譯打包測試軟體的時候,很麻煩。因此,需要編寫一個shell指令碼,可以根據傳入的引數,自動打包測試版或者釋出版App,同時可以生成 無線安裝所需的pl
用Ant實現Java專案的自動構建和部署
Ant是一個Apache基金會下的跨平臺的構件工具,它可以實現專案的自動構建和部署等功能。在本文中,主要讓讀者熟悉怎樣將Ant應用到Java專案中,讓它簡化構建和部署操作。 一.安裝與配置 下載地址:http://ant.apache.org/,在本文中下載的是1.7.0版本。解壓到某
spring boot 打包和部署
這兩天專案剛剛寫完準備測試,專案是用Springboot搭建的,一個project和三個module,分別是API(用來其他系統的呼叫,包括前端)、service(內含service層、dao層和mapper以及mybatis的xml檔案)和job(任務排程的module)
caffe打包和部署
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include H:\caffe\caffe-ssd-microsoft\caffe-ssd-microsoft\include H:\caffe\caffe-ss
Ant詳解(用Ant實現Java專案的自動構建和部署)
Ant是一個Apache基金會下的跨平臺的構件工具,它可以實現專案的自動構建和部署等功能。在本文中,主要讓讀者熟悉怎樣將Ant應用到Java專案中,讓它簡化構建和部署操作。 一.安裝與配置 下載地址:http://ant.apache.org/,在本文
Gemini Blueprint參考文件 第8章 打包和部署基於Spring的OSGi應用
8.1.Bundle格式和Manifest頭 每一個應用模組都應打包成一個OSGi的bundle。bundle本質上是包含META-INF/MANIFEST.MF檔案的jar檔案,MANIFEST.MF檔案包含了OSGi服務平臺能夠識別的一系列頭資訊。參見OSGi服務平臺核心規範第3.2節瞭解細節。一些OS
Java配置maven+jenkins+git(svn)+tomcat自動編譯和部署(持續整合)
目的 在開發中,需要經常頻繁的對測試伺服器進行部署,而且在多人協同中開發經常遇到的問題就是別人更新了他的程式碼,而你去更新你的程式碼時並沒有更新到別人的程式碼,導致測試環境的程式碼不是最新,當然這個問題也好解決,那就是每次更新的時候先獲取版本控制器上面的程式碼,然後更新
iOS APP archive打包和打包成Ipa
archive打包就是專案做在最後一部,打包上線到APP Store上(非越獄版)。打包成ipa就是為了上線到PP助手、快用助手、360等網站上(越獄版)。 開發環境 : Xcode 6以上 & Object C 一、archive打包 1、模擬器選擇iOS
IOS工程自動打包併發布指令碼實現
作者:webfrogs 轉載請註明出處。 前言 IOS的開發過程中,當需要給測試人員釋出測試包的時候,直接使用xcode來做的效率是非常低下的。尤其是當有一點小改動需要重新出包時,那簡直是個折磨的人的工作。通過一番研究後,遂決定寫一系列指令碼,以代替人工完成打