從 xcarchive 到分發的 ipa

KyXu發表於2017-01-26

寫這篇文章的起因是要更新 app ,然而上傳 ipa 檔案到 iTunes Connect 時發現體積巨大,是 App Store 顯示的體積的好幾倍,於是仔細研究了一下,各種體積的檔案都是些什麼。

各格式簡要說明

.xcarchive

- Xcode Archive
- 由 Xcode 進行 Archive 操作產生的結果,出現在 Xcode Organizer 中
- 主要包含 .dSYM .app .dylib(針對 Swift)
- 用於生成 .ipa 檔案複製程式碼

從 xcarchive 到分發的 ipa

.ipa(Xcode 產出)

- iPhone Application Archive
- 主要包含 .app .dylib(針對 Swift)
- 最終從本地 upload 到 iTunes Connect 的檔案複製程式碼

.ipa(iTunes 下載)

- iPhone Application Archive
- 主要包含 .app iTunesMetadata iTunesArtwork
- iTunes 用於管理應用軟體安裝包的形式複製程式碼

.app

- Applicaiton
- 主要包含圖片、語言檔案等資源,以及動態庫和 Unix 可執行檔案
- 安裝到 iOS 裝置的檔案的格式複製程式碼

從 xcarchive 到 ipa

在進行 Archive 操作之前,我們就可以在 Xcode 導航欄的 Products 目錄中看到 .app 檔案,extension target 對應的是 .appex 檔案,所以歸檔出 .xcarchive 並不是一個非常複雜的操作,只需要編譯、連結、簡單的簽名,如果是 Swift 專案的話還需要拷貝一下標準庫。

我們檢視 .xcarchive 裡面的內容是通過“顯示包內容”看見的,而 .ipa 則需要像 .zip 檔案一樣解壓,那麼也可以理解為什麼打包出 ipa 檔案相對耗時了,尤其是 Swift 專案,不光要進行壓縮操作,要 processing,一堆原生動態庫加上第三方 framework 還要輪著等著簽名。

從 xcarchive 到分發的 ipa

這些保證了 ipa 檔案不能被模擬器裝上(沒有 x86 架構),只能被 iOS 裝置安裝,你買的應用程式發給別人,別人並不能直接裝上。從兔兔助手等平臺安裝的盜版軟體一定是被重新簽名過的。
(由於 ipa 檔案上傳到 iTunes Connect 之後,還會被重新處理,所以個人尚且不知道後續的處理過程還進行過怎樣的簽名工作)

所以 ipa 檔案才可以作為加密檔案放在軟體商店,xcarchive 不可以。

從 Xcode 產出的 ipa 到使用者下載的 ipa

從 xcarchive 到分發的 ipa

如圖是我開發的一款軟體打包過程的各個狀態,可以看到壓縮狀態的 ipa 檔案是體積最小的。如果將 ipa 檔案解壓成資料夾,它的體積會和 xcarchive 檔案很接近,因為它內部包含了比它本身還要大的整個 .app 包。
從 xcarchive 到分發的 ipa

然後我分別通過 AppStore 和 TestFlight 安裝了我上傳的軟體,結果都只佔用了大約 15M 的空間。
前面提到,下載到裝置的是 ipa,安裝到裝置的是 app。但看圖,會發現 TestFlight 頁面展示的體積和另外三張圖相去甚遠,30M+。仔細分析下:

  1. iPhone 5S 推出之後,iOS 裝置指令集從 armv6、armv7、armv7s 一路幹到了 arm64,這麼些個不同的裝置安裝到本地的檔案肯定不一樣吧
  2. 同一裝置不同系統,安裝的檔案也不一樣吧
  3. Xcode 一次只產出一個 ipa,但是考慮到這款軟體支援的系統版本數量和裝置種類數量,可能最終幾十種不同的 iOS 環境(自造詞,系統版本或裝置型號不同都算環境不同),從同一個 AppStore 頁面,下載了幾十個不同的 ipa 檔案
  4. 嘗試釋出過 app 的開發者都知道,上傳 ipa 檔案完成之後,還要等待一段時間,才能在 iTunes Connect 頁面看見一個“構建版本”。雖然不知道這個“構建版本”在 Apple 的伺服器裡面具體都有哪些東西,但至少應該包含一大堆的 ipa 檔案,分別指定了對應什麼系統版本、什麼裝置型號
  5. 在這個過程中 ipa 檔案的體積發生了很大變化,App Thining 也發生在這個過程中。

至此可以看出,AppStore 頁面顯示的體積應該是預估的應用安裝到裝置的體積,而不是你下載這款軟體所耗費的流量。這也解釋了我之前嘗試用剩 1G 儲存的 iPad 去裝一個 AppStore 顯示 大小不到 1G 的遊戲,為什麼會裝不上,因為下載到 iPad 的檔案實際可能大於 1G。

TestFlight 裡面顯示的 30M+,肯定是經過 iTunes Connect 處理過的 ipa,但考慮到 .ipa 檔案並不會比安裝到裝置的 .app 包體積更小,個人認為這是解壓過後的 ipa 檔案的體積。

我的 app 是如何一步一步變小的

未處理的 .app - 85.6 M
(加入動態庫、.dSYM 等)
xcarchive - 167.7 M
未處理的 ipa 資料夾 - 172 M
(經過類似 zip 壓縮)
未處理的 .ipa - 70.8 M(開發者感受到的體積)
(個人推測)處理後的 ipa 資料夾- 約 30M(使用者下載需要耗費的流量)
處理後的 .app - 約 15M(最終佔用使用者裝置體積)

備註

App Thining 包含 Slicing、Bitcode 和 On-Demand Resources,其中 Slicing 是預設啟用、無法關閉的,但只在 iOS 9.0.2 之後有效,後面兩個選項在 Xcode 中預設開啟,可以手動關閉。

這是 Xcode 產物體積與使用者下載到裝置中的軟體體積差距較大的主要原因。

推薦閱讀:初探 iOS 9 的 App 瘦身功能

相關文章