Funksjoner for å bygge og levere iOS-applikasjoner

I denne artikkelen deler vi erfaringen med å sette sammen og levere iOS-applikasjoner til brukere, som Plarium Krasnodar-studioet har samlet i prosessen med å feilsøke CI/CD.

Funksjoner for å bygge og levere iOS-applikasjoner

Trening

Hver person som på en eller annen måte er involvert i utviklingen av applikasjoner for Apple-enheter har allerede satt pris på den kontroversielle bekvemmeligheten til infrastrukturen. Vanskeligheter finnes overalt: fra utviklerprofilmenyen til feilsøkings- og byggeverktøyene.

Det er mange artikler om "grunnleggende" på Internett, så vi vil prøve å fremheve det viktigste. Her er det du trenger for å bygge søknaden din på en vellykket måte:

  • utviklerkonto;
  • en macOS-basert enhet som fungerer som en byggeserver;
  • generert utviklersertifikat, som vil bli videre brukt til å signere søknaden;
  • opprettet applikasjon med unik ID (betydningen av pakkeidentifikatoren bør bemerkes, fordi bruken av jokertegn-ID gjør det umulig å bruke mange funksjoner i applikasjonen, for eksempel: Associated Domains, Push Notifications, Apple Sign In og andre);
  • profil applikasjonssignaturer.

Et utviklersertifikat må genereres via nøkkelring på en hvilken som helst macOS-enhet. Type sertifikat er veldig viktig. Avhengig av applikasjonsmiljøet (Dev, QA, Staging, Production) vil det variere (Utvikling eller Distribusjon), og det samme vil typen applikasjonssignaturprofil.

Hovedtyper av profiler:

  • Utvikling - beregnet for å signere søknaden til utviklingsteamet, et utviklingssertifikat brukes (typenavn iPhone-utvikler: XXXXX);
  • Ad Hoc - beregnet for å signere en testapplikasjon og intern verifisering av QA-avdelingen, utviklerens distribusjonssertifikat brukes (typenavn iPhone-distribusjon: XXXXX);
  • App Store - utgivelsesbygg for ekstern testing via TestFlight og opplasting til App Store, utviklerens distribusjonssertifikat brukes.

Ved generering av utviklings- og ad hoc-profiler er det også indikert enhetsliste, som du kan installere en build på, som lar deg begrense tilgangen for brukere ytterligere. Det er ingen liste over enheter i App Store-profilen, siden tilgangskontroll under lukket beta-testing håndteres av TestFlight, som vil bli diskutert senere.

For klarhetens skyld kan du presentere utviklerens profil i form av en tabell nedenfor. Dette gjør det lettere å forstå hvilke parametere vi trenger for montering og hvor de skal hentes fra.

Funksjoner for å bygge og levere iOS-applikasjoner

sammenstilling

For å gjøre det enklere å skille sammenstillinger etter prosjekt og miljø bruker vi profilnavn som ${ProjectName}_${Instance}, det vil si prosjektnavn + forekomst (avhenger av applikasjonsmiljøet: Dev, QA, GD, Staging, Live, og så videre).

Når den importeres til byggeserveren, endrer profilen navn til en unik ID og flyttes til mappen /Users/$Username/Library/MobileDevice/Provisioning Profiles (hvor $Username tilsvarer brukerkontonavnet til byggeserveren).

Det er to måter å bygge en *.ipa-fil på – eldre (PackageApplication) og moderne (via XcAchive-oppretting og eksport). Den første metoden anses som foreldet siden versjon 8.3 har app-filpakkemodulen blitt fjernet fra Xcode-distribusjonen. For å bruke den må du kopiere modulen fra den gamle Xcode (versjon 8.2 og tidligere) til mappen:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

Og kjør deretter kommandoen:

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

Deretter må du samle *.app-filen til applikasjonen:

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

Hvor:

-workspace — bane til prosjektfilen.

-scheme — ordningen som er brukt, spesifisert i prosjektet.

-derivedDataPath — bane for å laste ned det sammensatte programmet (*.app).

CODE_SIGN_IDENTITY — navnet på utviklerkontoen, som kan verifiseres i nøkkelring (iPhone-utvikler: XXXX XXXXXXX, uten TeamID i parentes).

Funksjoner for å bygge og levere iOS-applikasjoner

PROVISIONING_PROFILE — Profil-ID for signering av søknaden, som kan fås med kommandoen:

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

Hvis applikasjonen bruker en tilleggsprofil (for eksempel for push-varsler), så i stedet for PROVISIONING_PROFILE indikerer:

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

Deretter skal den resulterende *.app-filen pakkes inn i *.ipa. For å gjøre dette kan du bruke en kommando som:

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

Denne metoden anses imidlertid som foreldet fra Apples synspunkt. Det er aktuelt å skaffe *.ipa ved å eksportere fra applikasjonsarkivet.

Først må du samle arkivet med kommandoen:

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

Forskjellene ligger i monteringsmetoden og alternativene SYNCHRONOUS_SYMBOL_PROCESSING, som deaktiverer symbolavlasting ved byggetidspunkt.

Deretter må vi generere en fil med eksportinnstillinger:

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

Hvor:

$Method — leveringsmetode, tilsvarer applikasjonssignaturprofiltypen, det vil si at for utvikling vil verdien være utvikling, for Ad Hoc - ad-hoc, og for App Store - app-butikk.

$BundleID — Applikasjons-ID, som er angitt i applikasjonsinnstillingene. Du kan sjekke med kommandoen:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName и $ProfileId — utviklernavn og signaturprofil-ID-innstillinger som ble brukt tidligere og må samsvare med verdiene i eksportinnstillingene.

$TeamID — tisifret ID i parentes etter utviklerens navn, eksempel: iPhone-utvikler: …… (XXXXXXXXXX); kan sjekkes i nøkkelring.

Deretter, ved å bruke eksportkommandoen, får vi den nødvendige *.ipa-filen:

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

Levering

Nå må den innsamlede filen leveres til sluttbrukeren, det vil si installert på enheten.

Det finnes mange tjenester for distribusjon av utviklings- og ad hoc-bygg, som HockeyApp, AppBlade og andre, men i denne artikkelen vil vi snakke om en frittstående server for distribusjon av applikasjoner.

Installasjon av applikasjonen for iOS skjer i 2 trinn:

  1. Motta applikasjonsinstallasjonsmanifestet gjennom Items-tjenesten.
  2. Installasjon av *.ipa-filen i henhold til informasjonen spesifisert i manifestet via HTTPS.

Derfor må vi først generere et installasjonsmanifest (filtype *.plist) med kommandoen:

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, inneholder manifestet nesten alle parameterne som er involvert i å bygge applikasjonen.

Applikasjonsversjon ($AppVersion) kan sjekkes med kommandoen:

defaults read $ProjectDir/Info CFBundleVersion

Parameter $ipaUrl inneholder en direkte lenke for å laste ned *.ipa-filen. Fra den syvende versjonen av iOS må applikasjonen installeres via HTTPS. I den åttende versjonen har formatet til manifestet endret seg litt: blokker med innstillinger for applikasjonsikoner som

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

Derfor, for å installere applikasjonen, er en enkel HTML-side med en lenke som dette nok:

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

For behovene til utviklings- og testavdelingen har Plarium laget sin egen byggeinstallasjonsapplikasjon, som gir oss:

  • autonomi og uavhengighet,
  • sentralisering av tilgangskontroll og sikker installasjon av applikasjoner gjennom "midlertidige" dynamisk opprettede lenker,
  • utvidbar funksjonalitet (det vil si at utviklingsteamet, om nødvendig, kan integrere manglende funksjoner i en eksisterende applikasjon).

Testing

Nå skal vi snakke om pre-release testing av applikasjonen ved hjelp av TestFlight.

Nødvendige betingelser for nedlasting er typen App Store-signaturprofil og tilstedeværelsen av genererte API-nøkler.

Det er flere måter å laste ned applikasjonen på:

  • via Xcode (Organisator),
  • via altool,
  • via Application Loader for eldre versjoner av Xcode (nå Transporter).

For automatisk nedlasting brukes altool, som også har to autorisasjonsmetoder:

  • App-spesifikt passord,
  • API-nøkkel.

Det er å foretrekke å laste ned applikasjonen ved hjelp av API-nøkkelen.

For å få API-nøkkelen, gå til link og generere en nøkkel. I tillegg til selve nøkkelen i *.p8-format, trenger vi to parametere: IssuerID og KeyID.

Funksjoner for å bygge og levere iOS-applikasjoner

Deretter importerer du den nedlastede nøkkelen til byggeserveren:

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

Før du laster opp applikasjonen til TestFlight, må du validere applikasjonen, vi gjør dette med kommandoen:

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

hvor apiKey и apiIssuer har feltverdier fra API-nøkkelgenereringssiden.

Deretter, etter vellykket validering, laster vi applikasjonen med kommandoen --upload-app med samme parametere.

Applikasjonen vil bli testet av Apple i løpet av én eller to dager og vil deretter bli tilgjengelig for eksterne testere: de vil få e-post til lenker for installasjon.

En annen måte å laste ned en applikasjon gjennom altool er å bruke appspesifikt passord.

For å få det appspesifikke passordet må du gå til link og generer den i sikkerhetsdelen.

Funksjoner for å bygge og levere iOS-applikasjoner

Deretter bør du opprette en byggeserverpost i nøkkelring med dette passordet. Fra versjon 11 av Xcode kan dette gjøres med kommandoen:

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

Hvor:

$DeveloperName — navnet på iOS-utviklerkontoen som ble brukt til å logge på Apple-tjenester.

$AppPswd — generert app-spesifikt passord.

Deretter får vi verdien av asc-provider-parameteren og sjekker suksessen til passordimporten med kommandoen:

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

Vi får utgangen:

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

Som du kan se, faller den nødvendige Short Name-verdien (asc-provider) sammen med $TeamID-parameteren som vi brukte da vi bygde applikasjonen.

For å validere og laste applikasjonen inn i TestFlight, bruk kommandoen:

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

Som en parameterverdi -p du kan ta verdien $AppPswd i ukryptert (eksplisitt) form.

Men som allerede nevnt, fra et ytelsessynspunkt, er det bedre å velge API Key for altool-autorisasjon, siden forskjellige versjoner av Xcode har visse problemer ("ser ikke" nøkkelring, autorisasjonsfeil under opplasting, etc.).

Det er alt, faktisk. Jeg ønsker alle involverte vellykkede bygg og problemfrie utgivelser i App Store.

Kilde: www.habr.com

Legg til en kommentar