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, oappId(bundle identifier) e oappName.
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 build2) Adicionar a plataforma iOS (se ainda não existir)
npx cap add ios3) Sincronizar alterações para o iOS
Quando você muda código web, plugins ou configurações do Capacitor, sincronize:
npx cap sync iosUse 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 iosIsso abre o App.xcworkspace no Xcode.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
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.tsdefineappId. - 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 iosDepois, 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.plistexplicando 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:
| Recurso | Chave no Info.plist | Exemplo de descrição |
|---|---|---|
| Câmera | NSCameraUsageDescription | “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.” |
| Microfone | NSMicrophoneUsageDescription | “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.tse rodenpx 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 iospara 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.