Funktioner för att bygga och leverera iOS-applikationer

I den här artikeln delar vi erfarenheten av att montera och leverera iOS-applikationer till användare, som Plarium Krasnodar-studion har samlat på sig i processen med att felsöka CI/CD.

Funktioner för att bygga och leverera iOS-applikationer

Utbildning

Varje person som på ett eller annat sätt är involverad i utvecklingen av applikationer för Apple-enheter har redan uppskattat den kontroversiella bekvämligheten med infrastrukturen. Svårigheter finns överallt: från utvecklarprofilmenyn till felsöknings- och byggverktygen.

Det finns gott om artiklar om "grunderna" på Internet, så vi kommer att försöka lyfta fram det viktigaste. Här är vad du behöver för att bygga din applikation framgångsrikt:

  • utvecklarkonto;
  • en macOS-baserad enhet som fungerar som en byggserver;
  • genererad utvecklarcertifikat, som kommer att användas vidare för att underteckna ansökan;
  • skapad applikation med unika ID (Vikten av paketidentifieraren bör noteras, eftersom användningen av jokertecken-ID gör det omöjligt att använda många funktioner i applikationen, till exempel: associerade domäner, push-meddelanden, Apple-inloggning och andra);
  • profil applikationssignaturer.

Ett utvecklarcertifikat måste genereras via nyckelring på valfri macOS-enhet. Typen av certifikat är mycket viktig. Beroende på applikationsmiljön (Dev, QA, Staging, Production) kommer det att skilja sig (Utveckling eller Distribution), liksom typen av applikationssignaturprofil.

Huvudtyper av profiler:

  • Utveckling - avsedd för att signera utvecklingsteamets ansökan, ett utvecklingscertifikat används (typnamn iPhone-utvecklare: XXXXX);
  • Ad Hoc - avsedd för att signera en testapplikation och intern verifiering av QA-avdelningen, utvecklarens distributionscertifikat används (typnamn iPhone Distribution: XXXXX);
  • App Store - release build för extern testning via TestFlight och uppladdning till App Store, utvecklarens distributionscertifikat används.

Vid generering av utvecklings- och ad hoc-profiler anges det också enhetslista, där du kan installera en build, som låter dig begränsa åtkomsten ytterligare för användare. Det finns ingen lista över enheter i App Store-profilen, eftersom åtkomstkontroll under stängd beta-testning hanteras av TestFlight, vilket kommer att diskuteras senare.

För tydlighetens skull kan du presentera utvecklarens profil i form av en tabell nedan. Detta gör det enklare att förstå vilka parametrar vi behöver för montering och var man kan få dem ifrån.

Funktioner för att bygga och leverera iOS-applikationer

aggregatet

För att göra det enklare att separera sammanställningar efter projekt och miljö använder vi profilnamn som ${ProjectName}_${Instance}, det vill säga projektnamn + instans (beror på applikationsmiljön: Dev, QA, GD, Staging, Live, och så vidare).

När den importeras till byggservern ändrar profilen sitt namn till ett unikt ID och flyttas till mappen /Users/$Username/Library/MobileDevice/Provisioning Profiles (Var $Username motsvarar användarkontonamnet för byggservern).

Det finns två sätt att bygga en *.ipa-fil - äldre (PackageApplication) och modern (via XcAchive-skapande och export). Den första metoden anses vara föråldrad, eftersom app-filpaketeringsmodulen har tagits bort från Xcode-distributionen sedan version 8.3. För att använda den måste du kopiera modulen från den gamla Xcode (version 8.2 och tidigare) till mappen:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

Och kör sedan kommandot:

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

Därefter måste du samla in *.app-filen för applikationen:

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

Var:

-workspace — sökväg till projektfilen.

-scheme — Det system som används, specificerat i projektet.

-derivedDataPath — sökväg för att ladda ner det sammansatta programmet (*.app).

CODE_SIGN_IDENTITY — namnet på utvecklarkontot, som kan verifieras i nyckelring (iPhone-utvecklare: XXXX XXXXXXX, utan TeamID inom parentes).

Funktioner för att bygga och leverera iOS-applikationer

PROVISIONING_PROFILE — Profil-ID för att signera ansökan, som kan erhållas med kommandot:

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

Om applikationen använder en ytterligare profil (till exempel för push-meddelanden), så istället för PROVISIONING_PROFILE ange:

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

Därefter ska den resulterande *.app-filen paketeras i *.ipa. För att göra detta kan du använda ett kommando som:

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

Denna metod anses dock vara föråldrad ur Apples synvinkel. Det är relevant att skaffa *.ipa genom att exportera från applikationsarkivet.

Först måste du samla in arkivet med kommandot:

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

Skillnaderna ligger i monteringssätt och alternativ SYNCHRONOUS_SYMBOL_PROCESSING, vilket inaktiverar symbolavlastning vid byggtid.

Därefter måste vi skapa en fil med exportinställningar:

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

Var:

$Method — leveransmetod, motsvarar applikationens signaturprofiltyp, det vill säga för utveckling kommer värdet att vara utveckling, för Ad Hoc - ad-hoc och för App Store - app-store.

$BundleID — Applikations-ID, som anges i applikationsinställningarna. Du kan kontrollera med kommandot:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName и $ProfileId — inställningar för utvecklarnamn och signaturprofil-ID som användes tidigare och måste matcha värdena i exportinställningarna.

$TeamID — tiosiffrigt ID inom parentes efter utvecklarens namn, exempel: iPhone-utvecklare: …… (XXXXXXXXXX); kan kontrolleras i nyckelring.

Därefter, med hjälp av exportkommandot, får vi den nödvändiga *.ipa-filen:

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

Leverans

Nu måste den insamlade filen levereras till slutanvändaren, det vill säga installerad på enheten.

Det finns många tjänster för att distribuera utvecklings- och ad hoc-byggen, såsom HockeyApp, AppBlade och andra, men i den här artikeln kommer vi att prata om en fristående server för att distribuera applikationer.

Installation av applikationen för iOS sker i två steg:

  1. Ta emot applikationsinstallationsmanifestet via Items Service.
  2. Installation av *.ipa-filen enligt informationen som anges i manifestet via HTTPS.

Därför måste vi först generera ett installationsmanifest (filtyp *.plist) med kommandot:

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

Som du kan se innehåller manifestet nästan alla parametrar som är involverade i att bygga applikationen.

Applikationsversion ($AppVersion) kan kontrolleras med kommandot:

defaults read $ProjectDir/Info CFBundleVersion

Parameter $ipaUrl innehåller en direktlänk för att ladda ner *.ipa-filen. Från den sjunde versionen av iOS måste applikationen installeras via HTTPS. I den åttonde versionen har formatet på manifestet ändrats något: block med inställningar för applikationsikoner som

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

För att installera applikationen räcker det alltså med en enkel HTML-sida med en länk som denna:

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

För behoven hos utvecklings- och testavdelningarna har Plarium skapat sin egen bygginstallationsapplikation, som ger oss:

  • självständighet och oberoende,
  • centralisering av åtkomstkontroll och säker installation av applikationer genom "tillfälliga" dynamiskt skapade länkar,
  • expanderbar funktionalitet (det vill säga utvecklingsteamet kan vid behov integrera saknade funktioner i en befintlig applikation).

testning

Nu kommer vi att prata om pre-release testning av applikationen med hjälp av TestFlight.

Nödvändiga villkor för nedladdning är typen av App Store-signaturprofil och närvaron av genererade API-nycklar.

Det finns flera sätt att ladda ner applikationen:

  • via Xcode (Organizer),
  • via altool,
  • via Application Loader för äldre versioner av Xcode (nu Transporter).

För automatisk nedladdning används altool, som också har två auktoriseringsmetoder:

  • Appspecifikt lösenord,
  • API-nyckel.

Det är att föredra att ladda ner programmet med hjälp av API-nyckeln.

För att få API-nyckeln, gå till länk och generera en nyckel. Förutom själva nyckeln i *.p8-format kommer vi att behöva två parametrar: IssuerID och KeyID.

Funktioner för att bygga och leverera iOS-applikationer

Importera sedan den nedladdade nyckeln till byggservern:

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

Innan du laddar upp applikationen till TestFlight måste du validera applikationen, det gör vi med kommandot:

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

var apiKey и apiIssuer har fältvärden från API-nyckelgenereringssidan.

Därefter, efter framgångsrik validering, laddar vi applikationen med kommandot --upload-app med samma parametrar.

Applikationen kommer att testas av Apple inom en eller två dagar och blir sedan tillgänglig för externa testare: de kommer att skickas via e-post till länkar för installation.

Ett annat sätt att ladda ner en applikation via altool är att använda App-Specific Password.

För att få det appspecifika lösenordet måste du gå till länk och generera den i avsnittet Säkerhet.

Funktioner för att bygga och leverera iOS-applikationer

Därefter bör du skapa en byggserverpost i nyckelring med detta lösenord. Från version 11 av Xcode kan detta göras med kommandot:

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

Var:

$DeveloperName — namnet på iOS-utvecklarkontot som används för att logga in på Apples tjänster.

$AppPswd — genererat appspecifikt lösenord.

Därefter får vi värdet av parametern asc-provider och kontrollerar framgången för lösenordsimporten med kommandot:

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

Vi får utdata:

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

Som du kan se, sammanfaller det erforderliga Short Name-värdet (asc-provider) med $TeamID-parametern som vi använde när vi byggde applikationen.

För att validera och ladda applikationen till TestFlight, använd kommandot:

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

Som ett parametervärde -p du kan ta värdet $AppPswd i okrypterad (uttrycklig) form.

Men, som redan nämnts, ur prestandasynpunkt är det bättre att välja API Key för altool-auktorisering, eftersom olika versioner av Xcode har vissa problem ("ser inte" nyckelring, auktoriseringsfel under uppladdning, etc.).

Det är allt, faktiskt. Jag önskar alla inblandade framgångsrika builds och problemfria releaser i App Store.

Källa: will.com

Lägg en kommentar