Recursos de montagem e entrega de aplicativos iOS

Neste artigo, Maxim Shestakov, engenheiro de DevOps no estúdio Plarium Krasnodar, compartilha sua experiência na criação e fornecimento de aplicativos iOS para usuários acumulados durante a depuração de CI / CD.



Treinamento


Todo mundo conectado ao desenvolvimento de aplicativos para dispositivos Apple já conseguiu apreciar a usabilidade controversa da infraestrutura. As dificuldades estão por toda parte: do menu de perfil do desenvolvedor às ferramentas de depuração e montagem.

Existem muitos artigos sobre o básico na rede, portanto, tentaremos destacar o principal. Aqui está o que você precisa para criar o aplicativo com sucesso:

  • Conta de desenvolvedor ;
  • dispositivo baseado em macOS atuando como um servidor de compilação;
  • o certificado de desenvolvedor gerado , que será usado para assinar o aplicativo;
  • aplicativo criado com um ID exclusivo (a importância do Identificador de pacote configurável deve ser observada, porque o uso do ID curinga impossibilita o uso de muitas funções do aplicativo, por exemplo: Domínios Associados, Notificações Push, Login da Apple e outros);
  • perfil de assinatura do aplicativo.

O certificado de desenvolvedor deve ser gerado através do Keychain em qualquer dispositivo macOS. O tipo de certificado é muito importante. Dependendo do ambiente do aplicativo (Dev, QA, Staging, Produção), ele será diferente (Desenvolvimento ou Distribuição), bem como o tipo de perfil de assinatura do aplicativo.

Os principais tipos de perfis:

  • Desenvolvimento - projetado para assinar o aplicativo da equipe de desenvolvimento, usando o certificado de Desenvolvimento (nome do formulário iPhone Developer: XXXXX);
  • Ad Hoc - destinado à assinatura de um aplicativo de teste e verificação interna pelo departamento de controle de qualidade, usando o certificado de distribuição do desenvolvedor (nome do tipo de distribuição do iPhone: XXXXX);
  • App Store - versão lançada para testes externos através do TestFlight e upload para a App Store, usando o certificado de distribuição do desenvolvedor.

Ao gerar perfis de Desenvolvimento e Ad Hoc, também é indicada uma lista de dispositivos nos quais você pode instalar a compilação, o que permite restringir ainda mais o acesso dos usuários. O perfil da App Store não possui uma lista de dispositivos, pois o TestFlight é responsável pelo controle de acesso durante o teste beta fechado, que será discutido mais adiante.

Para maior clareza, você pode apresentar o perfil do desenvolvedor na forma de um tablet abaixo. É mais fácil entender quais parâmetros para a montagem precisamos e onde obtê-los.



Montagem


Para facilitar a separação de montagens por projeto e ambiente, usamos os nomes dos perfis da exibição ${ProjectName}_${Instance}, ou seja, o nome da instância do projeto + (depende do ambiente do aplicativo: Dev, QA, GD, Staging, Live e assim por diante).

Ao importar para um servidor de construção, o perfil altera seu nome para um ID exclusivo e move-se para a pasta /Users/$Username/Library/MobileDevice/Provisioning Profiles(onde $Usernamecorresponde ao nome da conta do usuário do servidor de construção).

Existem duas maneiras de criar o arquivo * .ipa - obsoleto (PackageApplication) e moderno (por meio da criação e exportação do XcAchive). O primeiro método é considerado obsoleto, pois a partir da versão 8.3, o módulo de empacotamento de arquivos do aplicativo foi removido da distribuição do Xcode. Para usá-lo, você precisa copiar o módulo do Xcode antigo (versão 8.2 e anterior) para a pasta:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

E, em seguida, execute o comando:

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

Em seguida, você precisa coletar o arquivo * .app do aplicativo:

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

Onde:

-workspace- caminho para o arquivo do projeto.

-scheme- circuito usado especificado no projeto.

-derivedDataPath- o caminho para descarregar o aplicativo montado (* .app).

CODE_SIGN_IDENTITY- o nome da conta de desenvolvedor que pode ser verificada no Keychain (desenvolvedor do iPhone: XXXX XXXXXXX, sem o TeamID entre colchetes).



PROVISIONING_PROFILE- O ID do perfil para assinar o aplicativo, que pode ser obtido com o comando:

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

Se o aplicativo usar um perfil adicional (por exemplo, para notificações push), PROVISIONING_PROFILEindique:

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

Em seguida, o arquivo * .app resultante deve ser empacotado em * .ipa. Para fazer isso, você pode usar um comando do formulário:

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

No entanto, esse método é considerado obsoleto do ponto de vista da Apple. É relevante obter * .ipa exportando do arquivo do aplicativo.

Primeiro você precisa coletar o arquivo morto com o 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

As diferenças estão no método de montagem e na opção SYNCHRONOUS_SYMBOL_PROCESSINGque desativa o descarregamento de caracteres durante a montagem.

Em seguida, precisamos gerar um arquivo com configurações de exportação:

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

Onde:

$Method- o método de entrega corresponde ao tipo de perfil de assinatura do aplicativo, ou seja, para Desenvolvimento, o valor será desenvolvimento, para Ad Hoc - ad-hoc e para a App Store - loja de aplicativos.

$BundleID- O ID do aplicativo especificado nas configurações do aplicativo. Você pode verificar com o comando:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName $ProfileId- configurações para o nome do desenvolvedor e o ID do perfil de assinatura que foram usados ​​anteriormente e devem corresponder aos valores nas configurações de exportação.

$TeamID- ID de dez dígitos entre colchetes após o nome do desenvolvedor, por exemplo: Desenvolvedor do iPhone: ....... (XXXXXXXXXX); pode verificar no chaveiro.

Em seguida, usando o comando export, obtemos o arquivo * .ipa necessário:

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

Entrega


Agora, o arquivo montado deve ser entregue ao usuário final, ou seja, instalado no dispositivo.

Para a distribuição de desenvolvimento e compilações Ad Hoc, existem muitos serviços como HockeyApp, AppBlade e outros, mas neste artigo falaremos sobre um servidor autônomo para distribuição de aplicativos.

A instalação do aplicativo para iOS ocorre em 2 etapas:

  1. Obtenção do manifesto de instalação do aplicativo por meio do Serviço de Itens.
  2. Instalando o arquivo * .ipa de acordo com as informações especificadas no manifesto via HTTPS.

Portanto, para iniciantes, precisamos gerar o manifesto de instalação (tipo de arquivo * .plist) com o 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

Como você pode ver, o manifesto contém quase todos os parâmetros envolvidos na montagem do aplicativo.

A versão do aplicativo ( $AppVersion) pode ser verificada com o comando:

defaults read $ProjectDir/Info CFBundleVersion

O parâmetro $ipaUrlcontém um link direto para baixar o arquivo * .ipa. A partir da sétima versão do iOS, o aplicativo deve ser instalado via HTTPS. Na oitava versão, o formato do manifesto mudou um pouco: os blocos com configurações para ícones de aplicativos do formulário foram removidos

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

Assim, para instalar o aplicativo, basta uma página html simples com um link do formulário:

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

Para as necessidades dos departamentos de desenvolvimento e teste, a Plarium criou seu aplicativo de instalação de compilação, que nos fornece:

  • autonomia e independência,
  • controle de acesso centralizado e instalação segura de aplicativos por meio de links "temporários" criados dinamicamente,
  • funcionalidade extensível (ou seja, a equipe de desenvolvimento, se necessário, pode integrar as funções ausentes em um aplicativo existente).

Teste


Agora, falaremos sobre o teste de aplicativos de pré-lançamento usando o TestFlight .

Os pré-requisitos para o download são o tipo de perfil de assinatura da App Store e a presença de chaves de API geradas.

Existem várias maneiras de baixar o aplicativo:

  • via Xcode (Organizer),
  • através do altool,
  • via Application Loader para versões mais antigas do Xcode (agora Transporter).

Para carregamento automático, é utilizado altool, que também possui dois métodos de autorização:

  • Senha específica do aplicativo,
  • Chave API

É preferível fazer o download do aplicativo usando a API Key.

Para obter a chave da API, siga o link e gere a chave. Além da própria chave no formato * .p8, precisaremos de dois parâmetros: IssuerID e KeyID.



Em seguida, importamos a chave baixada para o servidor de compilação:

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

Antes de carregar o aplicativo no TestFlight, você precisa validar o aplicativo, faça isso com o comando:

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

Onde apiKeye apiIssuerpossui valores de campo na página de geração de chave da API.

Em seguida, após a validação bem-sucedida, carregamos o aplicativo com um comando --upload-appcom os mesmos parâmetros.

O aplicativo será testado pela Apple dentro de um a dois dias e depois estará disponível para testadores externos: eles receberão links de e-mail para instalação.

Outra maneira de baixar o aplicativo através do altool é usar a senha específica do aplicativo.

Para obter a senha específica do aplicativo, siga o link e gere-o na seção Segurança.



Em seguida, crie um registro do servidor de compilação no Keychain com essa senha. A partir da versão 11 do Xcode, isso pode ser feito com o comando:

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

Onde:

$DeveloperNameé o nome da conta de desenvolvedor do iOS usada para fazer login nos serviços da Apple.

$AppPswd- Senha específica do aplicativo gerada.

Em seguida, obtemos o valor do parâmetro asc-provider e verificamos o sucesso da importação da senha com o comando:

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

Temos a conclusão:

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

Como você pode ver, o valor desejado de Nome Curto (provedor ascendente) corresponde ao parâmetro $ TeamID que usamos ao criar o aplicativo.

Para validar e carregar o aplicativo no TestFlight, use o comando:

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

Como um valor de parâmetro, -pvocê pode pegar o valor $AppPswdna forma não criptografada (explícita).

No entanto, como já mencionado, do ponto de vista da operabilidade, é melhor selecionar a Chave da API para autorização de altool, pois em diferentes versões do Xcode são encontrados certos problemas (ele não "vê" o Keychain, erros de autorização durante o descarregamento, etc.).

Isso, de fato, é tudo. Desejo a todos envolvidos em compilações bem-sucedidas e lançamentos sem problemas na App Store.

All Articles