Build iOS com Ionic e Capacitor: Xcode, perfis e distribuição

Capítulo 20

Tempo estimado de leitura: 9 minutos

+ Exercício

Visão geral do pipeline iOS no Ionic + Capacitor

No iOS, o app Ionic roda dentro de um projeto nativo gerado pelo Capacitor. Você desenvolve a UI em HTML/CSS/TypeScript, mas para instalar em um iPhone/iPad e para distribuir (TestFlight/App Store), o build final passa pelo Xcode. Na prática, você vai: (1) sincronizar o projeto web para o iOS, (2) abrir o workspace no Xcode, (3) ajustar identificadores e configurações do app, (4) configurar assinatura (signing) e perfis, (5) compilar e instalar em dispositivo, e (6) gerar um arquivo de distribuição (via Archive) para envio.

O que o Capacitor gera no iOS

  • ios/App: projeto nativo iOS.
  • ios/App/App.xcworkspace: workspace do Xcode (use este, não o .xcodeproj).
  • capacitor.config.ts: define, entre outras coisas, o appId (bundle identifier) e o appName.

Pré-requisitos específicos do iOS

  • macOS com Xcode instalado.
  • Conta Apple Developer (para rodar em dispositivo físico e distribuir). Para simulador, a exigência é menor, mas para recursos e testes reais, use dispositivo.
  • Dispositivo iOS conectado (opcional, mas recomendado).

Passo a passo: gerar e sincronizar o projeto iOS

1) Garantir que o build web está atualizado

Antes de abrir no Xcode, gere o build web e sincronize com o projeto iOS.

ionic build

2) Adicionar a plataforma iOS (se ainda não existir)

npx cap add ios

3) Sincronizar alterações para o iOS

Quando você muda código web, plugins ou configurações do Capacitor, sincronize:

npx cap sync ios

Use sync para copiar assets web e atualizar plugins nativos. Se você só mudou o código web, npx cap copy ios também funciona, mas sync é mais completo.

4) Abrir no Xcode

npx cap open ios

Isso abre o App.xcworkspace no Xcode.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Ajustes essenciais no Xcode: bundle identifier, versão e time

Bundle Identifier (appId) e o que ele impacta

O bundle identifier é o identificador único do app no ecossistema Apple, no formato de domínio reverso (ex.: com.suaempresa.seuapp). Ele precisa ser único e deve bater com o App ID registrado no Apple Developer.

  • No Capacitor: capacitor.config.ts define appId.
  • No Xcode: em Targets > App > Signing & Capabilities, o campo Bundle Identifier deve refletir o mesmo valor.

Se você alterar o appId no capacitor.config.ts, rode:

npx cap sync ios

Depois, confirme no Xcode se o Bundle Identifier foi atualizado.

Versão (Marketing Version) e Build Number

No Xcode, em Targets > App > General:

  • Version (ex.: 1.2.0): a versão que o usuário vê.
  • Build (ex.: 45): número incremental para cada envio ao TestFlight/App Store.

Regra prática: ao enviar um novo build para TestFlight/App Store, incremente o Build. Ao lançar uma nova versão pública, incremente a Version e também o Build.

Team (time) e assinatura automática

Em Signing & Capabilities:

  • Selecione o Team (sua conta Apple Developer).
  • Ative Automatically manage signing para simplificar no início.

Com assinatura automática, o Xcode tenta criar/baixar certificados e perfis compatíveis para o bundle identifier e o tipo de build (Debug/Release).

Permissões, descrições de uso e Capabilities

Entendendo a diferença: permissões vs capabilities

  • Permissões (Privacy Usage Descriptions): textos obrigatórios no Info.plist explicando por que o app acessa câmera, fotos, localização etc. Sem isso, o app pode crashar ao solicitar acesso.
  • Capabilities: habilitam serviços do iOS (Push Notifications, Sign in with Apple, Associated Domains, Background Modes, etc.). Muitas exigem configuração no Apple Developer e no Xcode.

Onde editar o Info.plist

No Xcode, abra Targets > App > Info (ou o arquivo Info.plist) e adicione as chaves de privacidade conforme os recursos usados. Exemplos comuns:

RecursoChave no Info.plistExemplo de descrição
CâmeraNSCameraUsageDescription“Precisamos da câmera para tirar fotos do seu perfil.”
Fotos (leitura)NSPhotoLibraryUsageDescription“Precisamos acessar suas fotos para você selecionar imagens.”
Fotos (salvar)NSPhotoLibraryAddUsageDescription“Precisamos salvar imagens na sua galeria quando você exportar.”
Localização (quando em uso)NSLocationWhenInUseUsageDescription“Usamos sua localização para mostrar pontos próximos.”
MicrofoneNSMicrophoneUsageDescription“Precisamos do microfone para gravar áudio.”

Boas práticas para as descrições:

  • Seja específico sobre a funcionalidade (evite textos genéricos).
  • Não prometa algo que não faz (pode causar reprovação).
  • Se o recurso é opcional, explique o benefício.

Habilitando Capabilities no Xcode

Em Targets > App > Signing & Capabilities, clique em + Capability e adicione o que precisar. Exemplos:

  • Push Notifications: habilita push; geralmente exige também Background Modes > Remote notifications e configuração no Apple Developer.
  • Associated Domains: para Universal Links; exige configurar domínios e arquivos de associação no servidor.
  • Background Modes: para tarefas específicas em background (use com cuidado).

Se uma capability exigir entitlements, o Xcode cria/atualiza o arquivo .entitlements do target.

Assinatura no iOS: conceitos práticos (sem mistério)

O que você precisa para rodar em dispositivo e distribuir

Para instalar em um iPhone real e para distribuir, o iOS exige que o app seja assinado. Os elementos principais são:

  • Certificate (certificado): identifica quem assina o app. Tipos comuns: Development e Distribution.
  • App ID: registro do bundle identifier no Apple Developer (pode ser explícito ou com wildcard; para a maioria dos apps, use explícito).
  • Provisioning Profile (perfil): “pacote” que liga App ID + certificado + (no caso de desenvolvimento) lista de dispositivos autorizados.

Development vs Distribution (na prática)

  • Development: para rodar em dispositivos específicos durante desenvolvimento/testes internos. Exige que o dispositivo esteja registrado no portal (UDID) quando não se usa certos fluxos automáticos.
  • Distribution: para distribuir via TestFlight/App Store. Não é limitado por lista de dispositivos; é voltado para publicação.

Assinatura automática vs manual

  • Automática: o Xcode cria/gerencia certificados e perfis, reduzindo erros. Ideal para começar e para times pequenos.
  • Manual: você escolhe explicitamente certificados e perfis. Útil em CI/CD, empresas com controle rígido, múltiplos targets/ambientes.

Mesmo usando assinatura automática, é importante entender que o bundle identifier precisa existir/ser válido no Apple Developer e que capabilities podem exigir permissões extras no portal.

Rodar no simulador e em dispositivo físico

Simulador

No Xcode, selecione um simulador (ex.: iPhone 15) e clique em Run. O simulador não cobre todos os comportamentos (câmera real, notificações push completas, sensores), mas é ótimo para validação rápida.

Dispositivo físico

Passos típicos:

  • Conecte o iPhone via cabo (ou configure wireless debugging).
  • No Xcode, selecione o dispositivo no topo.
  • Em Signing & Capabilities, selecione o Team e mantenha assinatura automática.
  • Se for a primeira vez, no iPhone vá em Ajustes > Geral > VPN e Gerenciamento de Dispositivo (ou “Gerenciamento de Perfis”) e confie no desenvolvedor, se solicitado.

Se o Xcode reclamar de “No matching provisioning profiles”, normalmente é bundle identifier incorreto, time errado, ou capability habilitada sem permissão no portal.

Gerar build de distribuição (Archive) e enviar para TestFlight/App Store

1) Usar configuração Release

Para distribuição, você normalmente arquiva em Release. No Xcode, selecione Any iOS Device (arm64) (ou um dispositivo real) como destino para habilitar Archive.

2) Archive

No menu: Product > Archive. Ao finalizar, abre o Organizer com o archive gerado.

3) Validar e distribuir

No Organizer:

  • Validate App: checa assinatura, entitlements e alguns requisitos.
  • Distribute App: escolha App Store Connect para enviar ao TestFlight/App Store.

Você precisará de:

  • Bundle identifier registrado e associado a um app no App Store Connect.
  • Versão e build number coerentes (build number não pode repetir para o mesmo app).

4) TestFlight

Após o upload, o processamento ocorre no App Store Connect. Em seguida, você libera para testadores internos/externos. Testes externos podem exigir revisão.

Checklist de conformidade antes de enviar

Identidade e versionamento

  • Bundle Identifier correto e estável (não mudar entre builds do mesmo app publicado).
  • Version e Build incrementados corretamente.
  • Display Name (nome exibido) revisado.

Privacidade e permissões (Info.plist)

  • Toda permissão solicitada tem chave de uso correspondente (ex.: câmera, fotos, localização, microfone).
  • Textos de uso claros, específicos e alinhados ao comportamento real do app.
  • Não declarar permissões que o app não usa (reduz risco de questionamento e melhora confiança).

Capabilities e entitlements

  • Capabilities habilitadas no Xcode correspondem ao que foi habilitado no Apple Developer.
  • Se usar push, verifique se Push Notifications está habilitado e se o ambiente (dev/prod) está coerente.
  • Associated Domains configurado corretamente (domínios e arquivos no servidor).

Assinatura e distribuição

  • Team correto selecionado.
  • Provisioning e certificados válidos (não expirados).
  • Archive feito com destino apropriado (Any iOS Device/Device real).

Troubleshooting típico (erros comuns e como resolver)

1) “No matching provisioning profiles found”

  • Confirme o Bundle Identifier (Xcode e capacitor.config.ts).
  • Selecione o Team correto.
  • Ative Automatically manage signing e tente novamente.
  • Se houver capabilities, verifique se estão habilitadas no Apple Developer para esse App ID.

2) “Signing for ‘App’ requires a development team”

  • Em Signing & Capabilities, selecione um Team.
  • Garanta que você está logado no Xcode em Settings/Accounts.

3) App fecha ao tentar acessar câmera/fotos/localização

  • Falta a chave de privacidade no Info.plist (ex.: NSCameraUsageDescription).
  • Adicione a chave e rode novamente.

4) “Bundle identifier is not available” ou conflito de identificador

  • Escolha um bundle identifier único (ex.: inclua nome da empresa/projeto).
  • Atualize no capacitor.config.ts e rode npx cap sync ios.

5) “Archive” desabilitado no Xcode

  • Selecione Any iOS Device (arm64) ou um dispositivo físico como destino (não simulador).
  • Confirme se o esquema selecionado é o do app.

6) Erros após instalar plugin Capacitor (build falha no Xcode)

  • Rode npx cap sync ios para atualizar dependências nativas.
  • No Xcode, faça File > Packages > Reset Package Caches se estiver usando SPM, ou limpe build (Product > Clean Build Folder).
  • Feche e reabra o .xcworkspace.

7) “App Store Connect Operation Error” no upload

  • Verifique se o app existe no App Store Connect e se o bundle identifier corresponde.
  • Incremente o Build (não pode repetir).
  • Confirme que você está usando assinatura de distribuição apropriada (geralmente gerenciada automaticamente pelo Xcode, ou manualmente com perfil de distribuição).

8) Problemas com permissões em iOS (comportamento diferente do Android)

  • No iOS, a ausência de descrição de uso pode causar crash ao solicitar permissão.
  • Algumas permissões têm variações (ex.: localização “When In Use” vs “Always”); declare apenas o necessário.

Fluxo recomendado de trabalho (resumo operacional)

  • Atualizou o app web: ionic build + npx cap sync ios.
  • Abra no Xcode: npx cap open ios.
  • Revise Bundle Identifier, Version/Build, Team.
  • Garanta Info.plist com descrições de uso e capabilities necessárias.
  • Teste em dispositivo físico.
  • Archive e envio via Organizer para TestFlight/App Store.

Agora responda o exercício sobre o conteúdo:

Ao alterar o appId (bundle identifier) no capacitor.config.ts, qual ação garante que o projeto iOS seja atualizado corretamente antes de conferir o Bundle Identifier no Xcode?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Ao mudar o appId, é recomendado rodar npx cap sync ios para aplicar a atualização no projeto nativo, copiando assets e atualizando plugins/configurações. Depois, confirme no Xcode se o Bundle Identifier refletiu o novo valor.

Próximo capitúlo

Publicação e manutenção de apps Ionic: versionamento, atualizações e boas práticas finais

Arrow Right Icon
Capa do Ebook gratuito Ionic para Iniciantes: aplicativos híbridos com HTML, CSS e TypeScript
95%

Ionic para Iniciantes: aplicativos híbridos com HTML, CSS e TypeScript

Novo curso

21 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.