Práticas recomendadas e ferramentas para o desenvolvimento de aplicativos iOS

Ao desenvolver aplicativos móveis, tive que criar projetos do zero mais de uma vez. Ao mesmo tempo, eu e minha equipe sempre gastamos muito tempo na configuração básica do projeto, como a integração de ferramentas de terceiros, a configuração da estrutura do projeto, a criação de classes básicas, a integração de bibliotecas externas etc.

Decidi que o tempo necessário para iniciar o projeto pode ser reduzido e a parte principal do processo pode ser automatizada. Ao mesmo tempo, coletei as melhores práticas e ferramentas que usamos e preparei um modelo de projeto que usamos ao iniciar novos projetos. Esse modelo deve economizar o tempo do desenvolvedor para configurar um novo projeto, além de fornecer uma estrutura de projeto comum à qual todos os membros da equipe se acostumarão, para que você não precise mais pensar e estudar a estrutura de um novo projeto para ele. Agora é sempre o mesmo.

Cada ferramenta ou abordagem adicionada ao modelo merece um artigo separado, mas eu gostaria de tentar resumir cada parágrafo e dar uma breve explicação sobre por que os incluí neste artigo.

Cocoapods


Eu não acho que Cocoapods exija uma submissão. Esta é uma biblioteca para gerenciar dependências externas para projetos iOS. Ele existe há muito tempo e é confiável e comprovado em campo em milhares (se não milhões) de projetos. Também existem gerenciadores de dependência alternativos, por exemplo: Cartago , mas decidi continuar com o Cocoapods, porque ele tem a maior variedade de projetos de código aberto suportados. O uso do Cocoapods é muito simples e vem com um índice de pesquisa que facilita a localização de pacotes que podem ser úteis a qualquer momento.

Um projeto de modelo é fornecido com um Podfile simples que contém Swiftlint e R.swift. O modelo também inclui um gemfile para gerenciar a versão do Cocoapods usada para gerenciamento de dependências. Essa solução geralmente é ignorada pelos desenvolvedores, mas evita problemas que ocorrem quando os desenvolvedores de sua equipe instalam dependências usando versões diferentes do Cocoapods. O Gemfile usa à força a mesma versão do Cocoapods para toda a equipe.

Swiftlint


O Swiftlint é uma ferramenta muito útil para impor certas regras e estilo de escrita para cada desenvolvedor na mesma equipe. Esse sistema pode ser considerado um sistema automatizado de verificação de código que avisa o desenvolvedor sobre momentos perigosos, como, por exemplo, projeções de força, tentativas de força etc. etc., mas, além do exposto, esse sistema aplica um estilo geral de escrita de código, monitoramento para que todos os desenvolvedores sigam as mesmas regras associadas ao "estilo de código", por exemplo: recuos ou intervalos. Essa abordagem tem enormes vantagens, não apenas economizando tempo na verificação do código, mas também tornando os arquivos do projeto reconhecíveis, o que aumenta a legibilidade e, como resultado, o entendimento de todos os membros da equipe de desenvolvimento. Este link fornece uma lista de todas as regras. No modelo Swiftlint, ele é instalado usando o Cocoapods e incluído na etapa "Fases de compilação", portanto, será exibido um aviso ao desenvolvedor toda vez que o projeto for compilado.

R.swift


R.swift é uma ferramenta para obter recursos fortemente tipados e preenchidos automaticamente, como imagens, segmentos de fonte e localizações. Ele executa todas as ações acima, varrendo o projeto e criando as classes necessárias para obter recursos. A maior vantagem desta biblioteca é que, ao usar recursos, ela cria o código do programa:

  • Totalmente digitado - menos projeções e suposições sobre qual método será retornado
  • Tempo de compilação verificado - não há mais linhas inválidas que impedem a execução do aplicativo durante a execução do código
  • Preenchimento automático - não é necessário adivinhar o nome image / nib / storyboard novamente

Considere o seguinte código usando a API oficial da string:

let icon = UIImage(named: “custom-icon”) 

Se você cometeu um erro no nome da imagem, receberá zero. Se algum membro da sua equipe alterar o nome do recurso de imagem, esse código retornará zero ou sua execução será interrompida se você forçar a expansão da imagem. Ao usar R.swift, fica assim:

 let icon = R.image.customIcon() 

Agora você pode ter certeza de que o ícone realmente existe (o compilador avisará se não estiver, graças às verificações do tempo de compilação) e terá certeza de que não digitará o nome do ícone, porque usará o preenchimento automático.

R.swift é instalado usando Cocoapods e integra-se ao modelo na Fase de Compilação e gerará classes de shell Swift para cada compilação. Isso significa que, se você adicionar um arquivo / imagem / localização / fonte / cor / caneta, etc., tudo isso estará disponível através da R.swift após a compilação do projeto.

Arquivo AppDelegate separado para testes


Muitas vezes esquecem as boas práticas de usar uma classe TestAppDelegate separada ao executar testes. Por que essa é uma boa ideia? Normalmente, a classe AppDelegate trabalha bastante quando o aplicativo é iniciado. Ele pode ter lógica de configuração de janela, configurar a exibição básica da interface do usuário do aplicativo, executar a lógica de registro para receber notificações, ter um código de configuração de conexão com o banco de dados e, às vezes, fazer chamadas de API do servidor. Os testes de unidade não devem ter efeitos colaterais. Você realmente não deseja fazer chamadas aleatórias à API e personalizar toda a estrutura da interface do usuário do seu aplicativo apenas para executar testes de unidade?

TestAppDelegate também é uma opção apropriada para obter o código que você deseja executar apenas uma vez durante a execução do conjunto de testes. Pode conter código que gera objetos simulados, stubs de solicitação de rede etc.

O modelo contém o arquivo main.swift, que é o principal ponto de entrada do aplicativo. Existem métodos neste arquivo que testam o ambiente do aplicativo e, se for um ambiente de teste, eles chamam TestAppDelegate.

Sinalizadores de perfil de desempenho do compilador


O Swift é um ótimo idioma, mais fácil de usar e mais seguro que o Objective-C (IMO). Mas quando foi introduzido pela primeira vez, havia uma grande falha - o tempo de compilação. Na época em que eu estava trabalhando em um projeto no Swift, que tinha cerca de 40 mil linhas de código Swift (um projeto de tamanho médio). O código era muito pesado, com configurações e inferência de tipo, e a compilação de uma montagem limpa levou quase 5 minutos. Se você fizer pequenas alterações, o projeto será recompilado e levará cerca de 2 minutos para ver as alterações. Essa foi uma das piores experiências que já experimentei e, por causa disso, quase parei de usar o Swift.

A única solução foi tentar determinar o tempo de compilação do projeto e alterar seu código para que o compilador funcione mais rapidamente. Para ajudar a resolver esses problemas, a Apple introduz alguns sinalizadores não oficiais do compilador que avisam o desenvolvedor que leva muito tempo para compilar o corpo do método ou determinar o tipo de expressão. Adicionei esses sinalizadores ao projeto de modelo para avisar sobre o longo tempo de compilação do seu aplicativo.

Atualmente, o tempo de compilação diminuiu significativamente e os desenvolvedores raramente precisam otimizar seu código apenas para reduzir o tempo de compilação. Ainda assim, é melhor saber tudo com antecedência do que tentar resolver esse problema quando o projeto se tornar muito grande.

Configurações de desenvolvimento / preparação / produção


Outra boa abordagem (ou, pode-se dizer, uma necessidade) é ter uma configuração separada e variáveis ​​de ambiente para ambientes de desenvolvimento, teste final e publicação de aplicativos. Atualmente, quase todos os aplicativos devem funcionar com um servidor e, geralmente, esses servidores são implantados em vários ambientes. O ambiente de desenvolvimento é usado para implantação diária pelos desenvolvedores para testar seu código. O ambiente de teste final é usado para criar versões estáveis ​​ou para teste por testadores e clientes.

Uma maneira de oferecer suporte a vários ambientes em um projeto iOS é adicionar configurações no nível do projeto.

imagem
Configurações no nível do projeto

Após definir as configurações, é possível criar um arquivo Configuration.plist contendo variáveis ​​para cada ambiente.

imagem
Configuration.plist

Ao iniciar um projeto, é possível indicar qual configuração deve ser usada. Você pode fazer isso em um diagrama de montagem.

imagem

Em seguida, você precisa adicionar outra propriedade ao arquivo de projeto Info.plist. O valor dessa propriedade será substituído dinamicamente no tempo de execução no nome da configuração atual.

imagem
Tudo isso é pré-configurado no modelo.

Resta apenas escrever uma classe que possa extrair essas variáveis ​​em tempo de execução, dependendo da configuração selecionada no esquema de montagem. O modelo contém a classe ConfigurationManager , que pode recuperar variáveis ​​para o ambiente atual. Você também pode verificar a implementação desta classe no Github para ver como ela funciona.

Leia-me


Cada projeto deve conter um arquivo Leiame, que contém pelo menos instruções para instalar dependências e iniciar o projeto. Também deve conter descrições da arquitetura e dos módulos do projeto. Infelizmente, os desenvolvedores não gostam de escrever documentação (o arquivo leia-me faz parte deste trabalho) e vi um projeto que foi desenvolvido há meses e até tinha um arquivo Leia-me. Para remover o ônus de escrever um arquivo leia-me, o modelo contém um arquivo leia-me padrão que cobre a instalação e a estrutura do projeto. Ao configurar um novo projeto usando modelos, você inclui automaticamente o arquivo Leiame.

Gitignore


Atualmente, a maioria dos projetos usa o GIT como um sistema de controle de versão. Ao usar o GIT, os desenvolvedores não desejam ignorar alguns arquivos ou pastas no projeto, como a pasta de construção ou a pasta de dados derivada. Para evitar que o desenvolvedor encontre um arquivo gitignore adequado para seu projeto iOS, o modelo contém o gitignore padrão fornecido pelos membros do Github.

Classes base para manipulação de links e notificações externas


Atualmente, quase todos os aplicativos devem lidar com links e notificações externas. Para fazer isso, o desenvolvedor deve escrever algum código padrão na classe AppDelegate. Este modelo contém uma descrição de como fazer isso, também contém classes base que facilitam o trabalho com links e notificações externos.

Conclusão


Para resumir, o modelo descrito contém as melhores abordagens e integra ferramentas úteis de terceiros. Tudo isso economiza o tempo de desenvolvimento da equipe gasto na criação de um novo projeto, além de fornecer uma base comum e sólida para o restante do projeto. Deixe este modelo servir você e sua equipe para o benefício!

Source: https://habr.com/ru/post/pt473630/


All Articles