Desenvolvimento iOS com o meu Mac desligado
por Marcello Gonzatto Birkan, Fundador
Desenvolver para iOS sempre teve um pré-requisito físico: o Mac ligado na minha frente. Xcode, simulador, um cabo, eu ali. Esta semana eu tirei o Mac do caminho e o ciclo continuou inteiro — escrever o Swift, compilar, instalar num iPhone, percorrer a tela, fotografar o que apareceu e abrir o PR.
Quem faz isso é uma thread do Claude Projects, que roda numa VM Linux sem Xcode e sem simulador. O que faltava, o Revyl preenche: o CLI manda o código para um runner macOS que compila o .app, e depois abre um iPhone simulado na nuvem que a própria thread controla e fotografa. Como tudo isso é uma conversa, o aparelho de onde eu escrevo deixa de importar — esta eu conduzi do desktop, mas mandar a tarefa do celular é o mesmo gesto.
O que aconteceu de verdade
Testei no Coloreku, um jogo de cores que eu estou fazendo em SwiftUI. Mandei uma tarefa e fui fazer outra coisa.
A tarefa desta vez foi uma correção, e é honesto dizer isso: o que eu já rodei de ponta a ponta é um bug, não uma feature nova. Mas nada no laço depende disso. Escrever código, compilar, instalar, percorrer a tela e voltar com prova é o mesmo trabalho, seja a mudança de uma linha ou de uma tela inteira.
O bug era de ordem: com o Modo Rápido desligado, tocar numa célula vazia já pintava a célula, quando deveria apenas selecioná-la e esperar a cor vir da paleta. O que voltou:
tapCellreordenado noGameViewModel, que é onde a ordem errada estava- 12 testes escritos para os dois modos de entrada
- build remoto e device na nuvem executados, com o fluxo percorrido de ponta a ponta
- duas fotos da tela, tiradas durante o teste
- PR #4 aberto, +233 −27, checagens verdes

As fotos são a parte que mudou o meu jeito de trabalhar. A primeira mostra o tabuleiro 2×2 com o azul escolhido na paleta e a célula vazia tocada: ela ganhou só o contorno tracejado de seleção, e o contador de MOVES continua em 0. Antes da correção aquele toque já teria pintado. A segunda mostra o toque seguinte na paleta, a cor entrando, MOVES indo para 1, e o detector marcando em vermelho os três azuis em conflito.
Uma checagem verde diz que o código rodou. A foto diz que a tela ficou do jeito que eu pedi. São afirmações diferentes, e até agora só a primeira cabia numa thread.
O que ainda não funciona
Os 12 testes ainda não rodam. O alvo ColorekuTests não tem nenhum arquivo fonte, então a pasta de testes inteira não é compilada — um problema meu, anterior a tudo isso, que o agente encontrou e me avisou em vez de fingir que não existia. O PR está aberto esperando a minha revisão; não foi mergeado.
E o cerco é mais apertado do que parece:
- Só simulador. Câmera, sensores, push e desempenho real continuam fora do alcance.
- Swift itera devagar. Cada mudança exige um build remoto novo. Isso serve para entregar e provar uma mudança, não para ajuste fino de interface.
- Um device por vez no plano grátis. Se duas threads tentarem ao mesmo tempo, elas esperam ou falham, então eu limito a uma thread de verificação de cada vez.
- A conta chega em dois lugares: os tokens das threads e os minutos de simulador, a US$ 0,15 por minuto acima da cota grátis. Um device esquecido ligado é o erro mais caro que dá para cometer aqui.
- O Xcode do runner para na 26.5. Um app que usa o SDK do iOS 27 simplesmente não compila lá.
Vale dizer com todas as letras: nem a Anthropic nem o Revyl afirmam ter testado esse fluxo de ponta a ponta. A documentação do próprio Revyl é explícita em não garantir que uma execução completa tenha sido feita. Por isso eu validei cada peça separadamente antes de confiar um projeto a ela, e por isso este post fala de um app e um PR, não de um processo.
As três coisas que fizeram funcionar
A configuração em si é curta, e quase tudo que deu trabalho foi descobrir onde ela vazava.
O CLI precisa entrar no PATH no script de setup do ambiente, não no meio da sessão. A chave de API vai como variável de ambiente, nunca no repositório. E a rede do ambiente precisa deixar passar o backend do Revyl explicitamente — a falha aqui aparece como um comando que demora dez segundos e morre sem explicar nada.
A terceira é a que eu não teria adivinhado: o CLAUDE.md do projeto precisa de uma seção de nuvem. O do Coloreku, como o de todos os meus apps, manda usar o MCP do Xcode e cair no xcodebuild se ele não estiver disponível. Na nuvem os dois fallbacks falham, porque nenhum dos dois existe. Uma instrução escrita para o Mac vira uma armadilha silenciosa quando a sessão está em outro lugar, e a regra nova — de tirar uma a três fotos da mudança visual durante o teste que já está rodando, entregá-las na conversa e não commitar nenhuma — foi junto no mesmo PR.
O que vem agora
O próximo é o Looté, que é o caso difícil: o CLAUDE.md dele é construído inteiro em volta do MCP do Xcode, e o deployment target é iOS 26.5, exatamente no limite da imagem do runner. Se ele passar, a regra vira padrão nos meus repositórios iOS, e a próxima tarefa que eu mandar vai ser uma feature.
Se você tem um app iOS parado esperando alguém ter tempo de abrir o Xcode, me conta.