Funzionalità di assemblaggio e consegna di applicazioni iOS

In questo articolo condividiamo l'esperienza di assemblaggio e fornitura di applicazioni iOS agli utenti, che lo studio Plarium Krasnodar ha accumulato nel processo di debug CI/CD.

Funzionalità di assemblaggio e consegna di applicazioni iOS

Formazione

Ogni persona che in un modo o nell'altro è coinvolta nello sviluppo di applicazioni per i dispositivi Apple ha già apprezzato la controversa comodità dell'infrastruttura. Le difficoltà si trovano ovunque: dal menu del profilo sviluppatore agli strumenti di debug e creazione.

Ci sono molti articoli sulle “nozioni di base” su Internet, quindi cercheremo di evidenziare la cosa principale. Ecco cosa ti serve per creare la tua applicazione con successo:

  • account sviluppatore;
  • un dispositivo basato su macOS che funge da server di compilazione;
  • generato certificato di sviluppatore, che verrà ulteriormente utilizzato per firmare la domanda;
  • applicazione creata con univoco ID (è da sottolineare l'importanza del Bundle Identifier, perché l'utilizzo dell'ID jolly rende impossibile l'utilizzo di molte funzionalità dell'applicazione, ad esempio: Domini Associati, Notifiche Push, Accesso Apple ed altre);
  • profilo firme delle applicazioni.

Un certificato sviluppatore deve essere generato tramite Portachiavi su qualsiasi dispositivo macOS. Il tipo di certificato è molto importante. A seconda dell'ambiente dell'applicazione (sviluppo, QA, gestione temporanea, produzione) sarà diverso (sviluppo o distribuzione), così come il tipo di profilo di firma dell'applicazione.

Principali tipologie di profili:

  • Sviluppo: per firmare la domanda del team di sviluppo viene utilizzato un certificato di sviluppo (nome del tipo iPhone Developer: XXXXX);
  • Ad Hoc: destinato alla firma di un'applicazione di prova e alla verifica interna da parte del dipartimento QA, viene utilizzato il certificato di distribuzione dello sviluppatore (nome del tipo Distribuzione iPhone: XXXXX);
  • App Store: build di rilascio per test esterni tramite TestFlight e caricamento su App Store, viene utilizzato il certificato di distribuzione dello sviluppatore.

Viene indicato anche durante la generazione di profili di sviluppo e ad hoc elenco dei dispositivi, su cui è possibile installare una build, che consente di limitare ulteriormente l'accesso per gli utenti. Non esiste un elenco di dispositivi nel profilo App Store, poiché il controllo degli accessi durante i beta test chiusi è gestito da TestFlight, di cui parleremo più avanti.

Per chiarezza, puoi presentare il profilo dello sviluppatore sotto forma di tabella qui sotto. Ciò semplifica la comprensione di quali parametri abbiamo bisogno per l'assemblaggio e da dove ottenerli.

Funzionalità di assemblaggio e consegna di applicazioni iOS

montaggio

Per semplificare la separazione degli assiemi per progetto e ambiente, utilizziamo nomi di profilo come ${ProjectName}_${Instance}, ovvero nome progetto + istanza (dipende dall'ambiente dell'applicazione: Dev, QA, GD, Staging, Live e così via).

Una volta importato nel server di compilazione, il profilo cambia nome in un ID univoco e viene spostato nella cartella /Users/$Username/Library/MobileDevice/Provisioning Profiles (dove $Username corrisponde al nome dell'account utente del server di compilazione).

Esistono due modi per creare un file *.ipa: legacy (PackageApplication) e moderno (tramite la creazione e l'esportazione di XcAchive). Il primo metodo è considerato obsoleto, poiché dalla versione 8.3 il modulo di confezionamento dei file dell'app è stato rimosso dalla distribuzione Xcode. Per utilizzarlo è necessario copiare il modulo dal vecchio Xcode (versione 8.2 e precedenti) nella cartella:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

E poi esegui il comando:

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

Successivamente è necessario raccogliere il file *.app dell'applicazione:

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

Dove:

-workspace - percorso del file di progetto.

-scheme — lo schema utilizzato, specificato nel progetto.

-derivedDataPath — percorso per scaricare l'applicazione assemblata (*.app).

CODE_SIGN_IDENTITY — il nome dell'account sviluppatore, che può essere verificato nel Portachiavi (Sviluppatore iPhone: XXXX XXXXXXX, senza TeamID tra parentesi).

Funzionalità di assemblaggio e consegna di applicazioni iOS

PROVISIONING_PROFILE — ID del profilo per la firma della domanda, ottenibile con il comando:

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

Se l'applicazione utilizza un profilo aggiuntivo (ad esempio, per le notifiche push), invece di PROVISIONING_PROFILE indicare:

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

Successivamente, il file *.app risultante dovrebbe essere compresso in *.ipa. Per fare ciò, puoi usare un comando come:

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

Tuttavia, questo metodo è considerato obsoleto dal punto di vista di Apple. È importante ottenere *.ipa esportando dall'archivio dell'applicazione.

Per prima cosa devi raccogliere l'archivio con il comando:

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

Le differenze risiedono nel metodo di assemblaggio e nelle opzioni SYNCHRONOUS_SYMBOL_PROCESSING, che disabilita lo scaricamento dei simboli in fase di compilazione.

Successivamente dobbiamo generare un file con le impostazioni di esportazione:

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

Dove:

$Method — metodo di consegna, corrisponde al tipo di profilo della firma dell'applicazione, ovvero per Development il valore sarà development, per Ad Hoc - ad-hoc e per App Store - app-store.

$BundleID — ID dell'applicazione, specificato nelle impostazioni dell'applicazione. Puoi verificare con il comando:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName и $ProfileId - Impostazioni del nome dello sviluppatore e dell'ID del profilo della firma utilizzate in precedenza e devono corrispondere ai valori nelle impostazioni di esportazione.

$TeamID — ID di dieci cifre tra parentesi dopo il nome dello sviluppatore, ad esempio: Sviluppatore iPhone: …… (XXXXXXXXXX); può essere controllato in Portachiavi.

Successivamente, utilizzando il comando export, otteniamo il file *.ipa necessario:

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

Consegna

Ora il file raccolto deve essere consegnato all'utente finale, ovvero installato sul dispositivo.

Esistono molti servizi per la distribuzione di build di sviluppo e ad hoc, come HockeyApp, AppBlade e altri, ma in questo articolo parleremo di un server autonomo per la distribuzione delle applicazioni.

L'installazione dell'applicazione per iOS avviene in 2 fasi:

  1. Ricezione del manifesto di installazione dell'applicazione tramite il servizio Items.
  2. Installazione del file *.ipa secondo le informazioni specificate nel manifest tramite HTTPS.

Pertanto, dobbiamo prima generare un manifest di installazione (tipo di file *.plist) con il comando:

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

Come puoi vedere, il manifest contiene quasi tutti i parametri coinvolti nella creazione dell'applicazione.

Versione dell'applicazione ($AppVersion) può essere controllato con il comando:

defaults read $ProjectDir/Info CFBundleVersion

Parametro $ipaUrl contiene un collegamento diretto per scaricare il file *.ipa. A partire dalla settima versione di iOS l'applicazione deve essere installata tramite HTTPS. Nell'ottava versione, il formato del manifest è leggermente cambiato: blocchi con impostazioni per le icone delle applicazioni come

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

Pertanto, per installare l'applicazione è sufficiente una semplice pagina HTML con un collegamento come questo:

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

Per le esigenze dei reparti di sviluppo e testing, Plarium ha realizzato la propria applicazione di installazione build, che ci garantisce:

  • autonomia e indipendenza,
  • centralizzazione del controllo degli accessi e installazione sicura delle applicazioni attraverso collegamenti “temporanei” creati dinamicamente,
  • funzionalità espandibile (ovvero il team di sviluppo, se necessario, può integrare le funzioni mancanti in un'applicazione esistente).

Test

Ora parleremo del test pre-rilascio dell'applicazione utilizzando TestFlight.

Le condizioni richieste per il download sono il tipo di profilo di firma dell'App Store e la presenza di chiavi API generate.

Esistono diversi modi per scaricare l'applicazione:

  • tramite Xcode (Organizzatore),
  • tramite altool,
  • tramite Application Loader per le versioni precedenti di Xcode (ora Transporter).

Per il download automatico viene utilizzato altool, che dispone anche di due metodi di autorizzazione:

  • Password specifica per l'app,
  • Chiave API.

È preferibile scaricare l'applicazione utilizzando la chiave API.

Per ottenere la chiave API, vai a collegamento e generare una chiave. Oltre alla chiave stessa in formato *.p8, avremo bisogno di due parametri: IssuerID e KeyID.

Funzionalità di assemblaggio e consegna di applicazioni iOS

Successivamente, importa la chiave scaricata sul server di compilazione:

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

Prima di caricare l'applicazione su TestFlight, è necessario convalidare l'applicazione, lo facciamo con il comando:

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

Где apiKey и apiIssuer avere valori di campo dalla pagina di generazione della chiave API.

Successivamente, una volta completata con successo la convalida, carichiamo l'applicazione con il comando --upload-app con gli stessi parametri.

L'applicazione verrà testata da Apple entro uno o due giorni e sarà poi disponibile ai tester esterni: verranno inviati via email i link per l'installazione.

Un altro modo per scaricare un'applicazione tramite altool consiste nell'utilizzare la password specifica per l'app.

Per ottenere la password specifica per l'app devi andare su collegamento e generarlo nella sezione Sicurezza.

Funzionalità di assemblaggio e consegna di applicazioni iOS

Successivamente, dovresti creare un record del server di build in Portachiavi con questa password. Dalla versione 11 di Xcode questo può essere fatto con il comando:

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

Dove:

$DeveloperName — il nome dell'account sviluppatore iOS utilizzato per accedere ai servizi Apple.

$AppPswd - password specifica per l'app generata.

Successivamente, otteniamo il valore del parametro asc-provider e controlliamo il successo dell'importazione della password con il comando:

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

Otteniamo l'output:

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

Come puoi vedere, il valore del nome breve richiesto (asc-provider) coincide con il parametro $TeamID che abbiamo utilizzato durante la creazione dell'applicazione.

Per convalidare e caricare l'applicazione in TestFlight, utilizzare il comando:

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

Come valore di parametro -p puoi prenderne il valore $AppPswd in forma non crittografata (esplicita).

Tuttavia, come già accennato, dal punto di vista delle prestazioni, è meglio scegliere API Key per l'autorizzazione altool, poiché diverse versioni di Xcode presentano alcuni problemi (“non vede” il portachiavi, errori di autorizzazione durante il caricamento, ecc.).

Questo è tutto, in realtà. Auguro a tutti coloro che sono coinvolti build di successo e rilasci senza problemi nell'App Store.

Fonte: habr.com

Aggiungi un commento