建構和交付 iOS 應用程式的功能

在這篇文章中,我們分享了Plarium Krasnodar工作室在調試CI/CD過程中累積的組裝和交付iOS應用程式給使用者的經驗。

建構和交付 iOS 應用程式的功能

訓練

每一個以某種方式參與蘋果設備應用程式開發的人都已經意識到基礎設施的有爭議的便利性。困難無所不在:從開發人員設定檔選單到調試和建置工具。

網路上有很多關於「基礎知識」的文章,因此我們將盡力突出主要內容。以下是成功建立應用程式所需的內容:

  • 開發者帳戶;
  • 充當建置伺服器的基於 macOS 的設備;
  • 產生的 開發者憑證,這將進一步用於簽署應用程式;
  • 創建具有獨特的應用程式 ID (需要注意Bundle Identifier的重要性,因為使用通配符ID會導致無法使用應用程式的許多功能,例如:關聯域、推播通知、Apple Sign In等);
  • 輪廓 應用程式簽名。

必須透過任何 macOS 裝置上的鑰匙圈產生開發人員憑證。證書的類型非常重要。根據應用程式環境(開發、QA、登台、生產)的不同(開發或分發),應用程式簽署設定檔的類型也會有所不同。

型材的主要類型:

  • 開發 - 用於簽署開發團隊的應用程序,使用開發證書(類型名稱 iPhone Developer:XXXXX);
  • Ad Hoc - 用於簽署測試應用程式並由 QA 部門進行內部驗證,使用開發人員的分發證書(類型名稱 iPhone Distribution:XXXXX);
  • App Store - 透過 TestFlight 進行外部測試的發布版本並上傳到 App Store,使用開發人員的分發憑證。

產生 Development 和 Ad Hoc 設定檔時,也會指示 設備列表,您可以在其上安裝一個版本,該版本允許您進一步限制使用者的存取。 App Store 設定檔中沒有裝置列表,因為內測期間的存取控制由 TestFlight 處理,這將在稍後討論。

為了清楚起見,您可以用下表的形式展示開發者的個人資料。這使得我們更容易理解組裝需要哪些參數以及從哪裡取得它們。

建構和交付 iOS 應用程式的功能

裝配

為了更容易按專案和環境分離程序集,我們使用設定檔名稱,例如 ${ProjectName}_${Instance},即專案名稱+實例(取決於應用程式環境:Dev、QA、GD、Staging、Live等)。

當匯入到建置伺服器時,設定檔將其名稱變更為唯一 ID 並移動到資料夾 /Users/$Username/Library/MobileDevice/Provisioning Profiles (在哪裡 $Username 對應於建置伺服器的使用者帳戶名稱)。

建構 *.ipa 檔案有兩種方法 - 傳統 (PackageApplication) 和現代(透過 XcAchive 建立和匯出)。第一種方法被認為已過時,因為自版本 8.3 以來,應用程式檔案打包模組已從 Xcode 發行版中刪除。要使用它,您需要將模組從舊的 Xcode(版本 8.2 及更早版本)複製到該資料夾:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

然後運行命令:

chmod +x /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/*

接下來需要收集應用程式的*.app檔案:

xcodebuild 
-workspace $ProjectDir/$ProjectName.xcworkspace 
-scheme $SchemeName 
-sdk iphoneos 
build 
-configuration Release 
-derivedDataPath build 
CODE_SIGN_IDENTITY=”$DevAccName”
PROVISIONING_PROFILE=”$ProfileId”
DEPLOYMENT_POSTPROCESSING=YES 
SKIP_INSTALL=YES 
ENABLE_BITCODE=NO

在哪裡:

-workspace — 專案檔案的路徑。

-scheme ——專案中指定的所使用的方案。

-derivedDataPath — 下載已組裝應用程式的路徑 (*.app)。

CODE_SIGN_IDENTITY — 開發者帳號名稱,可在 Keychain 中驗證(iPhone 開發者:XXXX XXXXXXX,括號內不含 TeamID)。

建構和交付 iOS 應用程式的功能

PROVISIONING_PROFILE — 用於簽署應用程式的設定檔 ID,可以透過以下命令取得:

cd "/Users/$Username/Library/MobileDevice/Provisioning Profiles/" && find *.mobileprovision -type f | xargs grep -li ">${ProjectName}_${Instance}<" | sed -e 's/.mobileprovision//'

如果應用程式使用附加設定檔(例如,用於推播通知),則代替 PROVISIONING_PROFILE 表明:

APP_PROFILE=”$AppProfile” 
EXTENSION_PROFILE=”$ExtProfile” 

接下來,生成的 *.app 檔案應打包為 *.ipa。為此,您可以使用以下命令:

/usr/bin/xcrun --sdk iphoneos PackageApplication 
-v $(find "$ProjectDir/build/Build/Products/Release-iphoneos" -name "*.app") 
-o "$ProjectDir/$ProjectName_$Instance.ipa"

然而,從蘋果的角度來看,這種方法被認為是過時的。透過從應用程式存檔導出來獲取*.ipa 是相關的。

首先,您需要使用以下命令收集存檔:

xcodebuild 
-workspace $ProjectDir/$ProjectName.xcworkspace 
-scheme $SchemeName 
-sdk iphoneos 
-configuration Release 
archive 
-archivePath $ProjectDir/build/$ProjectName.xcarchive 
CODE_SIGN_IDENTITY=”$DevAccName” 
PROVISIONING_PROFILE=”$ProfileId”
ENABLE_BITCODE=NO 
SYNCHRONOUS_SYMBOL_PROCESSING=FALSE

差異在於裝配方法和選項 SYNCHRONOUS_SYMBOL_PROCESSING,這會在建置時禁用符號卸載。

接下來我們需要產生一個包含匯出設定的檔案:

ExportSettings="$ProjectDir/exportOptions.plist"

cat << EOF > $ExportSettings
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>uploadBitcode</key>
<false/>
<key>uploadSymbols</key>
<false/>
<key>method</key>
<string>$Method</string>
<key>provisioningProfiles</key>
<dict>
<key>$BundleID</key>
<string>$ProfileId</string>
</dict>
<key>signingCertificate</key>
<string>$DevAccName</string>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>$TeamID</string>
<key>thinning</key>
<string><none></string>
</dict>
</plist>
EOF

在哪裡:

$Method — 交付方法,對應於應用程式簽章設定檔類型,即對於 Development,該值將為development,對於 Ad Hoc - ad-hoc,對於 App Store - app-store。

$BundleID — 應用程式 ID,在應用程式設定中指定。您可以使用命令檢查:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName и $ProfileId — 先前使用的開發者名稱和簽章設定檔 ID 設定,必須與匯出設定中的值相符。

$TeamID — 開發者姓名後括號內的十位 ID,例如:iPhone 開發者:…(XX​​XXXXXXXX);可以在鑰匙圈中查看。

接下來,使用匯出命令,我們獲得必要的 *.ipa 檔案:

xcodebuild 
-exportArchive 
-archivePath $ProjectDir/build/$ProjectName.xcarchive 
-exportPath $ProjectDir 
-exportOptionsPlist $ExportSettings

交貨

現在需要將收集到的文件交付給最終用戶,也就是安裝在裝置上。

有許多用於分發開發和 Ad Hoc 建置的服務,例如 HockeyApp、AppBlade 等,但在本文中我們將討論用於分發應用程式的獨立伺服器。

安裝 iOS 應用程式分兩個階段進行:

  1. 透過專案服務接收應用程式安裝清單。
  2. 根據清單中指定的資訊透過 HTTPS 安裝 *.ipa 檔案。

因此,我們首先需要使用以下命令產生安裝清單(檔案類型 *.plist):

cat << EOF > $manifest
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>$ipaUrl</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>$BundleID</string>
<key>bundle-version</key>
<string>$AppVersion</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>$ProjectName_$Instance</string>
<key>subtitle</key>
<string>$Instance</string>
</dict>
</dict>
</array>
</dict>
</plist>
EOF

如您所見,清單包含建立應用程式涉及的幾乎所有參數。

應用程式版本($AppVersion) 可以使用以下命令進行檢查:

defaults read $ProjectDir/Info CFBundleVersion

參數 $ipaUrl 包含下載 *.ipa 檔案的直接連結。從 iOS 第七版開始,應用程式必須透過 HTTPS 安裝。在第八個版本中,清單的格式略有變化:帶有應用程式圖示設定的區塊,例如

<images>
   <image>...</image>
</images>

因此,要安裝該應用程序,一個帶有如下連結的簡單 HTML 頁面就足夠了:

itms-services://?action=download-manifest&url=https://$ServerUrl/$ProjectName/$Instance/iOS/$AppVersion/manifest.plist

為了滿足開發和測試部門的需求,Plarium 創建了自己的建置安裝應用程序,它為我們提供了:

  • 自治和獨立,
  • 透過「臨時」動態建立的連結集中存取控制和安全安裝應用程序,
  • 可擴展的功能(即,開發團隊在必要時可以將缺少的功能整合到現有應用程式中)。

測試

現在我們將討論使用應用程式的預發布測試 試飛.

下載所需的條件是 App Store 簽章設定檔的類型以及產生的 API 金鑰的存在。

有多種方式下載該應用程式:

  • 透過 Xcode(組織者),
  • 透過阿爾工具,
  • 透過舊版 Xcode 的應用程式載入器(現在的 Transporter)。

自動下載使用的是altool,它也有兩種授權方式:

  • 應用程式專用密碼,
  • API 金鑰。

最好使用 API 金鑰下載應用程式。

若要取得 API 金鑰,請訪問 鏈接 並產生密鑰。除了 *.p8 格式的金鑰本身之外,我們還需要兩個參數:IssuerID 和 KeyID。

建構和交付 iOS 應用程式的功能

接下來,將下載的金鑰匯入到建置伺服器:

mkdir -p ~/.appstoreconnect/private_keys
mv ~/Downloads/AuthKey_${KeyID}.p8 ~/.appstoreconnect/private_keys/

在將應用程式上傳到 TestFlight 之前,您需要驗證應用程序,我們使用以下命令執行此操作:

xcrun altool 
--validate-app 
-t ios 
-f $(find "$ProjectDir" -name "*.ipa") 
--apiKey “$KeyID” 
--apiIssuer “$IssuerID” 

在哪裡 apiKey и apiIssuer 具有來自 API 金鑰產生頁面的欄位值。

接下來,驗證成功後,我們使用以下命令載入應用程式 --upload-app 具有相同的參數。

該應用程式將在一兩天內由 Apple 進行測試,然後可供外部測試人員使用:他們將透過電子郵件收到安裝連結。

透過 altool 下載應用程式的另一種方法是使用應用程式專用密碼。

要獲取應用程式專用密碼,您需要訪問 鏈接 並在安全性部分生成它。

建構和交付 iOS 應用程式的功能

接下來,您應該使用此密碼在鑰匙圈中建立建置伺服器記錄。從 Xcode 11 版本開始,可以使用以下命令完成此操作:

xcrun altool --store-password-in-keychain-item "Altool" -u "$DeveloperName" -p $AppPswd

在哪裡:

$DeveloperName — 用於登入 Apple 服務的 iOS 開發者帳戶的名稱。

$AppPswd — 產生的應用程式專用密碼。

接下來,我們取得asc-provider參數的值,並使用指令檢查密碼匯入是否成功:

xcrun altool --list-providers -u "$DeveloperName" -p "@keychain:Altool"

我們得到輸出:

Provider listing:
- Long Name - - Short Name -
XXXXXXX        XXXXXXXXX

如您所見,所需的短名稱值 (asc-provider) 與我們在建立應用程式時使用的 $TeamID 參數一致。

若要驗證應用程式並將其載入到 TestFlight 中,請使用下列命令:

xcrun altool 
--(validate|upload)-app   
-f $(find "$ProjectDir" -name "*.ipa") 
-u "$DeveloperName" 
-p "@keychain:Altool" 

作為參數值 -p 你可以取這個值 $AppPswd 以未加密(顯式)形式。

不過,前面已經提到,從效能的角度來看,最好選擇 API Key 進行 altool 授權,因為不同版本的 Xcode 都會存在一定的問題(「看不到」Keychain、上傳時授權錯誤等)。

事實上,僅此而已。我希望每個人都能在 App Store 中成功建立並順利發布。

來源: www.habr.com

添加評論