Todo o fluxo de desenvolvimento foi registrado com o GithubProjects conforme sugerido. Aproveitei para adicionar alguns links ao longo da documentação que apontam para Milestones, PullRequests e Issues que considero importantes. A documentação a seguir tem o objetivo de apresentar alguns comentários que considero relevantes sobre a maneira com que eu organizei o desenvolvimento e tomei algumas decisões.
Na pasta raíz do projeto:
- Instale a versão do ruby especificada no arquivo .ruby-version
- Instale o gerenciador de gemas bundler
$ gem install bundler
- Instale as Gemas
$ Bundler install
- Instale as dependências
$ Bundle exec pod install
Basta rodar a build de testes do scheme The-Norris
, ele também irá rodar os testes dos outros módulos.
- The-Noris: 88,0% (
112 tests
) - Interface: 91,0% (
19 tests
) - Client: 86,5% (
7 tests
)
1. Setup
Nesta etapa eu fiz todo o planejamento do desenvolvimento, o que incluiu:
- Estudar a API
- Desenhar os componentes, telas, fluxos, estados, cores e fontes do aplicativo
- Mapeamento de dependências
- Definição de arquitetura
- Swift Lint: é simplesmente o lint com o qual eu estou habituado a trabalhar.
- SwiftGen: Gera arquivos que garantem o acesso seguro às imagens e strings do projeto.
- Quick: Oferece sintaxe que favorece a escrita de testes unitários mais legíveis e organizados
- Nimble: Funciona bem em conjunto com
Quick
, trazendo ferramentas muito práticas de verificação - Nimble-Snapshots: Testes de
Snapshot
integrados com a sintaxe doNimble
O aplicativo será modularizado conforme esta descrição, e a arquitetura do aplicativo será MVVM, com a adição de uma camada que eu chamei de service para descarregar a ViewModel de regras de negócio relacionadas a tratamento de erros e consumo de dados oriundos da API e do Banco dados local.
A navegação será baseada em ChildViewControllers, com o uso de uma camada chamada de "FlowController".
Esta abordagem se assemelha bastante ao Coordinator, porém a stack de "ChildCoordinators" toma proveito do próprio ciclo de vida das UIViewControllers com o uso de ChildViewControllers, o que trás vantagens durante a inicialização e finalização de fluxos.
Eu também usei uma implementação de "controller base" chamada "StateViewController" para abstrair os principais estados de uma tela, também fazendo uso de ChildViewControllers.
2. Foundation
Nesta etapa eu comecei a programar com o objetivo de concluir tudo o que eu considerei como recurso básico para o desenvolvimento da primeira feature, o que incluiu:
- Criação e configurações do projeto
- Adição de cores, imagens e fontes
- Criação de componentes
- Criação do mecanismo de requisições Client
Na terceira etapa eu desenvolvi o que eu considerei o "Mínimo Produto Viável" do aplicativo proposto, o que incluiu:
- Tela de listagem dos fatos pesquisados
- Tela de busca
Após o desenvolvimento o usuário podia fazer uma pesquisa, ver os resultados listados e compartilhar um fato, sem as sugestões, histórico de pesquisas, ou qualquer persistência local.
Esta etapa contou com o desenvolvimento da busca de categorias, persistência local das mesmas, e exibição delas como sugestões na tela de pesquisa.
- As categorias são buscadas na api [somente uma vez, durante a inicialização do app](The-Norris/Features/Splash Screen/Controller/SplashScreenViewController.swift).
- São exibidas 8 categorias aleatórias como sugestão de pesquisa
O último incremento do escopo básico do projeto adicionou a lista de pesquisas passadas à tela de pesquisa, garantindo a ordem decrescente por data de pesquisa, e a proteção contra a inclusão de entradas repetidas no banco de dados.
Eu escolhi fazer o extra dois, desenvolvendo a persistência local de todos os resultados bem sucedidos de pesquisa, associados à query que foi feita para retorná-los. Eu usei o id de cada objeto "Fact" como constraint no Objeto do CoreData, impedindo que estas entradas se repetissem no banco de dados, mesma abordagem usada para que os "termos passados não fossem duplicados.