Décio Montanhani

Gerando Xcode Project com Tuist

21/02/2021tuistxcodeprojiosswift

Com muitas empresas buscando escalar seus times e modularização ganhando muita força na comunidade, começamos a enfrentar muitos problemas lidando com o Xcode diretamente. Isso porque o Xcode tem o seu arquivo de configuração do projeto, o .xcodeproj.

Esse arquivo contém as informações relacionadas aos arquivos do projeto e como eles são linkados, ou seja, ele é a fonte de verdade (source of truth) do projeto. Isso faz com que esse arquivo tenha muitos conflitos no versionamento ao trabalhar em equipes grandes, simplesmente trocando um arquivo de lugar, por exemplo. É nesse ponto que Tuist entra.

O que é Tuist?

Tuist é uma CLI (Command Line Tool) que facilita a geração, manutenção e interação com o .xcodeproj. É open-source e feito em Swift 🎉.

Para você instalar e criar o seu primeiro projeto com ele, dê uma olhada no Getting Started no site oficial. Mas já adianto que é super simples, fácil de instalar e sem depender de outras ferramentas para funcionar.

Beleza, e como funciona?

O Tuist gera o projeto do Xcode baseado em algumas regras definidas em um arquivo de configuração chamado Project.swift, que aponta o caminho dos arquivos através do filesystem.

import ProjectDescription
let project = Project(name: "MyApp",
                      organizationName: "MyOrg",
                      targets: [
                        Target(name: "MyApp",
                               platform: .iOS,
                               product: .app,
                               bundleId: "io.tuist.MyApp",
                               infoPlist: "Info.plist",
                               sources: ["Sources/**"],
                               resources: ["Resources/**"],
                               headers: Headers(public: ["Sources/public/A/**", "Sources/public/B/**"],
                                                private: "Sources/private/**",
                                                project: ["Sources/project/A/**", "Sources/project/B/**"]),
                               dependencies: [
                                    /* Target dependencies can be defined here */
                                    /* .framework(path: "framework") */
                                ]),
                        Target(name: "MyAppTests",
                               platform: .iOS,
                               product: .unitTests,
                               bundleId: "io.tuist.MyAppTests",
                               infoPlist: "Info.plist",
                               sources: ["Tests/**"],
                               dependencies: [
                                    .target(name: "MyApp")
                               ])
                      ])

Esse arquivo é bem tranquilo, principalmente por ser em Swift! Você edita todas essas configurações do app utilizando o comando tuist edit no terminal, fazendo com que abra no Xcode um projeto temporário com esses arquivos de configuração dentro, facilitando sua alteração, com autocomplete e tudo que o Swift proporciona pra você! Massa, né?

E por o Tuist gerar o arquivo .xcodeproj, é possível colocar esse arquivo no gitignore, evitando milhares de conflitos que temos no nosso dia a dia! Só por isso já vale a pena utilizar a ferramenta.

Modularização sem sofrimento

Pra quem utiliza módulos em seus projetos no mesmo repositório, já sofreu com algumas coisas que acontecem ao criá-lo manualmente (pra quem não conhece, leia esse artigo aqui). Por exemplo, ao criar um novo módulo, você precisa ter as mesmas build configurations do seu projeto principal, se não ao utilizar o seu módulo, ele pode dar crash, com a mensagem ld: framework not found NomeDoFramework. Além de lembrar de referenciar o seu framework no projeto principal também.

Com o Tuist, isso fica muito mais simples. Para adicionar um novo módulo como dependência do seu projeto principal, só é necessário referenciá-lo na propriedade dependencies do Project.swift de onde você deseja usá-lo.

E sobre os builds configurations, você consegue criar pré configurações dos seus módulos para que ele já venha configurado do jeito que geralmente é utilizado no seu projeto. Para conseguir isso, é só criar os project helpers, que são funções estáticas que retornam o objeto Project já com suas configurações padrões.

Rapidez para criação de módulos

Com o Tuist, também é possível criar módulos diretamente pelo terminal, necessitando apenas de linkar onde você desejar. Com o setup inicial do Tuist em um projeto qualquer, ele já vem com um template pré configurado de criação de módulo. Com isso, você consegue criar um novo módulo digitando tuist scaffold framework --name NomeDoMeuModulo.

Você pode ir na pasta Templates do Tuist e criar/editar os templates que façam sentido para seu projeto, assim como templates de arquitetura também.

Como saber mais sobre a ferramenta?

Segue uma lista de links para você estudar mais e conhecer a ferramenta:

  • Documentação oficial. Lá você já encontra muita informação sobre como o Tuist funciona, além de outras muitas features que não abordei por aqui.
  • Awesome Tuist. Aqui você encontra um compilado de informações sobre Tuist, seja talks, blog posts e alguns projetos open source que foram feitos utilizando a ferramenta.
  • Tuist Fixtures. Neste link você encontra diversos exemplos utilizando coisas que ficamos na dúvida apenas ao ler a documentação. Como utilizar com AppClips, CoreData, extensions, etc.

Conclusão

Pra quem tem um app gigante e quer utilizar o Tuist, acredito que esse trabalho será bem árduo. Porém, com o tempo acredito que vem a recompensa desses inúmeros benefícios que citei neste post. Um exemplo de case de sucesso utilizando essa ferramenta é o SoundCloud, que inclusive foi um dos desenvolvedores de lá (Pedro Piñera) que desenvolveu a ferramenta.

Nos meus repositórios do github eu já o utilizo, você pode conferir neste projeto em que fiz um """clone""" do mercado livre neste link.

Ficou com alguma dúvida? Quer que eu crie outro post falando mais ou até criando um tutorial? Deixa um feedback ai nos comentários ou me procure nas minhas redes sociais como @deciomontanhani. Valeu!!

© Décio Montanhani 2023