Como desenvolver aplicativos de Mac que sejam universais

Explicação simplificada de como criar apps que funcionem em dispositivos Apple com Apple Silicon ou Intel, independente do modelo de Mac utilizado em seu desenvolvimento.

Renê Amado
Academy@EldoradoCPS
5 min readJul 2, 2020

--

Novidades WWDC 20

De acordo com os anúncios da Apple no WWDC 20, apps desenvolvidos para a arquitetura Intel continuarão funcionando nos Mac’s com Apple Silicon por meio da tradução Rosetta, que será abordada mais para a frente.

A nova versão do Xcode possui diversas novas funcionalidades que prometem facilitar o desenvolvimento para a plataforma Apple. Falando mais especificamente da transição da arquitetura dos computadores da Apple, com o Xcode 12 podemos escolher como buildar o nosso app de Mac, seja para o Mac Intel (atual), Mac com a tradução Rosetta (somente em Mac’s com Apple Silicon) e para qualquer Mac (Intel e Apple Silicon).

Com o Xcode de 12 é possível garantir que a sua aplicação para Mac estará disponível nos novos computadores com processadores Apple Silicon, não sendo necessário mudar as configurações de build para lidar com problemas de portabilidade.

Como foi anunciado, a partir deste ano, todos as aplicações de Mac devem ser universais, isto é, devem estar disponíveis para as arquiteturas Apple Silicon e Intel.

Selecionando opções de Build no Xcode 12 em um Mac com processador Intel.

O Rosetta

Caso você já possua um Mac com Apple Silicon e queira desenvolver e ofertar suas aplicações para os Mac’s Intel, é possível usar a ferramenta de tradução Rosetta, que foi concebida justamente para isso.

O Rosetta é um ambiente de tradução que possibilita rodar um aplicação desenvolvida para Mac’s Intel nos computadores com Apple Silicon perfeitamente. Ao escolher a opção Rosetta no momento de buildar o app no Xcode, sua aplicação será buildada em Intel e, em seguida, buildará em Rosetta para mostrar como essa aplicação ficaria em um Mac com arquitetura Intel. Contudo, Rosetta possui algumas limitações, não sendo possível rodar extensões de Kernel, virtualização ou AVX vector instruction.

Tratando possíveis problemas de Build

Selecionando a arquitetura de processador em que a aplicação estará disponível.

Tanto o processador arm64, utilizado no Apple Silicon, como o processador Intel, utilizado nos Mac’s desde 2005, são Little Endian. Isto é, o armazenamento na memória é feito a partir do Byte menos significativo até o Byte mais significativo. Com isso, não é necessário se preocupar com a variação da ordem dos Bytes na memória.

Além disso, arm64 possui a mesma arquitetura utilizada em aplicações iOS. Assim, será ainda mais simples para desenvolvedores que utilizem código compartilhado para aplicações de Mac e iOS.

Opção Multiplataform ao criar uma aplicação no Xcode 12.

Uma diferença significativa entre as arquiteturas Intel e arm64, é sobre o tamanho das páginas de memória. Páginas de memória são blocos de memória de um mesmo tamanho em que o computador armazena e recupera dados quando precisa utilizá-los na memória principal .

Bom, no Apple Silicon as páginas da memória possuem 16kB, enquanto nos processadores Intel o tamanho das páginas é de 4kB. Por conta disto, caso você use a constante “Page_Size” em seu código, ocorrerá um erro ao buildar o aplicativo em Rosetta, isto se deve ao fato de que essa constante não existir mais no Xcode 12.

Entretanto, podemos alterar essa constante por outras duas novas, dependendo do que deseja fazer com o valor dela. Caso queira apenas acessar o tamanho da página no momento em que a aplicação é compilada, utilize a variável “PAGE_MAX_SIZE”. Por outro lado, caso queira acessar o tamanho disponível da página atualizado dinamicamente ao longo da execução, utilize a variável “vm_page_size”.

Não é necessário se preocupar com o tamanho de página efetivamente utilizado na sua aplicação, mas, sim, com como acessar o valor desse tamanho da página. Já que, em computadores com Apple Silicon, o Rosetta disponibilizará um ambiente com páginas de 4kB para aplicações desenvolvidas para a arquitetura Intel.

Outra fonte de erro importante é o uso de bibliotecas e/ou frameworks não atualizados para serem universais. Isto é, bibliotecas que não estão disponíveis para a arquitetura de processadores Apple Silicon e Intel. Neste caso, é importante removê-los temporariamente até que o criador destes frameworks o atualize para os novos padrões da Apple e você possa atualizá-los no seu projeto.

Com esses ajustes, será possível buildar sua aplicação no modo universal, disponível para qualquer Mac com Intel ou Apple Silicon. Mas, caso sua aplicação faça uso de outros comandos mais baixo nível, como código em assembly, esses comandos deverão ser refatorados de acordo com as convenções da arquitetura arm64.

É importante ressaltar que é possível utilizar qualquer Mac para gerar aplicações universais como o Xcode 12. Contudo, para testar em tempo de execução, utilizar ferramentas de debug e o Rosetta é necessário ter um Mac com Apple Silicon.

Fazendo o Archive para a publicação do app

Fazendo o Archive de aplicações para Mac no Xcode 12.

No Xcode 12 é possível usar o “Archive Build”, que gerará automaticamente aplicações universais.

Informações sobre a aplicação após o Archive, com ênfase nas arquiteturas suportadas por ela.

Para isso, é necessário que os problemas de portabilidade, como arquivos binários externos não atualizados (frameworks, por exemplo), acessos indevidos a antiga constante “Page_Size” e problemas com a arquitetura de códigos baixo nível tenham sido resolvidos.

Com isso, os desenvolvedores agora têm acesso a três tipos de crash logs diferentes, que são gerados levando em conta os três tipos possíveis de Build. Relembrando, essas Build's são: o Rosetta, ambiente que roda aplicações feitas para a arquitetura Intel em computadores com Apple Silicon, e para os processadores Intel e Apple Silicon.

Referências

https://developer.apple.com/documentation/apple_silicon

https://developer.apple.com/documentation/xcode/porting_your_macos_apps_to_apple_silicon

https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary

https://developer.apple.com/documentation/apple_silicon/addressing_architectural_differences_in_your_macos_code

https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment

--

--

Renê Amado
Academy@EldoradoCPS

iOS Developer | Apple Developer Academy @ Eldorado and student at Universidade Estadual de Campinas