Concrete Logo
Hamburger button

Criando um aplicativo com boas práticas em Swift (Parte 2)

  • Blog
  • 24 de Agosto de 2016
Share

Ontem, publiquei aqui no post a primeira parte de uma série sobre como criar um app com Swift, você pode ver aqui. Nessa segunda parte, vou mostrar uma arquitetura MVP aplicada em Swift. A utilização do MVP no projeto contribuiu para uma melhor segregação de responsabilidade, melhor arrumação do código e mais testabilidade, mas gostaria de levar a discussão da utilização de uma arquitetura mais à frente, deixando meu entendimento após diversas discussões sobre elas.

Quando falo sobre aplicação de arquiteturas sempre prefiro ser comedido. O MVP em um pequeno projeto pode ser mais organizado, mas a literatura em geral não favorece quanto à aplicação de Animações e à utilização da Presenter para diversas views, o que pode culminar em um Presenter massivo, por exemplo. Nesses casos, um dos maiores conhecimentos que se pode tirar proveito é o SOLID. Esses princípios poderão levá-lo a criar uma arquitetura ideal a sua necessidade.

Neste projeto, o model não possui grandes funções, ele apenas implementa o protocolo Mappable para o parse de JSON para o Objeto. Na camada de view teremos o protocolo ShotsView, e nele serão assinadas as funções que serão implementadas pela ShotsViewController. Esse protocolo também permitirá a criação de um mock que facilitará na validação dos testes da presenter, que veremos à frente.

Protocolo:

Implementação:

Por fim, o presenter. Sendo um mediador entre o model e a view, ele é responsável pelo controle dos dados e estados da view e atualização do modelo. Com uma propriedade do tipo ShotsView, que é atribuida pela ViewController que implementa o protocolo, o presenter saberá quando chamar cada estado da view.

Esse talvez seja o melhor momento para falar sobre o Gettable. Vindo do conceito de Orientação a Protocolo, ele serve para adicionar comportamento ao serviço. Nesse caso, ele permite ao serviço obter dados e, caso necessário, poderiamos adicionar outros comportamentos possíveis como, por exemplo, o de deletar.

Em Gettable, usamos o associatedtype para manter um espaço reservado para um tipo usado como parte do protocolo que é especificado quando o protocolo é implementado.

Essa abordagem, junto com a injeção de dependência, como no caso do serviço do método getShots, também nos ajudará com os testes a seguir.

Para os testes criaremos nossos Mocks de serviço, o ShotServiceMock, e de view, o ShotViewMock. Ambos se aproveitarão dos recursos que citei acima. O ShotViewMock se aproveita do protocolo criado na arquitetura MVP para implementação da Controller, e com ele validaremos se as chamadas do presenter ocorreram como esperávamos.

O ShotServiceMock se aproveita do conceito de Orientação a Protocolo, permitindo implementar Gettable e responder o que se espera.

Como a função getShots da presenter espera um serviço que implemente Gettable e que o associatedType seja do tipo [Shot], representado por <Service: Gettable where Service.DataArray == [Shot]>, basta que nosso ShotServiceMock siga essas condições para ser passado como dependência.

Assim, garantimos que cada ponto do getShots está sendo testado dependendo das situações que tivermos. Por exemplo, se o array de Shots retornar vazio, o hideEmptyView deverá ser falso.

E assim finalizo esse compilado de práticas que podem ajudar na organização, testabilidade e arquitetura. Esse código está disponível no git, e lá você poderá verificar como se comporta a aplicação, mais testes e outros trechos de códigos não colocados no Post.

Ficou alguma dúvida ou tem algo a acrescentar? Fique à vontade nos campos abaixo. Até a próxima!