Асаблівасці зборкі і дастаўкі iOS-прыкладанняў

У гэтым артыкуле мы дзелімся досведам зборкі і дастаўкі карыстачам прыкладанняў для iOS, які назапасіўся ў студыі Plarium Krasnodar падчас адладкі CI/CD.

Асаблівасці зборкі і дастаўкі iOS-прыкладанняў

Падрыхтоўка

Кожны чалавек, так ці інакш звязаны з распрацоўкай прыкладанняў для прылад Apple, ужо паспеў ацаніць спрэчнае зручнасць інфраструктуры. Складанасці сустракаюцца паўсюль: пачынальна з меню профіля распрацоўніка і сканчаючы прыладамі адладкі і зборкі.

Артыкулаў аб «азах» звышдастаткова ў сетцы, таму пастараемся вылучыць галоўнае. Вось што трэба для паспяховай зборкі прыкладання:

  • акаўнт распрацоўніка;
  • прылада на базе macOS, якое выступае ў ролі білд-сервера;
  • згенераваны сертыфікат распрацоўніка, які будзе далей выкарыстоўвацца для подпісы дадатку;
  • створанае прыкладанне з унікальным ID (варта адзначыць важнасць Bundle Identifier, таму што ўжыванне wildcard ID робіць немагчымым выкарыстанне шматлікіх функцый прыкладання, напрыклад: Associated Domains, Push Notifications, Apple Sign In і іншых);
  • профіль подпісы прыкладання.

Сертыфікат распрацоўніка варта згенераваць праз Keychain на любой прыладзе на базе macOS. Вельмі важным з'яўляецца тып сертыфіката. У залежнасці ад асяроддзя прыкладання (Dev, QA, Staging, Production) ён будзе адрознівацца (Development ці Distribution), гэтак жа як і тып профіля подпісу прыкладання.

Асноўныя тыпы профіляў:

  • Development — прызначаны для подпісу дадатку каманды распрацоўшчыкаў, выкарыстоўваецца Development-сертыфікат (імя віду iPhone Developer: XXXXX);
  • Ad Hoc — прызначаны для подпісу тэставага дадатку і ўнутранай праверкі QA-аддзелам, выкарыстоўваецца Distribution-сертыфікат распрацоўшчыка (імя віду iPhone Distribution: XXXXX);
  • App Store - рэлізны білд для знешняга тэсціравання праз TestFlight і выгрузкі ў App Store, выкарыстоўваецца Distribution-сертыфікат распрацоўніка.

Пры генерацыі профіляў 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 модуль пакавання app-файла прыбраны з дыстрыбутыва 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 Developer: 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//'

Калі ў дадатку выкарыстоўваецца дадатковы профіль (напрыклад, для Push Notifications), то замест 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"

Аднак гэты спосаб лічыцца састарэлым з пункту гледжання Apple. Актуальным з'яўляецца атрыманне *.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 Developer: …… (XXXXXXXXXX); можна праверыць у Keychain.

Далей з дапамогай каманды экспарту атрымліваем неабходны файл *.ipa:

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

Дастаўка

Зараз сабраны файл трэба даставіць канчатковаму карыстачу, гэта значыць усталяваць на прыладу.

Для распаўсюджвання білдаў Development і Ad Hoc існуе мноства сэрвісаў накшталт HockeyApp, AppBlade і іншых, аднак у рамках дадзенага артыкула прамова пайдзе аб аўтаномным серверы для раздачы прыкладанняў.

Устаноўка прыкладання для iOS праходзіць у 2 этапы:

  1. Атрыманне маніфесту ўстаноўкі прыкладання праз Items Service.
  2. Усталёўка файла *.ipa паводле інфармацыі, паказанай у маніфесце, праз HTTPS.

Такім чынам, нам для пачатку трэба згенераваць маніфест усталёўкі (тып файла *.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 стварыла сваё прыкладанне ўстаноўкі білдаў, якое дае нам:

  • аўтаномнасць і незалежнасць,
  • цэнтралізацыю кіравання доступам і бяспечную ўстаноўку прыкладанняў праз «часовыя», якія дынамічна ствараюцца спасылкі,
  • пашыраецца функцыянал (гэта значыць каманда распрацоўкі пры неабходнасці можа інтэграваць адсутнічаюць функцыі ва ўжо існуючы дадатак).

Тэставанне

Цяпер гаворка пойдзе аб предрелизном тэсціраванні прыкладання з дапамогай TestFlight.

Абавязковымі ўмовамі для загрузкі з'яўляюцца тып профіля подпісы App Store і наяўнасць згенераваных API-ключоў.

Ёсць некалькі спосабаў загрузкі прыкладання:

  • праз Xcode (Organizer),
  • праз altool,
  • праз Application Loader для старых версій Xcode (зараз Transporter).

Для аўтаматычнай загрузкі выкарыстоўваецца altool, у якім таксама ёсць два спосабу аўтарызацыі:

  • App-Specific Password,
  • API Key.

Больш пераважнай з'яўляецца загрузка прыкладання з дапамогай API Key.

Для атрымання API Key пераходзім па спасылцы і які генеруецца ключ. Акрамя самога ключа ў фармаце *.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 з'яўляецца выкарыстанне App-Specific Password.

Для атрымання App-Specific Password трэба перайсці па спасылцы і згенераваць яго ў раздзеле Security.

Асаблівасці зборкі і дастаўкі iOS-прыкладанняў

Далей варта стварыць у Keychain запіс білд-сервера з гэтым паролем. З 11 версіі Xcode гэта можна зрабіць камандай:

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

Дзе:

$DeveloperName - імя акаўнта iOS-распрацоўніка, выкарыстоўванае для лагіна ў сэрвісы Apple.

$AppPswd - згенераваны App-Specific Password.

Далей атрымліваем значэнне параметра asc-provider і правяраем паспяховасць імпарту пароля камандай:

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

Атрымліваем выснову:

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

Як бачым, шуканае значэнне Short Name (asc-provider) супадае з параметрам $ TeamID, які мы выкарыстоўвалі пры зборцы прыкладання.

Для валідацыі і загрузкі прыкладання ў TestFlight ужывальны каманду:

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

У якасці значэнне параметра -p можна ўзяць значэнне $AppPswd у незашыфраваным (відавочным) выглядзе.

Аднак, як ужо было сказанае, з пункта гледжання працаздольнасці для аўтарызацыі altool лепш абраць API Key, бо ў розных версіях Xcode сустракаюцца тыя ці іншыя праблемы ("не бачыць" Keychain, памылкі аўтарызацыі пры выгрузцы і іншае).

На гэтым, уласна, усё. Жадаю ўсім датычным паспяховых зборак і беспраблемных рэлізаў у App Store.

Крыніца: habr.com

Дадаць каментар