Entender o processo de build de uma aplicação iOS é a chave para se tornar cada vez mais independente do XCode nas aplicações. Neste artigo, em apenas 5 passos, você compreenderá melhor os enigmas dessa plataforma.


A menos que você nunca tenha trabalhado com aplicações iOS, atire a primeira pedra aqueles que não se depararam, em algum momento, com um erro absolutamente sem sentido vindo do XCode ou um comportamento inesperado da aplicação já em tempo de execução.

Como resultado desses comportamentos, o primeiro caminho é sempre a busca por uma solução mirabolante no stackoverflow ou qualquer outro fórum de desenvolvimento. Aí você resolve o problema pontual, mas não faz a menor ideia do porque deu certo ou errado.

Chegou a hora de mudar esse cenário e entender como as coisas funcionam por detrás da pomposa interface do XCode.

1º passo – Teste de funcionamento

Por mais que a ideia de não usar o XCode para gerar uma aplicação iOS pareça excitante, infelizmente isso ainda não é possível.

Isso acontece porque, mesmo sem abri-lo, alguns executáveis vindos de seu toolbox serão necessários. Por exemplo: o swiftc.

E começaremos exatamente pelo teste de funcionamento do swiftc. Serão 3 comandos:

  1. Criaremos um arquivo swift chamado SwiftFile.swift com o conteúdo de um print de uma soma (2 + 2).
  2. O compilador do swift irá gerar um executável baseado no arquivo SwiftFile.swift
  3. O executável será acionado e apresentará o resultado esperado da soma (4)
echo “print(2 + 2)” > SwiftFile.swift
swiftc SwiftFile.swift
./SwiftFile

2º passo – Geração do aplicativo

Agora que já verificamos o funcionamento do executável, vamos criar nossa aplicação.

Primeiramente, crie uma pasta com o nome do seu aplicativo e extensão .app. Exemplo: IterisApp.app.

<code bash>mkdir IterisApp.app</code>

Em seguida, crie o arquivo Info.plist

<?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>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>IterisApp</string>
	<key>CFBundleIdentifier</key>
	<string>br.com.iteris.app</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>IterisApp</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~iPad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>

Observações:
O arquivo deve ser colocado dentro da pasta IterisApp.app., sendo que:

  • CFBundleExecutable: IterisApp é o nome do executável.
  • CFBundleIdentifier: br.com.iteris.app é o identificador único da aplicação.
  • CFBundleExecutable: APPL é o que sinaliza que estamos criar uma aplicação mobile.

3º passo – Criação dos arquivos essenciais

Uma vez que a aplicação esteja criada, passaremos para a elaboração de dois arquivos essenciais.

Iniciaremos com o arquivo main.swift:

import UIKit
UIApplicationMain(
    CommandLine.argc,
    CommandLine.unsafeArgv,
    nil,
    NSStringFromClass(AppDelegate.self)
)

E depois, daremos continuidade com o arquivo AppDelegate.swift, com o texto Iteris Anywhere and Together centralizado em um fundo branco.

import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        
        let vc = UIViewController()
        vc.view.backgroundColor = .white

        self.window?.rootViewController = vc
        self.window?.makeKeyAndVisible()

        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "Iteris Anywhere and Together"

        vc.view.addSubview(label)

        label.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true

        return true
    }
}

4º passo – Compilação dos arquivos

Estamos quase chegando ao final, isto é, chegou o momento de compilarmos os arquivos AppDelegate e main.swift.

SDK = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.0.sdk

ARCH_TARGET = x86_64-apple-ios14.0-simulator

swiftc main.swift AppDelegate.swift \
-target $(ARCH_TARGET) -sdk $(SDK) \
-o IterisApp

A princípio, antes de continuarmos, perceba que criamos duas variáveis: SDK e ARCH_TARGET

  • SDK: aponta aonde esta o SDK do IOS e qual a versão desejada. 
  • ARCH_TARGET : aponta pra qual arquitetura o executável será compilado.

Para o SDK, optamos pelo uso da versão 14, assim como a arquitetura do simulador do IOS, também na versão 14.0.

Em seguida, utilizaremos o compilador swift para compilar os arquivos main.swift e AppDelegate.swift.

Neste caso, também usamos as flags -target e -sdk, que foram alimentadas com os valores das variáveis definidas posteriormente. Também usamos a flag -o, na qual definimos o nome do executável criado pelo compilador, que no exemplo se chama IterisApp.

Finalmente, se até aqui tudo ocorreu conforme esperado, você já conseguirá visualizar o arquivo IterisApp disponível.

Para que possamos realizar o teste da aplicação, mova o executável que foi gerado pelo último comando para a pasta IterisApp.app.

5º passo – Teste

Desse modo, você observará que a pasta IterisApp.app possui dois arquivos: Info.plist e IterisApp.

Por fim, abra o simular com o comando open -a Simulator.app e arraste a pasta IterisApp.app pra dentro do simulador.

Ao realizar essa ação, o aplicativo será instalado e permitirá que você realize o teste.

A princípio, após realizarmos esses 5 passos, percebemos que um aplicativo nada mais é do que um executável + arquivo Info.plist com algumas mínimas informações.

Porém, as aplicações IOS modernas não são tão simples como se fez parecer. Geralmente ela envolve outros tipos de artefatos, como .frameworks, .bundles e outros que podem ser compilados de maneira dinâmica (.dylib) ou estática (.a). Mas esse assunto fica para outro dia.