O Xamarin é uma plataforma de desenvolvimento mobile que vem crescendo bastante nos últimos anos, e muito desse sucesso ocorre devido à sua estrutura de compartilhamento de código. Quando comparamos, por exemplo, um projeto Xamarin para Android e iOS, temos em torno de 75% do código compartilhado. Isso possibilita um ganho muito grande em tempo de desenvolvimento se fizermos uma comparação direta com Java (para Android) e Swift/Objective-C (para iOS).

O ganho oferecido pelo Xamarin é concretizado, basicamente, por causa dos seus dois tipos de projetos: Portable Class Library, ou PCL, e Shared Assets Projects, ou SAP. Cada um deles possui um escopo específico e utilização recomendada. Embora seja possível utilizar somente um deles, em projetos maiores, no entanto, é praticamente certo que o desenvolvedor Xamarin precisará de ambos.

Nesse artigo, veremos como lidar com eles e quando devemos utilizar um ou outro tipo. Esse conhecimento ajudará a maximizar o código compartilhado e, consequentemente, aumentar o desempenho da equipe de desenvolvimento.

Portable Class Libraries: bibliotecas portáveis

O conceito de compartilhamento de código por meio de bibliotecas não é novo: podemos encontrá-lo no C, por exemplo. No .NET Framework, esse conceito evoluiu para as chamadas Class Libraries, projetos específicos para criação de bibliotecas que transcendem o escopo de uma determinada solução. Para utilização em outros projetos/soluções, basta obter a DLL daquela biblioteca e teremos algo durável, capaz de ser utilizado e compartilhado da forma como desejamos.

As PCLs seguem por esse mesmo caminho, como o próprio nome sugere. Entretanto, elas são “Portable”, ou seja, bibliotecas portáveis. Na prática, isso significa que elas são bibliotecas de classe específicas para funcionamento em plataformas móveis. É nesse ponto que entra sua participação no Xamarin.

É válido ressaltar, aqui, que as PCLs existiam antes mesmo do Xamarin. Elas foram criadas como uma forma de compartilhar código entre as plataformas da Microsoft, como Windows Phone, Silverlight e Xbox. O Xamarin “apenas” expandiu o conceito e trouxe a possibilidade de utilização dessas com o Xamarin.Android e o Xamarin.iOS.

Por serem bibliotecas, as PCLs possuem duas características básicas:

  • A possibilidade de compartilhamento além do escopo da solução, como uma DLL;
  • A utilização de outras bibliotecas por meio de referências.

Essas duas características são o que precisamos ter em mente para sabermos quando é interessante utilizar PCLs ou SAPs, e fica ainda mais claro quando observamos a Figura 1, que traz um projeto Xamarin com uma PCL. Repare que temos referências (ao .NET Framework e a uma biblioteca JSON) e também propriedades (Properties) dentro da PCL - comumente utilizadas para configuração da DLL -, além das classes e outros arquivos específicos.

Estrutura de uma Portable Class Library
Figura 1. Estrutura de uma Portable Class Library

A partir disso, podemos notar que a estrutura das PCLs faz com que elas sejam a forma de compartilhamento primária na maioria dos projetos. Geralmente, ela conterá as regras de negócio da aplicação, bem como os mecanismos de acesso a dados, serviços do domínio ou da aplicação. Logo, o escopo das PCLs, normalmente, está no back-end do aplicativo que será criado com Xamarin, ou seja, naquilo que envolve a parte estrutural da aplicação.

Shared Assets Projects: compartilhamento de recursos

Os SAPs, ou Shared Assets Projects, são projetos para compartilhamento de recursos (ou assets). Eles possuem uma estrutura completamente diferente das PCLs: em primeiro lugar, não são bibliotecas. Logo, não podem ser compartilhados com outras soluções como DLLs ou mesmo conter referências. Enfim, essas são as principais limitações dos SAPs. Eles são dependentes dos projetos que os utilizam.

Para entendermos melhor essa dependência, analisemos a Figura 2. Note que, em comparação com a Figura 1, da PCL, não estão presentes as abas Properties e References; apenas os assets (as classes e outros arquivos).

Estrutura de um Shared Assets Project
Figura 2. Estrutura de um Shared Assets Project

No entanto, se os SAPs não possuem referências, como eles podem utilizar namespaces? Para respondermos a essa pergunta, precisamos entender que os SAPs são apenas uma maneira lógica de centralizar o código no momento do desenvolvimento: na prática, esse código continua dentro das plataformas. É como se o projeto Xamarin.Android tivesse uma cópia dos recursos do SAP, bem como o projeto Xamarin.iOS ou qualquer outro projeto. Assim, os SAPs utilizam as referências dos projetos que os referenciam.

Devido a isso, os SAPs viabilizam um recurso importante em muitos casos para o compartilhamento de código: as diretivas de compilação. Por meio delas, é possível escolher o código que será compilado em cada plataforma. Na Listagem 1, esse uso fica muito claro ao escolhermos uma mensagem específica para ser mostrada em cada plataforma.

Listagem 1. Utilização de diretivas de compilação nos SAPs

 namespace ExemploSAP
 {
     public static class HelperMensagem
     {
           public static string MostraMensagem ()
           {
                  string mensagem = "Seja bem-vindo ao ";

 #if __IOS__
            mensagem += "iOS!";
 #elif __ANDROID__
            mensagem += "Android!";
 #else
            mensagem += "Windows!";
 #endif

            return mensagem;
        }
     }
 }
  
  • Linha 01: Namespace da classe;
  • Linha 03: Definição da classe estática HelperMensagem;
  • Linha 05: Definição do método estático MostraMensagem();
  • Linha 07: Criação da mensagem básica, que será complementada para cada plataforma-alvo;
  • Linhas 09 e 10: Utilização da diretiva de compilação “#if”, que indica que, se a plataforma-alvo é o iOS, a mensagem deve ser complementada com a string “iOS!”;
  • Linhas 11 e 12: Utilização da diretiva de compilação “#elif” (else if), que indica que, se a plataforma-alvo não é iOS e é o Android, a mensagem deve ser complementada com a string “Android!”;
  • Linhas 13 e 14: Utilização da diretiva de compilação “#else”, que indica que, se a plataforma-alvo não é iOS ou Android, a mensagem deve ser complementada com a string “Windows!”;
  • Linha 15: Declaração de fechamento da diretiva de compilação “#if”;
  • Linha 17: Retorna a mensagem.

A utilização das diretivas de compilação é extremamente útil em aplicações que acessam recursos do dispositivo. Assim, é possível termos um comportamento base, para todas as plataformas, em conjunto com comportamentos específicos. Um exemplo muito comum para isso pode ser verificado no acesso a bancos de dados locais, uma vez que cada plataforma salva esses recursos em um lugar diferente do dispositivo.

PCL ou SAP?

Baseado em tudo o que vimos, PCL ou SAP? Depende muito do que desejamos compartilhar. É importante notar que, como os nomes sugerem, a PCL é uma biblioteca, enquanto o SAP é um compartilhador de recursos, simplesmente. Assim, o ideal é que, primeiramente, entendamos o que queremos em nossa aplicação, para depois tomar uma decisão.

Entretanto, existem algumas dicas às quais podemos nos ater, a saber:

  • PCLs são indicadas quando desejamos compartilhar o código com outras soluções ou quando precisamos de dependências (referências) específicas. Assim, as PCLs são completamente independentes dos projetos Android, iOS ou Windows;
  • SAPs, por sua vez, são recomendados quando temos o compartilhamento de apenas uma parte do código e, em geral, esse código é relacionado à experiência do usuário. Assim, esse tipo de projeto é interessante para compartilhamento de pedaços do código em um determinado método, com diretivas de compilação para as partes específicas, ou centralização de comportamentos comuns às interfaces.