Você está na página 1de 284

Contents

Plataforma cruzada
Criar aplicativos móveis
Requisitos
O ciclo de vida do desenvolvimento de software móvel
Passo a passo para a criação de um aplicativo de multiplataforma
Visão geral
Parte 1 – Noções básicas sobre a plataforma Xamarin Mobile
Parte 2 – Arquitetura
Parte 3 – Configurar uma solução multiplataforma do Xamarin
Parte 4 – Lidar com várias plataformas
Parte 5 – Estratégias práticas de compartilhamento de código
Parte 6 – Teste e aprovações da App Store
Estudo de caso: Tasky
Compartilhamento de código
Visão geral
.NET Standard
Projetos compartilhados
PCL (Bibliotecas de classe portáteis)
Projetos de bibliotecas multiplataforma do NuGet
Projetos de biblioteca existentes
Nova biblioteca multiplataforma
Novas bibliotecas específicas da plataforma
Guia de metadados
Pacotes NuGet (Manual)
Usar bibliotecas C/C++ em aplicativos multiplataforma
Suporte ao idioma
C#
Visão geral do suporte assíncrono
Recursos de linguagem C# 6
F#
Introdução
Amostras do F#
Visual Basic
Xamarin Android e iOS
Xamarin.Forms
Modelos HTML do Razor
Desempenho e segurança
Desempenho
Desempenho do Xamarin.Forms
Desempenho do Android
Desempenho do iOS
Desempenho do Mac
Protocolo TLS
Android
iOS e Mac
Depuração e implantação
Conectar-se aos serviços Web locais
Configuração personalizada do Linker
Depuração de vários processos
Desenvolvedores para computadores desktop
Comparação de ciclo de vida do aplicativo
Comparação de controles de interface do usuário
WPF x Xamarin.Forms
Diretrizes de portabilidade
Exemplos
Solução de problemas
Perguntas frequentes
Como posso exibir as bibliotecas com suporte em um PCL?
API de Reflexão de PCL
Estudo de caso de PCL: como posso resolver problemas relacionados a
System.Diagnostics.Tracing para o pacote NuGet de Fluxo de Dados de TPL da
Microsoft?
Como posso atualizar o NuGet?
Como fazer downgrade de um pacote NuGet?
Erro de pacotes ausentes após atualizar os pacotes do Nuget
Unificar os componentes do Google Play Services e o NuGet
Onde meus componentes são armazenados no meu computador?
Onde posso encontrar informações e logs da minha versão?
Quando e como devo criar um relatório de bugs?
Por que não há suporte para Jenkins no Xamarin?
Quais configurações do projeto são necessárias para o depurador?
Perguntas sobre o Visual Studio
Implantar caixas de seleção desabilitadas no Configuration Manager
Extensões do Visual Studio ausentes após a instalação
Como executar uma desinstalação completa do Xamarin para Visual Studio?
Como posso coletar as pilhas de chamadas atuais do processo do Visual Studio?
Por que o Visual Studio não inclui meu projeto de biblioteca referenciado no
build?
Atualizar referências de componentes para NuGet
Desenvolvimento multiplataforma no Q&A
Exemplos
Criar aplicativos móveis
02/11/2020 • 2 minutes to read • Edit Online

Antes de começar, confira o requisitos de sistema e as instruções de instalação para verificar se tudo está pronto
para começar.

Criar seu primeiro aplicativo


Início rápido do Xamarin.Forms
Se você deseja criar um aplicativo usando tecnologias de interface do usuário nativas (como Android XML ou
Xcode Storyboards), tente um desses guias específicos da plataforma:
Início Rápido Android
Início Rápido do iOS

Introdução ao desenvolvimento móvel


Para saber mais sobre como funciona o Xamarin e como abordar os projetos de desenvolvimento de aplicativo
móvel, leia os guias a seguir:
O que é o Xamarin?
Este documento explica o funcionamento do Xamarin em um alto nível e inclui links para as guias de introdução
do Xamarin.Forms, Android e iOS.
Ciclo de vida do desenvolvimento de software móvel
Este artigo aborda o ciclo de vida de desenvolvimento de software em relação a aplicativos móveis e discute
algumas das considerações necessárias ao criar projetos móveis. Para desenvolvedores que querem começar
diretamente a compilar, este guia pode ser ignorado e lido posteriormente para obter um entendimento mais
completo do desenvolvimento móvel.

Criando aplicativos de plataforma cruzada


Depois de escolher o Xamarin e levar em conta algumas considerações ao projetar e desenvolver aplicativos
móveis, você poderá realizar um compartilhamento de código expressivo entre plataformas móveis, reduzir o
tempo de lançamento no mercado, aproveitar talentos existentes, atender à demanda de acesso móvel dos
clientes e reduzir a complexidade multiplataforma. Este documento descreve as principais diretrizes para
aproveitar essas vantagens para aplicativos de produtividade e utilitários.
Introdução do Visual Studio para Mac
Saiba mais sobre o Ambiente de Desenvolvimento Integrado (IDE) para macOS do Visual Studio para Mac.

Vídeo de introdução
Como criar seu primeiro aplicativo Xamarin.Forms com o Xamarin para Visual Studio

Links relacionados
Requisitos do sistema
Instruções de instalação
Requisitos do sistema
02/11/2020 • 11 minutes to read • Edit Online

Os produtos Xamarin contam com os SDKs de plataforma da Apple e do Google para direcionar para iOS ou
Android, portanto, os nossos requisitos de sistema correspondem aos requisitos deles. Esta página descreve a
compatibilidade do sistema para a plataforma Xamarin, o ambiente de desenvolvimento recomendado e as
versões do SDK.
Observe as instruções de instalação para mais informações sobre como obter o software e os SDKs necessários.

Ambientes de desenvolvimento
Esta tabela mostra quais plataformas podem ser criadas com diferentes combinações de ferramentas de
desenvolvimento e sistemas operacionais:

MAC OS W IN DO W S

Ambiente de desenvolvimento Visual Studio para Mac Visual Studio

Xamarin.iOS Sim Sim (com o computador Mac)

Xamarin.Android Sim Sim

Xamarin.Forms ^ iOS e Android Android, Windows/UWP (iOS com


computador Mac)

Xamarin.Mac Sim Abrir o projeto e compilar apenas

^ Outras plataformas também estão disponíveis.

NOTE
Para desenvolver para iOS em computadores Windows, deve haver um computador Mac acessível na rede, para
compilação remota e depuração. Isso também funciona se o Visual Studio estiver em execução dentro de uma VM do
Windows em um computador Mac.

requisitos do macOS
Para usar um computador Mac para desenvolvimento do Xamarin são necessárias as seguintes versões de
software/SDK. Verifique a versão do sistema operacional e siga as instruções do Instalador do Xamarin.

REC O M EN DA DA S O B SERVA Ç Õ ES

Sistema operacional macOS Mojave (10.14) O Xcode 10 exige o macOS High Sierra
(10.13) ou mais recente.

Xamarin.iOS SDK do iOS 12 O SDK do iOS 12 é fornecido com o


Xcode 10.
REC O M EN DA DA S O B SERVA Ç Õ ES

Xamarin.Android Android 6.0 / API nível 23 Você ainda pode direcionar versões
mais antigas do Android enquanto
estiver usando o SDK mais recente ou
pode compilar em relação a versões
anteriores do SDK, se necessário.

Xamarin.Forms Aplicativos Xamarin.Forms em


macOS podem incluir projetos
do iOS, Android e macOS,
sujeitos aos requisitos de SDK
acima.
Projetos Xamarin.Forms para
Windows/UWP não podem ser
criados em macOS.

Xamarin.Mac SDK do macOS Mojave (10.14) O SDK do macOS Mojave (10.14) é


fornecido com o Xcode 10 e é
necessário para a criação de aplicativos
que usam as APIs mais recentes do
macOS.

NOTE
O Xcode pode ser instalado (e atualizado) em developer.apple.com ou por meio da Mac App Store.

Teste e depuração no macOS


Os aplicativos móveis do Xamarin podem ser implantados em dispositivos físicos via USB para teste e
depuração (os aplicativos Apple Watch são implantados primeiro no iPhone emparelhado).
Aplicativos Xamarin.Mac podem ser testados diretamente no computador de desenvolvimento.

N OTA S DE T EST E

Xamarin.iOS A maneira mais fácil para começar é usando o


iPhone, iPad, Apple Watch e simuladores de Apple TV
inclusos no Xcode.
Para usar um dispositivo para teste, siga estas
instruções.

Xamarin.Android Siga estas instruções para configurar seu dispositivoou use


um emulador:
O instalador do Xamarin inclui o Gerenciador de
emulador do Google que permite que você configure
emuladores Android da Google para teste.

Xamarin.Forms Aplicativos Xamarin.Forms para iOS e Android podem ser


implantados nas plataformas relevantes, conforme descrito
acima.

Xamarin.Mac Aplicativos Xamarin.Mac podem ser testados diretamente no


computador de desenvolvimento.
WARNING
O Xamarin.Mac 4.8 dá suporte apenas ao macOS 10.9 (Mavericks) ou superior. As versões anteriores do Xamarin.Mac
eram compatíveis com macOS 10.7 ou superior, mas essas versões mais antigas do macOS não têm infraestrutura TLS
suficiente para dar suporte ao TLS 1.2. Para macOS 10.7 ou macOS 10.8, use o Xamarin.Mac 4.6 ou anterior.

Requisitos do Windows
Para usar um computador Windows para desenvolvimento do Xamarin são necessárias as seguintes versões de
software/SDK. Verifique a versão do sistema operacional (e confirme se você não está usando uma versão
Express do Visual Studio. Caso esteja, considere atualizar para uma edição Community). O instalador do Visual
Studio 2019 e Visual Studio 2017 inclui uma opção para instalar o Xamarin automaticamente (a carga de
trabalho Desenvolvimento móvel com .NET ).

REC O M EN DA DA S O B SERVA Ç Õ ES

Sistema operacional Windows 10 A versão mínima do sistema


operacional é Windows 7. O suporte à
Plataforma Universal do Windows
Xamarin.Forms exige o Windows 10.

Xamarin.iOS SDK do iOS 10 (instalado em um Mac) Para criar projetos do iOS no Windows,
é necessário:
Visual Studio 2017 (é
recomendado o Visual Studio
2019) e
um computador Mac, acessível
pela rede do computador
Windows, que esteja em
conformidade com os
requisitos mínimos para
executar o Xamarin no macOS.

Xamarin.Android Android 6.0 / API nível 23 Você ainda pode direcionar versões
mais antigas do Android enquanto
estiver usando o SDK mais recente ou
pode compilar em relação a versões
anteriores do SDK, se necessário.

Xamarin.Forms Aplicativos Xamarin.Forms para


iOS e Android podem ser
implantados nas plataformas
relevantes, conforme descrito
acima.
Usar o Visual Studio também
significa que você pode testar
aplicativos da Plataforma
Universal do Windows (no
Windows 10) diretamente no
computador de
desenvolvimento.
REC O M EN DA DA S O B SERVA Ç Õ ES

Xamarin.Mac Projetos Xamarin.Mac (aplicativos de


área de trabalho do macOS) podem
ser abertos no Visual Studio e
compilados para verificar se há erros,
mas aplicativos Mac não podem ser
criados atualmente para a distribuição
no Visual Studio.

NOTE
O Xamarin para Visual Studio é compatível com qualquer versão do Visual Studio 2019 ou Visual Studio 2017
(Community, Professional e Enterprise).
Para usar os SDKs mais recentes do Android e do iOS, é necessário ter a versão mais recente do Visual Studio. Para
obter requisitos de versão específicos, confira as notas sobre a versão do Xamarin.Android e as notas sobre a versão
do Xamarin.iOS.
Para desenvolver aplicativos do Xamarin.Forms para a UWP (Plataforma Universal do Windows), é necessário o
Windows 10 com o Visual Studio 2017. É recomendável o Visual Studio 2019.

Teste e depuração no Windows


Os aplicativos móveis do Xamarin podem ser implantados em dispositivos físicos via USB ou sem fio para teste
e depuração (os dispositivos iOS devem estar conectados ao computador Mac e não no computador que está
executando o Visual Studio).

N OTA S DE T EST E

Xamarin.iOS A maneira mais fácil para começar é usando o


iPhone, iPad, Apple Watch e simuladores de Apple TV
inclusos no Xcode. Os simuladores podem ser
acessados no Mac conectado durante a depuração
com o Visual Studio.
Para usar um dispositivo para teste, execute estas
instruções (executando a maioria das etapas no
computador Mac conectado).

Xamarin.Android Execute estas instruções para configurar seu dispositivo ou


use um emulador:
O instalador do Xamarin inclui o Gerenciador de
emulador do Google que permite que você
configure emuladores Android da Google para teste.

Xamarin.Forms Aplicativos Xamarin.Forms podem ser implantados nos


dispositivos e emuladores relevantes, conforme descrito
acima. O aplicativo iOS pode ser testado somente por meio
de hardware Mac conectado; e os aplicativos de
tablet/desktop do Windows para UWP podem ser testados
diretamente no computador de desenvolvimento.

Instruções de instalação
A versão mais recente do Xamarin para macOS pode ser baixada com o Visual Studio para Mac. Para o
Windows, siga as instruções de instalação do Visual Studio.
Uma lista completa das nossas versões atuais do produto está disponível na página de novidades. Esta página
também contém links para as notas sobre a versão.
Instruções de instalação específicas para cada plataforma estão disponíveis aqui:
Xamarin.iOS
Xamarin.Android
Xamarin.Mac
Também há informações adicionais sobre Plataformas compatíveis com o Xamarin.Forms.

Links relacionados
Baixe o Xamarin
Notas sobre a versão do Xamarin.Forms
Notas sobre a versão do Xamarin.Android
Notas sobre a versão do Xamarin.iOS
O ciclo de vida do desenvolvimento de software
móvel
02/11/2020 • 33 minutes to read • Edit Online

Criar aplicativos móveis pode ser tão fácil quanto abrir o Visual Studio, reunir alguns elementos, fazer alguns
testes rápidos e enviar para uma App Store – tudo em uma tarde. Ou pode ser um processo extremamente
complexo que envolve um design inicial rigoroso, teste de usabilidade, teste de garantia de qualidade em
milhares de dispositivos, um ciclo de vida completo beta e, em seguida, implantação de várias maneiras
diferentes.
Neste documento, faremos um exame introdutório minucioso da criação de aplicativos móveis, incluindo:
1. Processo – o processo de desenvolvimento de software é chamado de SDLC (ciclo de vida de
desenvolvimento do software). Examinaremos todas as fases do SDLC em relação ao desenvolvimento de
aplicativos móveis, incluindo: criação, design, desenvolvimento, estabilização, implantação e manutenção.
2. Considerações – há várias considerações ao criar aplicativos móveis, especialmente em contraste com
aplicativos da área de trabalho ou Web tradicionais. Examinaremos essas considerações e como eles afetam
o desenvolvimento para dispositivos móveis.
Este documento destina-se às perguntas fundamentais sobre o desenvolvimento de aplicativos móveis, tanto
para os novos desenvolvedores de aplicativos quanto para os experientes. Ele utiliza uma abordagem bastante
abrangente para introduzir a maioria dos conceitos que você executará durante todo o SDLC (ciclo de vida de
desenvolvimento do software). No entanto, este documento pode não se aplicar a todos. Se você está ansioso
para começar a criar aplicativos, é recomendável avançar para o guia de Introdução ao desenvolvimento móvel
e, em seguida, voltar para este documento mais tarde.

Ciclo de vida do software de desenvolvimento móvel


O ciclo de vida de desenvolvimento móvel praticamente não é diferente do SDLC para aplicativos Web ou da
área de trabalho. Assim como ocorre com estes, geralmente há 5 partes principais do processo:
1. Concepção – todos os aplicativos começam com uma ideia. Essa ideia geralmente é refinada para tornar-se
uma base sólida para um aplicativo.
2. Design – a fase de design consiste em definir a UX (experiência do usuário) do aplicativo, por exemplo,
como é o layout geral, como ele funciona, etc., bem como transformar essa experiência do Usuário em um
design de UI (Interface do Usuário) adequado, geralmente com a Ajuda de um designer gráfico.
3. Desenvolvimento – geralmente a fase com uso mais intensivo de recursos, costuma ser a verdadeira
criação do aplicativo.
4. Estabilização – quando o desenvolvimento é suficiente, o setor de garantia de qualidade geralmente
começa a testar o aplicativo e os erros são corrigidos. Muitas vezes, um aplicativo entra em uma fase beta
limitada na qual um público mais amplo recebe uma oportunidade para usá-lo, fornecer comentários e
informar sobre eventuais alterações.
5. Implantação
Muitas vezes, várias dessas partes são sobrepostas; por exemplo, é comum que o desenvolvimento esteja em
andamento enquanto a interface do usuário está sendo finalizada, sendo que ele pode até mesmo servir de
referência para o design dessa interface do usuário. Além disso, um aplicativo pode estar entrando em uma fase
de estabilização ao mesmo tempo que os novos recursos estão sendo adicionados a uma nova versão.
Além disso, essas fases podem ser usadas em qualquer número de metodologias SDLC como Ágil, Espiral,
Cascata, etc.
Cada uma dessas fases será explicada mais detalhadamente nas seções a seguir.
Começo
A ubiquidade e o nível de interação que as pessoas têm com dispositivos móveis significam que quase todo
mundo tem uma ideia para um aplicativo móvel. Com os dispositivos móveis, abre-se um modo totalmente
novo de interagir com a computação, a Web e até mesmo a infraestrutura empresarial.
O estágio de concepção trata-se de definir e refinar a ideia para um aplicativo. Para criar um aplicativo com
êxito, é importante fazer algumas perguntas fundamentais. Aqui estão algumas coisas a considerar antes de
publicar um aplicativo em uma das lojas de aplicativos públicas:
Vantagem competitiva – já existem aplicativos semelhantes por aí? Nesse caso, como este aplicativo
diferencia dos outros?
Para aplicativos que serão distribuídos em uma empresa:
Integração com a infraestrutura – qual infraestrutura existente ele estenderá ou com qual se integrará?
Além disso, os aplicativos devem ser avaliados no contexto do fator forma móvel:
Valor – que valor esse aplicativo traz os usuários? Como eles o usarão?
Formulário/mobilidade – como esse aplicativo funcionará em um fator forma móvel? Como adicionar
valor usando tecnologias como reconhecimento de local, a câmera, etc.?
Para ajudar a criar a funcionalidade de um aplicativo, pode ser útil definir Atores e Casos de Uso. Os atores são
funções dentro de um aplicativo e geralmente são usuários. Os casos de uso normalmente são ações ou
propósitos.
Por exemplo, um aplicativo de controle de tarefa pode ter dois atores: Usuário e Amigo. Um Usuário pode criar
uma tarefa e compartilhar uma tarefa com um Amigo. Nesse caso, uma tarefa de criar e compartilhar uma
tarefa são dois casos de uso distintos que, em conjunto com os atores, informará quais telas você precisa criar,
bem como quais entidades de negócios e lógica precisarão ser desenvolvidas.
Depois que um número apropriado de casos de uso e atores tiver sido capturado, é muito mais fácil de começar
a criar um aplicativo. O desenvolvimento pode então se concentrar em como criar o aplicativo, em vez do que o
aplicativo é ou deve fazer.
Criando aplicativos móveis
Depois de terem sido determinados os recursos e funcionalidade do aplicativo, a próxima etapa é começar a
tentar resolver a UX ou experiência do usuário.
Design da experiência do usuário
Geralmente, a experiência do usuário é feita por meio de delineados ou modelos com um dos vários kits de
ferramentas de design. Os modelos permitem criar uma experiência do usuário sem necessidade de se
preocupar com o design da interface do usuário real:
Ao criar modelos de experiência do usuário, é importante considerar as diretrizes de interface para as diversas
plataformas às quais o aplicativo se destinará. O aplicativo deve ficar "confortável" todas as plataformas. As
diretrizes de design oficiais para cada plataforma são:
1. Apple - Diretrizes de interface humana
2. Android – diretrizes de design
3. UWP – Noções básicas de design da UWP
Por exemplo, cada aplicativo tem uma metáfora para mudar entre seções em um aplicativo. O iOS usa uma
barra de guias na parte inferior da tela, o Android usa uma barra de guias na parte superior da tela e a UWP usa
a exibição Pivô ou guia.
Além disso, o próprio hardware também determina decisões de experiência do usuário. Por exemplo,
dispositivos iOS não têm nenhum botão voltar físico e, portanto, introduzem a metáfora do Controlador de
Navegação:
Além disso, o fator forma também influencia decisões de experiência do usuário. Um tablet tem muito mais
espaço e, portanto, pode exibir mais informações. Muitas vezes, aquilo que exige várias telas em um telefone é
compactado em uma única em um tablet:
E devido à grande variedade de fatores de forma existentes, geralmente há fatores forma de médio porte (entre
um telefone e um tablet) que você também pode usar como destino.
Design da IU (Interface do Usuário)
Depois que a experiência do usuário é determinada, a próxima etapa é criar o design de interface do usuário.
Enquanto a experiência do usuário é normalmente composta apenas de modelos preto e brancos, a fase de
Design de Interface do Usuário é o momento em que cores, gráficos, etc. são introduzidos e finalizados. Gastar
tempo com um bom design de interface do usuário é importante e geralmente os aplicativos mais populares
têm um design profissional.
Assim como ocorre com a experiência do usuário, é importante entender o que cada plataforma tem sua
própria linguagem de design, portanto, um aplicativo bem projetado ainda pode ter uma aparência diferente
em cada plataforma:
Desenvolvimento
A fase de desenvolvimento normalmente começa bem no início. Na verdade, assim que uma ideia tem algum
amadurecimento na fase conceitual/de inspiração, muitas vezes é desenvolvido um protótipo funcional que
valida a funcionalidade, suposições e ajuda a fornecer uma compreensão do escopo do trabalho.
No restante dos tutoriais, vamos nos concentrar principalmente na fase de desenvolvimento.
Estabilização
A estabilização é o processo de corrigir os bugs do seu aplicativo. Não apenas do ponto de vista funcional, por
exemplo: "Ele falha quando eu clico nesse botão", mas também em termos de usabilidade e desempenho. É
melhor iniciar estabilização muito cedo no processo de desenvolvimento para que as correções possam ocorrer
antes de se tornarem dispendiosas. Normalmente, aplicativos passam pelos estágios de Protótipo, Alfa, Beta e
Versão Release Candidate. Pessoas diferentes definem esses estágios diferentemente, mas eles geralmente
seguem o padrão a seguir:
1. Protótipo – o aplicativo ainda está em fase de prova de conceito e apenas a funcionalidade básica ou partes
específicas do aplicativo estão funcionando. Há bugs importantes presentes.
2. Alfa – o código da funcionalidade básica geralmente está pronto (compilado, mas não totalmente testado).
Ainda há bugs importantes presentes, as funcionalidades secundárias podem ainda não estar presentes.
3. Beta – a maior parte da funcionalidade agora está completa e houve pelo menos testes leves e alguma
correção de bugs. Problemas conhecidos importantes podem ainda estar presentes.
4. Versão Release Candidate – toda a funcionalidade está concluída e testada. Salvo por novos bugs, o
aplicativo é um candidato para liberação para uso.
Nunca é cedo demais para começar a testar um aplicativo. Por exemplo, se um grande problema for encontrado
no estágio de protótipo, a experiência do usuário do aplicativo ainda poderá ser modificada para adequar-se a
ele. Se um problema de desempenho for encontrado no estágio de alfa, será cedo suficiente para modificar a
arquitetura antes que muito código tenha sido criado com base em suposições falsas.
Normalmente, à medida que um aplicativo se move mais adiante no ciclo de vida, ele é aberto para mais
pessoas para experimentá-lo, testá-lo, fornecer comentários etc. Por exemplo, os aplicativos de protótipo só
podem ser mostrados ou disponibilizados para as principais partes interessadas, enquanto os aplicativos
candidatos à versão podem ser distribuídos para os clientes que se inscrevem para acesso antecipado.
Para os primeiros testes e implantação em um número relativamente pequeno de dispositivos, geralmente a
implantação direta de um computador de desenvolvimento é suficiente. No entanto, conforme o público-alvo
aumenta, isso pode rapidamente tornar-se complicado. Assim, há uma série de opções de implantação de teste
por aí que tornam esse processo muito mais fácil ao permitir que você convide pessoas para um pool de teste,
libere builds pela web e forneça ferramentas que permitam obter comentários do usuário.
Para testes e implantação, é possível usar o App Center para criação, teste, versão e monitoramento de
aplicativos de forma contínua.
Distribuição
Quando o aplicativo tiver sido estabilizado, é hora de disponibilizá-lo ao público. Há várias opções de
distribuição diferentes, dependendo da plataforma.
iOS
Aplicativos Xamarin.iOS e Objective-C são distribuídos exatamente do mesmo modo:
1. Apple App Store – a Apple App Store é um repositório de aplicativos online disponível globalmente,
incorporado no Mac OS X por meio do iTunes. Ele é de longe o método de distribuição mais popular para
aplicativos e permite que os desenvolvedores insiram seus aplicativos no mercado e distribuam-nos online
com o mínimo de esforço.
2. Implantação interna – a implantação interna destina-se à distribuição interna dos aplicativos corporativos
que não estão disponíveis publicamente por meio da App Store.
3. Implantação do Ad-Hoc – a implantação Ad-hoc é destinada principalmente para desenvolvimento e teste
e permite que você implante a um número limitado de dispositivos provisionados adequadamente. Quando
você implanta em um dispositivo por meio do Xcode ou Visual Studio para Mac, isso é conhecido como
implantação ad-hoc.
Android
Todos os aplicativos Android devem ser assinados antes de serem distribuídos. Os desenvolvedores assinam
seus aplicativos usando seu próprio certificado protegido por uma chave privada. Esse certificado pode fornecer
uma cadeia de autenticidade que vincula um desenvolvedor de aplicativos aos aplicativos que ele tenha criado e
lançado. Deve-se observar que, embora um certificado de desenvolvimento para Android possa ser assinado
por uma autoridade de certificação reconhecida, a maioria dos desenvolvedores não optam por utilizar esses
serviços e preferem eles próprios assinarem os seus certificados. A principal finalidade dos certificados é
diferenciar entre diferentes desenvolvedores e aplicativos. O Android usa essas informações para ajudá-lo a
imposição da delegação de permissões entre aplicativos e componentes em execução no SO Android.
Ao contrário de outras plataformas móveis populares, o Android adota uma abordagem muito aberta para a
distribuição de aplicativos. Os dispositivos não são bloqueados para uma única loja de aplicativos aprovada. Em
vez disso, todos são livres para criar uma loja de aplicativos e a maioria dos telefones Android permite que os
aplicativos sejam instalados dessas lojas de terceiros.
Isso permite aos desenvolvedores o uso de um canal de distribuição para seus aplicativos que, apesar de
potencialmente maior, é mais complexo. Google Play é a loja de aplicativos oficial do Google, mas há muitas
outras. Algumas populares são:
1. AppBrain
2. Amazon App Store para Android
3. Handango
4. GetJar
UWP
Aplicativos UWP são distribuídos aos usuários por meio da Microsoft Store. Os desenvolvedores enviam seus
aplicativos para aprovação e depois disso eles aparecem na loja. Para saber mais sobre como publicar
aplicativos do Windows, consulte a documentação de Publicação da UWP.

Considerações sobre desenvolvimento móvel


Embora o desenvolvimento de aplicativos móveis não seja fundamentalmente diferente de desenvolvimento de
área de trabalho/Web tradicional em termos de arquitetura ou processo, há algumas considerações sobre as
quais devemos estar atentos.
Considerações comuns
Multitarefa
Há dois desafios significativos para execução multitarefa (ter vários aplicativos em execução ao mesmo tempo)
em um dispositivo móvel. Primeiro, devido à limitação do espaço de tela, é difícil exibir vários aplicativos
simultaneamente. Portanto, em dispositivos móveis, apenas um aplicativo por vez pode ficar em primeiro plano.
Segundo, manter vários aplicativos abertos e executando tarefas podem usar a energia da bateria rapidamente.
Cada plataforma lida com multitarefa de modo diferente, o que exploraremos daqui a pouco.
Fator forma
Dispositivos móveis geralmente se encaixam em duas categorias, telefones e tablets, com alguns dispositivos de
transição intermediários. O desenvolvimento desses fatores forma é geralmente muito semelhante, no entanto,
a criação de aplicativos para eles pode ser muito diferente. Smartphones têm espaço de tela muito limitado e
tablets, embora maiores, ainda são dispositivos móveis com menos espaço de tela até mesmo do que a maioria
dos laptops. Por isso, controles de interface do usuário da plataforma móvel foram projetados especificamente
para serem eficazes em fatores forma menores.
Fragmentação do sistema operacional e dispositivo
É importante levar em conta diferentes dispositivos em todo o ciclo de vida de desenvolvimento de software:
1. Conceitualização e planejamento – lembre-se que o hardware e os recursos variam de dispositivo para
dispositivo, um aplicativo que depende de alguns recursos pode não funcionar corretamente em certos
dispositivos. Por exemplo, nem todos os dispositivos têm câmeras, portanto, se você estiver criando um
aplicativo de mensagens de vídeo, alguns dispositivos podem ser capazes de reproduzir vídeos, mas não de
capturá-los.
2. Design – durante a criação da UX (experiência do usuário) de um aplicativo, preste atenção às diferentes
proporções e tamanhos de tela em todos os dispositivos. Além disso, ao criar a IU (interface do usuário) de
um aplicativo, diferentes resoluções de tela devem ser consideradas.
3. Desenvolvimento – ao usar um recurso do código, a presença do recurso deve sempre ser testada
primeiro. Por exemplo, antes de usar um recurso de dispositivo, como uma câmera, sempre consultar
primeiro o sistema operacional quanto à presença do recurso. Em seguida, ao inicializar o
recurso/dispositivo, certifique-se de solicitar ao SO o que tem suporte atualmente com relação a esse
dispositivo e, em seguida, use essas configurações.
4. Teste – é incrivelmente importante testar o aplicativo cedo e frequentemente em dispositivos reais. Até
mesmo dispositivos com as mesmas especificações de hardware podem variar muito em seu
comportamento.
Recursos limitados
Dispositivos móveis tornam-se mais e mais eficientes o tempo todo, mas são dispositivos móveis com
funcionalidades limitadas em comparação com computadores desktop ou notebooks. Por exemplo,
desenvolvedores de aplicativos para computadores desktop geralmente não se preocupam com recursos de
memória; eles estão acostumados a ter memória física e virtual em grandes quantidades, enquanto em
dispositivos móveis você pode rapidamente consumir toda a memória disponível apenas ao carregar um
punhado de imagens de alta qualidade.
Além disso, aplicativos de processamento intensivo como jogos ou reconhecimento de texto podem
sobrecarregar de verdade a CPU móvel e afetar negativamente o desempenho do dispositivo.
Por causa de considerações como essa, é importante escrever código com inteligência e implantar
antecipadamente e com frequência para dispositivos reais, a fim de validar a capacidade de resposta.
Considerações do iOS
Multitarefa
Multitarefa é rigidamente controlada no iOS e há uma série de regras e comportamentos com os quais seu
aplicativo deverá estar em conformidade quando outro aplicativo vier para o primeiro plano, caso contrário, seu
aplicativo será encerrado pelo iOS.
Recursos específicos do dispositivo
Dentro de um fator forma particular, o hardware pode variar significativamente entre diferentes modelos. Por
exemplo, alguns dispositivos têm uma câmera voltada para a parte traseira, alguns também têm uma câmera
voltada para a frente e alguns não têm nenhuma.
Alguns dispositivos mais antigos (iPhone 3G e anteriores) nem mesmo permitem a execução multitarefa.
Devido a essas diferenças entre modelos de dispositivo, é importante verificar a presença de um recurso antes
de tentar usá-lo.
Restrições específicas do SO
Para certificar-se de que os aplicativos sejam responsivos e seguros, o iOS impõe uma série de regras às quais
os aplicativos devem obedecer. Além das regras relativas à execução multitarefa, há uma série de métodos de
evento dos quais seu aplicativo deve retornar em um determinado período de tempo, caso contrário, que ele
será encerrado pelo iOS.
Também vale a pena observar que os aplicativos são executados no que é conhecido como uma área restrita,
um ambiente que impõe restrições de segurança que restringem o que seu aplicativo pode acessar. Por
exemplo, um aplicativo pode ler e gravar seu próprio diretório, mas se tentar gravar no diretório de outro
aplicativo, ele será encerrado.
Considerações sobre o Android
Multitarefa
Execução multitarefa no Android tem dois componentes; o primeiro é o ciclo de vida da atividade. Cada tela em
um aplicativo Android é representada por uma atividade e há um conjunto específico de eventos que ocorrem
quando um aplicativo é colocado em segundo plano ou vem para o primeiro plano. É necessário seguir esse
ciclo de vida para criar aplicativos responsivos e com bom comportamento. Para obter mais informações, veja o
guia Ciclo de vida de atividade.
O segundo componente da execução multitarefa no Android é o uso de Serviços. Os Serviços são processos de
execução longa que existem independentemente de um aplicativo e são usados para executar processos
enquanto o aplicativo está em segundo plano. Para obter mais informações, veja o guia Criando serviços.
Muitos dispositivos e muitos fatores forma
O Google não impõe limites quanto a quais dispositivos podem executar o sistema operacional Android. Esse
paradigma aberto resulta em um ambiente de produtos populado por uma grande variedade de dispositivos
diferentes com hardware, taxas de proporção e resoluções de tela, recursos do dispositivo e funcionalidades
muito diferentes.
Devido à fragmentação extrema de dispositivos Android, a maioria das pessoas escolhe os 5 ou 6 dispositivos
mais populares para os quais projetar e testar e dá prioridade a eles.
Considerações sobre segurança
Todos os aplicativos no SO Android executam sob uma identidade distinta e isolada, com permissões limitadas.
Por padrão, os aplicativos podem fazer muito pouco. Por exemplo, sem permissões especiais, um aplicativo não
pode enviar uma mensagem de texto, determinar o estado do telefone ou até mesmo acessar a Internet! Para
acessar esses recursos, os aplicativos devem especificar no seu arquivo de manifesto do aplicativo quais
permissões eles desejam e quando eles serão instalados. O SO lê essas permissões, notifica o usuário que o
aplicativo está solicitando essas permissões e, em seguida, permite que o usuário continue ou cancele a
instalação. Essa é uma etapa essencial no modelo de distribuição Android por causa do modelo aberto de
repositório de aplicativos, já que os aplicativos não são coletados do modo que seriam para iOS, por exemplo.
Para obter uma lista de permissões de aplicativo, veja o artigo de referência Permissões de Manifesto na
documentação do Android.
Considerações do Windows
Multitarefa
A execução multitarefa na UWP tem duas partes: o ciclo de vida de páginas e aplicativos e os processos em
segundo plano. Cada tela em um aplicativo é uma instância de uma classe de página, que tem eventos
associados que estão sendo tornados ativos ou inativos (com regras especiais para lidar com o estado inativo
ou sendo "marcados para exclusão").
A segunda parte é fornecer agentes de segundo plano para tarefas de processamento, mesmo quando o
aplicativo não está em execução em primeiro plano.
Funcionalidades de dispositivo
Embora o hardware da UWP seja bastante homogêneo, ainda há componentes opcionais que, portanto, exigem
consideração especial durante a codificação. As funcionalidades opcionais do hardware incluem a câmera, a
bússola e o giroscópio. Há também uma classe especial de memória insuficiente (256 MB) que requer
consideração especial ou os desenvolvedores podem optar por não dar suporte a memória insuficiente.
Considerações sobre segurança
Para saber mais sobre considerações de segurança importantes na UWP, consulte a documentação de
Segurança.

Resumo
Este guia forneceu uma introdução para o SDLC, pois ele diz respeito ao desenvolvimento móvel. Ele introduziu
considerações gerais para a criação de aplicativos móveis e examinou uma série de considerações específicas da
plataforma incluindo design, teste e implantação.

Próximas etapas
O que é o Xamarin?
Introdução ao Xamarin
Como compartilhar o código entre plataformas
Compilando aplicativos multiplataforma
02/11/2020 • 2 minutes to read • Edit Online

Há duas opções para compartilhar código entre aplicativos móveis de plataforma cruzada: projetos de ativos
compartilhados e bibliotecas de classes portáteis. Essas opções são discutidas aqui; mais informações sobre
bibliotecas de classes portáteis e projetos compartilhados também estão disponíveis.
Visão geral
Parte 1 – noções básicas sobre a plataforma do Xamarin Mobile
Parte 2 – arquitetura
Parte 3 – Configurando uma solução de plataforma cruzada do Xamarin
Parte 4 – lidando com várias plataformas
Parte 5 – estratégias de compartilhamento de código práticas
Parte 6-aprovações de aplicativos de teste e de loja

Estudos de Caso
Os princípios descritos neste documento são colocados em prática na tarefade aplicativo de exemplo, bem
como aplicativos pré-criados como o Xamarin CRM.
Tasky
A tarefa é um aplicativo simples de lista de tarefas pendentes para iOS, Android e Windows Phone. Ele
demonstra as noções básicas de criação de um aplicativo de plataforma cruzada com o Xamarin e usa um banco
de dados SQLite local.

da
Leia o estudo de caso de tarefa.

Resumo
Esta seção apresenta as ferramentas de desenvolvimento de aplicativos do Xamarin e discute como criar
aplicativos direcionados a várias plataformas móveis.
Ele abrange uma arquitetura em camadas que estrutura o código para reutilização em várias plataformas e
descreve padrões de software diferentes que podem ser usados nessa arquitetura.
Os exemplos são fornecidos por funções de aplicativo comuns (como operações de arquivo e rede) e como eles
podem ser criados em uma forma de plataforma cruzada.
Por fim, ele aborda brevemente os testes e fornece referências a um estudo de caso que coloca esses princípios
em ação.

Links Relacionados
Opções de código de compartilhamento
Estudo de caso: Tasky
Aplicativo de exemplo de tarefa (github)
Desenvolvimento de aplicativo móvel xamarin: fundamentos de plataforma cruzada e C# e Xamarin. Forms
(Amazon)
Desenvolvimento móvel com C# por Greg Shackles (o ' Reilly)
Criando visão geral de aplicativos de plataforma
cruzada
15/01/2021 • 7 minutes to read • Edit Online

Este guia apresenta a plataforma Xamarin e como arquitetar um aplicativo de plataforma cruzada para
maximizar o uso de código e fornecer uma experiência nativa de alta qualidade em todas as principais
plataformas móveis: iOS, Android e Windows Phone.
A abordagem usada neste documento geralmente se aplica a aplicativos de produtividade e aplicativos de jogos,
mas o foco está na produtividade e no utilitário (aplicativos sem jogo). Consulte Ferramentas do Visual Studio
para Unity para obter diretrizes de desenvolvimento de jogos entre plataformas.
A frase "Write-Once, executar em qualquer lugar" é geralmente usada para enalteça as virtudes de uma única
base de código que é executada sem modificações em várias plataformas. Embora ele tenha o benefício de
reutilização de código, essa abordagem geralmente leva a aplicativos que têm um conjunto de recursos de
denominador mais baixo-comum e uma interface de usuário de aparência genérica que não se encaixa
perfeitamente em nenhuma das plataformas de destino.
O Xamarin não é apenas uma plataforma de "gravação única, executada em qualquer lugar", porque um de seus
pontos fortes é a capacidade de implementar interfaces de usuário nativas especificamente para cada
plataforma. No entanto, com um design elaborado, ainda é possível compartilhar a maior parte do código de
interface que não seja do usuário e obter o melhor dos dois mundos: escrever seu código de armazenamento de
dados e de lógica de negócios uma vez e apresentar interfaces de usuário nativas em cada plataforma. Este
documento discute uma abordagem arquitetônica geral para atingir essa meta.
Aqui está um resumo dos principais pontos para criar aplicativos de plataforma cruzada do Xamarin:
Use c# – escreva seus aplicativos em c#. O código existente escrito em C# pode ser portado para iOS e
Android usando o Xamarin com muita facilidade e, obviamente, usado em aplicativos do Windows.
Utilizar padrões de design do modelo MVC ou MVVM – desenvolva a interface do usuário do
aplicativo usando o padrão Model/View/Controller. Projete seu aplicativo usando uma abordagem de
modelo/exibição/controlador ou uma abordagem de Model/View/ViewModel em que há uma separação
clara entre o "modelo" e o restante. Determine quais partes do seu aplicativo usarão elementos nativos da
interface do usuário de cada plataforma (iOS, Android, Windows, Mac) e use-o como uma diretriz para
dividir seu aplicativo em dois componentes: "Core" e "user-interface".
Criar UIs nativas -cada aplicativo específico do sistema operacional fornece uma camada de interface de
usuário diferente (implementada em C# com a ajuda de ferramentas de design de interface do usuário
nativas):
1. No iOS, use as APIs do UIKit para criar aplicativos de aparência nativa, utilizando opcionalmente o iOS
designer do Xamarin para criar sua interface do usuário visualmente.
2. No Android, use Android. views para criar aplicativos de aparência nativa, tirando proveito do designer de
interface do usuário do Xamarin.
3. No Windows, você usará o XAML para a camada de apresentação, criado no designer de interface do usuário
do Visual Studio ou do Blend.
4. No Mac, você usará storyboards para a camada de apresentação, criada no Xcode.
Os projetos do Xamarin. Forms têm suporte em todas as plataformas e permitem que você crie interfaces do
usuário que podem ser compartilhadas entre plataformas usando o XAML do Xamarin. Forms.
A quantidade de reutilização de código dependerá, em grande parte, da quantidade de código mantida no
núcleo compartilhado e da quantidade de código específica da interface do usuário. O código principal é
qualquer coisa que não interaja diretamente com o usuário, mas, em vez disso, fornece serviços para partes do
aplicativo que coletarão e exibirão essas informações.
Para aumentar a quantidade de reutilização de código, você pode adotar componentes de plataforma cruzada
que fornecem serviços comuns em todos esses sistemas, como:
1. SQLite-net para o armazenamento local do SQL,
2. Plugins do Xamarin para acessar recursos específicos do dispositivo, incluindo câmera, contatos e
geolocalização,
3. Pacotes NuGet que são compatíveis com projetos do Xamarin, como JSON.net,
4. Usando recursos do .NET Framework para rede, serviços Web, e/s e muito mais.
Alguns desses componentes são implementados no estudo de caso de tarefa .

Separar código reutilizável em uma biblioteca principal


Seguindo o princípio de separação de responsabilidade, colocando em camadas a arquitetura do aplicativo e,
em seguida, movendo a funcionalidade principal que é independente da plataforma em uma biblioteca principal
reutilizável, você pode maximizar o compartilhamento de código entre plataformas, como a figura abaixo
ilustra:

Estudos de Caso
Há um estudo de caso que acompanha este documento – taskal pro. Cada estudo de caso aborda a
implementação dos conceitos descritos neste documento em um exemplo do mundo real. O código é de
código-fonte aberto e está disponível no GitHub.
Parte 1 – noções básicas sobre a plataforma do
Xamarin Mobile
02/11/2020 • 19 minutes to read • Edit Online

A plataforma Xamarin consiste em vários elementos que permitem desenvolver aplicativos para iOS e Android:
Linguagem C# – permite que você use uma sintaxe familiar e recursos sofisticados, como genéricos, LINQ e
a biblioteca de tarefas paralelas.
Mono .NET Framework – fornece uma implementação de plataforma cruzada dos recursos abrangentes
do .NET Framework da Microsoft.
Compilador – dependendo da plataforma, produz um aplicativo nativo (por exemplo, iOS) ou um aplicativo
.NET integrado e tempo de execução (por exemplo, Android). O compilador também executa muitas
otimizações para implantação móvel, como a vinculação de código não utilizado.
Ferramentas IDE – o Visual Studio no Mac e no Windows permite que você crie, compile e implante
projetos do Xamarin.
Além disso, como a linguagem subjacente é C# com o .NET Framework, os projetos podem ser estruturados
para compartilhar código que também pode ser implantado para Windows Phone.

Nos bastidores
Embora o Xamarin permita que você escreva aplicativos em C# e compartilhe o mesmo código em várias
plataformas, a implementação real em cada sistema é muito diferente.

Compilação
A origem do C# deixa seu caminho em um aplicativo nativo de maneiras muito diferentes em cada plataforma:
Ios – C# é uma AOT (antecipada de tempo) compilada para a linguagem do assembly ARM. O .NET
Framework está incluído, com classes não utilizadas sendo removidas durante a vinculação para reduzir o
tamanho do aplicativo. A Apple não permite a geração de código em tempo de execução no iOS, portanto
alguns recursos de linguagem não estão disponíveis (consulte limitações do Xamarin. Ios ).
Android – o C# é compilado para Il e empacotado com MonoVM + JIT'ing. As classes não utilizadas na
estrutura são eliminadas durante a vinculação. O aplicativo é executado lado a lado com Java/arte (tempo de
execução do Android) e interage com os tipos nativos por meio de JNI (Confira limitações do Xamarin.
Android ).
O Windows – C# é compilado para Il e executado pelo tempo de execução interno e não requer ferramentas
do Xamarin. A criação de aplicativos do Windows seguindo as diretrizes do Xamarin torna mais simples
reutilizar o código no iOS e no Android. Observe que o Plataforma Universal do Windows também tem uma
opção .net Native que se comporta da mesma forma que a compilação AOT do Xamarin. Ios.
A documentação do vinculador para xamarin. Ios e xamarin. Android fornece mais informações sobre essa parte
do processo de compilação.
Tempo de execução ' Compilation ' – gerando código dinamicamente com System.Reflection.Emit – deve ser
evitado.
O kernel da Apple impede a geração de código dinâmico em dispositivos iOS, portanto, emitir código
imediatamente não funcionará no Xamarin. iOS. Da mesma forma, os recursos de tempo de execução de
linguagem dinâmica não podem ser usados com as ferramentas do Xamarin.
Alguns recursos de reflexão funcionam (por exemplo, O MonoTouch. Dialog o usa para a API de reflexão),
apenas para a geração de código.

Acesso ao SDK da plataforma


O Xamarin torna os recursos fornecidos pelo SDK específico da plataforma facilmente acessíveis com uma
sintaxe C# familiar:
Ios – Xamarin. Ios expõe as estruturas do SDK do Cocoatouch da Apple como namespaces que você pode
referenciar do C#. Por exemplo, a estrutura UIKit que contém todos os controles de interface do usuário pode
ser incluída com uma using UIKit; instrução simples.
Android – Xamarin. Android expõe os SDK do Android do Google como namespaces, para que você possa
fazer referência a qualquer parte do SDK com suporte com uma instrução using, como
using Android.Views; para acessar os controles da interface do usuário.
Windows – os aplicativos do Windows são criados usando o Visual Studio no Windows. Os tipos de projeto
incluem Windows Forms, WPF, WinRT e Plataforma Universal do Windows (UWP).

Integração direta para desenvolvedores


A beleza do Xamarin é que, apesar das diferenças nos bastidores, o Xamarin. iOS e o Xamarin. Android
( juntamente com os SDKs do Windows da Microsoft) oferecem uma experiência simples para escrever código
C# que pode ser reutilizado em todas as três plataformas.
A lógica de negócios, o uso do banco de dados, o acesso à rede e outras funções comuns podem ser gravados
uma vez e reutilizados em cada plataforma, fornecendo uma base para interfaces de usuário específicas da
plataforma que parecem e executam como aplicativos nativos.

Disponibilidade do ambiente de desenvolvimento integrado (IDE)


O desenvolvimento do Xamarin pode ser feito no Visual Studio no Mac ou no Windows. O IDE escolhido será
determinado pelas plataformas que você deseja direcionar.
Como os aplicativos do Windows só podem ser desenvolvidos no Windows, para compilar para iOS, Android e
Windows, é necessário ter o Visual Studio para Windows. No entanto, é possível compartilhar projetos e
arquivos entre computadores Windows e Mac, portanto, aplicativos iOS e Android podem ser criados em um
Mac e um código compartilhado pode ser adicionado posteriormente a um projeto do Windows.
Os requisitos de desenvolvimento para cada plataforma são discutidos em mais detalhes no guia de requisitos .
iOS
O desenvolvimento de aplicativos iOS requer um computador Mac, executando o macOS. Você também pode
usar o Visual Studio para escrever e implantar aplicativos iOS com o Xamarin no Visual Studio. No entanto, um
Mac ainda é necessário para fins de criação e licenciamento.
O Xcode IDE da Apple deve ser instalado para fornecer o compilador e o simulador para teste. Você pode testar
seus próprios dispositivos gratuitamente, mas para compilar aplicativos para distribuição ( porexemplo, a loja
de aplicativos) você deve ingressar no programa de desenvolvedor da Apple (US $ $99 USD por ano). Cada vez
que você envia ou atualiza um aplicativo, ele deve ser revisado e aprovado pela Apple antes de ser
disponibilizado para os clientes baixarem.
O código é escrito com o IDE do Visual Studio e os layouts de tela podem ser criados programaticamente ou
editados com o iOS designer do Xamarin em qualquer IDE.
Consulte o Guia de instalação do Xamarin. Ios para obter instruções detalhadas sobre como configurar.
Android
O desenvolvimento de aplicativos Android requer que os SDKs Java e Android sejam instalados. Eles fornecem o
compilador, o emulador e outras ferramentas necessárias para compilar, implantar e testar. Java, as ferramentas
do SDK do Android e do Xamarin da Google podem ser instaladas e executadas no Windows e no macOS. As
seguintes configurações são recomendadas:
Windows 10 com Visual Studio 2019
macOS Mojave (10.11 +) com o Visual Studio 2019 para Mac
O Xamarin fornece um instalador unificado que irá configurar seu sistema com as ferramentas Java, Android e
Xamarin de pré-requisito (incluindo um designer visual para layouts de tela). Consulte o Guia de instalação do
Xamarin. Android para obter instruções detalhadas.
Você pode criar e testar aplicativos em um dispositivo real sem qualquer licença do Google, no entanto, para
distribuir seu aplicativo por meio de uma loja (como Google Play, Amazon ou Barnes & Noble), uma taxa de
registro pode ser paga para o operador. Google Play publicará seu aplicativo instantaneamente, enquanto os
outros armazenamentos têm um processo de aprovação semelhante ao da Apple.
Windows
Os aplicativos do Windows (WinForms, WPF ou UWP) são criados com o Visual Studio. Eles não usam o
Xamarin diretamente. No entanto, o código C# pode ser compartilhado entre o Windows, o iOS e o Android.
Visite o centro de desenvolvimento da Microsoft para saber mais sobre as ferramentas necessárias para o
desenvolvimento do Windows.

Criando a interface do usuário (IU)


Um dos principais benefícios do uso do Xamarin é que a interface do usuário do aplicativo usa controles nativos
em cada plataforma, criando aplicativos que são indistinguíveis de um aplicativo escrito em Objective-C ou Java
(para iOS e Android, respectivamente).
Ao criar telas em seu aplicativo, você pode dispor os controles no código ou criar telas completas usando as
ferramentas de design disponíveis para cada plataforma.
Criar controles programaticamente
Cada plataforma permite que controles de interface do usuário sejam adicionados a uma tela usando código.
Isso pode ser muito demorado, pois pode ser difícil visualizar o design concluído ao embutir coordenadas de
pixels para posições de controle e tamanhos.
No entanto, criar controles de forma programática tem benefícios, especialmente em iOS para criar exibições
que redimensionam ou renderizam de forma diferente nos tamanhos de tela iPhone e iPad.
Designer Visual
Cada plataforma tem um método diferente para dispor visualmente das telas:
Ios – o Ios designer do Xamarin facilita a criação de exibições usando a funcionalidade e os campos de
Propriedade do tipo "arrastar e soltar". Coletivamente, essas exibições compõem um storyboard e podem ser
acessadas no **. **Arquivo de Storyboard que está incluído no seu projeto.
Android – o Xamarin fornece um designer de interface do usuário do tipo "arrastar e soltar" do Android
para Visual Studio. Os layouts de tela do Android são salvos como . AXML arquivos ao usar as ferramentas
do Xamarin.
Windows – a Microsoft fornece um designer de interface do usuário de arrastar e soltar no Visual Studio e
no Blend. Os layouts de tela são armazenados como. Arquivos XAML.
Essas capturas de tela mostram os designers de telas visuais disponíveis em cada plataforma:
Em todos os casos, os elementos que você cria visualmente podem ser referenciados em seu código.
Considerações sobre interface do usuário
Um dos principais benefícios de usar o Xamarin para criar aplicativos de plataforma cruzada é que eles podem
tirar proveito dos kits de conhecimento da interface do usuário nativa para apresentar uma interface familiar
para os usuários. A interface do usuário também será executada tão rápido quanto qualquer outro aplicativo
nativo.
Algumas metáforas de interface do usuário funcionam em várias plataformas (por exemplo, todas as três
plataformas usam um controle de lista de rolagem semelhante), mas, para que seu aplicativo fique à direita, a
interface do usuário deve tirar proveito dos elementos da interface específica da plataforma, quando
apropriado. Exemplos de metáforas de interface do usuário específicas da plataforma incluem:
Ios – navegação hierárquica com botão de reversão suave, guias na parte inferior da tela.
Android – hardware/sistema – botão voltar do software, menu Ação, guias na parte superior da tela.
Windows – os aplicativos do Windows podem ser executados em desktops, tablets (como Microsoft
Surface) e telefones. Os dispositivos Windows 10 podem ter o botão voltar do hardware e os blocos
dinâmicos, por exemplo.
É recomendável que você leia as diretrizes de design relevantes para as plataformas para as quais você está se
concentrando:
Ios – diretrizes de interface humana da Apple
Android – diretrizes de interface do usuário do Google
Windows – diretrizes de design da experiência do usuário para Windows

Reutilização de biblioteca e código


A plataforma Xamarin permite reutilização de código C# existente em todas as plataformas, bem como a
integração de bibliotecas escritas nativamente para cada plataforma.
Bibliotecas e origem do C#
Como os produtos Xamarin usam C# e o .NET Framework, muitos códigos-fonte existentes (tanto de código-
fonte aberto quanto de projetos internos) podem ser reutilizados em projetos Xamarin. iOS ou Xamarin.
Android. Geralmente, a fonte pode ser simplesmente adicionada a uma solução Xamarin e funcionará
imediatamente. Se um recurso do .NET Framework sem suporte tiver sido usado, alguns ajustes poderão ser
necessários.
Exemplos de origem em C# que podem ser usados em Xamarin. iOS ou Xamarin. Android incluem: SQLite-NET,
NewtonSoft.JSem e SharpZipLib.
Associações Objective -C + projetos de associação
O Xamarin fornece uma ferramenta chamada btouch que ajuda a criar associações que permitem que
bibliotecas de Objective-C sejam usadas em projetos do Xamarin. Ios. Consulte a documentação sobre tipos
Objective-C de associação para obter detalhes sobre como isso é feito.
Exemplos de bibliotecas Objective-C que podem ser usadas no Xamarin. iOS incluem: verificação de código de
barras RedLaser, Google Analytics e integração com o PayPal. As associações do Xamarin. iOS de código aberto
estão disponíveis no GitHub.
Associações. jar + projetos de associação
O xamarin dá suporte ao uso de bibliotecas Java existentes no Xamarin. Android. Consulte a documentação
vinculando uma biblioteca Java para obter detalhes sobre como usar um. Arquivo JAR do Xamarin. Android.
As associações do Xamarin. Android de código aberto estão disponíveis no GitHub.
C via PInvoke
A tecnologia de "invocação de plataforma" (P/Invoke) permite que o código gerenciado (C#) Chame métodos
em bibliotecas nativas, bem como suporte para bibliotecas nativas para chamar o código gerenciado.
Por exemplo, a biblioteca SQLite-net usa instruções como esta:

[DllImport("sqlite3", EntryPoint = "sqlite3_open", CallingConvention=CallingConvention.Cdecl)]


public static extern Result Open (string filename, out IntPtr db);

Isso é associado à implementação do SQLite nativo em C-Language no iOS e no Android. Os desenvolvedores


familiarizados com uma API C existente podem construir um conjunto de classes C# para mapear para a API
nativa e utilizar o código de plataforma existente. Há documentação para vincular bibliotecas nativas no
Xamarin. Ios, os princípios semelhantes se aplicam ao Xamarin. Android.
C++ via CppSharp
Miguel explica CXXI (agora chamado de CppSharp) em seu blog. Uma alternativa à associação a uma biblioteca
C++ diretamente é criar um invólucro C e associá-lo por meio de P/Invoke.
Parte 2 – Arquitetura
02/11/2020 • 10 minutes to read • Edit Online

Uma filosofia importante da criação de aplicativos de plataforma cruzada é criar uma arquitetura que se presta
a uma maximização do compartilhamento de código entre plataformas. Obedecer aos seguintes princípios de
programação orientada a objeto ajuda a criar um aplicativo bem projetado:
Encapsulamento – garantindo que as classes e até mesmo as camadas de arquitetura exponham apenas
uma API mínima que executa suas funções necessárias e oculta os detalhes da implementação. Em um nível
de classe, isso significa que os objetos se comportam como ' caixas pretas ' e que o código de consumo não
precisa saber como eles realizam suas tarefas. Em um nível de arquitetura, isso significa implementar
padrões como a fachada que incentiva uma API simplificada que orquestra interações mais complexas em
nome do código em camadas mais abstratas. Isso significa que o código da interface do usuário (por
exemplo) só deve ser responsável por exibir telas e aceitar a entrada do usuário; e nunca interagir
diretamente com o banco de dados. Da mesma forma, o código de acesso a dados só deve ler e gravar no
banco de dado, mas nunca interagir diretamente com botões ou rótulos.
Separação de responsabilidades – garanta que cada componente (em arquitetura e nível de classe) tenha
uma finalidade clara e bem definida. Cada componente deve executar apenas suas tarefas definidas e expor
essa funcionalidade por meio de uma API que seja acessível para as outras classes que precisam usá-la.
Polimorfismo – a programação para uma interface (ou classe abstrata) que dá suporte a várias
implementações significa que o código principal pode ser escrito e compartilhado entre plataformas,
enquanto ainda interage com recursos específicos da plataforma.
O resultado natural é um aplicativo modelado após entidades do mundo real ou abstratas com camadas lógicas
separadas. Separar o código em camadas torna os aplicativos mais fáceis de entender, testar e manter. É
recomendável que o código em cada camada seja fisicamente separado (em diretórios ou até mesmo projetos
separados para aplicativos muito grandes), bem como separados logicamente (usando namespaces).

Camadas de aplicativo típicas


Ao longo deste documento e dos estudos de caso, nos referimos às seis camadas de aplicativo a seguir:
Camada de dados – persistência de dados não volátil, provavelmente é um banco de dados SQLite, mas
pode ser implementada com arquivos XML ou qualquer outro mecanismo adequado.
Camada de acesso a dados – wrapper em volta da camada de dados que fornece acesso de criação,
leitura, atualização, exclusão (CRUD) aos dados sem expor detalhes de implementação para o chamador. Por
exemplo, a DAL pode conter instruções SQL para consultar ou atualizar os dados, mas o código de referência
não precisa saber isso.
Camada de negócios – (às vezes chamada de camada de lógica de negócios ou BLL) contém definições de
entidade de negócios (o modelo) e lógica de negócios. Padrão de fachada do candidato para empresas.
Camada de acesso de ser viço – usada para acessar serviços na nuvem: de serviços da Web complexos
(REST, JSON, WCF) até a recuperação simples de dados e imagens de servidores remotos. Encapsula o
comportamento de rede e fornece uma API simples a ser consumida pelas camadas de aplicativo e de
interface do usuário.
Camada de aplicativo – código que normalmente é específico da plataforma (geralmente não
compartilhada entre plataformas) ou código que é específico para o aplicativo (geralmente não reutilizável).
Um bom teste de colocação do código na camada de aplicativo versus a camada da interface do usuário é (a)
para determinar se a classe tem algum controle de exibição real ou (b) se ele pode ser compartilhado entre
várias telas ou dispositivos (por exemplo, iPhone e iPad).
Camada de interface do usuário (IU) – a camada voltada para o usuário, contém telas, widgets e
controladores que os gerenciam.
Um aplicativo pode não conter necessariamente todas as camadas – por exemplo, a camada de acesso ao
serviço não existirá em um aplicativo que não acesse recursos de rede. Um aplicativo muito simples pode
mesclar a camada de dados e a camada de acesso a dados porque as operações são extremamente básicas.

Padrões comuns de software móvel


Padrões são uma maneira estabelecida de capturar soluções recorrentes para problemas comuns. Há alguns
padrões importantes que são úteis para entender na criação de aplicativos móveis que podem ser
mantidos/compreensíveis.
Model, View, ViewModel (MVVM) – o padrão Model-View-ViewModel é popular com estruturas que dão
suporte à vinculação de dados, como Xamarin. Forms. Ele foi popular por SDKs habilitados para XAML como
o Windows Presentation Foundation (WPF) e o Silverlight; em que o ViewModel atua como uma passagem
entre os dados (modelo) e a interface do usuário (exibição) por meio de vinculação de dados e comandos.
Modelo, exibição, controlador (MVC) – um padrão comum e geralmente mal compreendido, o MVC é
usado com mais frequência ao criar interfaces do usuário e fornece uma separação entre a definição real de
uma tela de IU (exibição), o mecanismo por trás dela que lida com a interação (controlador) e os dados que o
popula (modelo). O modelo é, na verdade, uma parte totalmente opcional e, portanto, o núcleo da
compreensão desse padrão está na exibição e no controlador. O MVC é uma abordagem popular para
aplicativos iOS.
Fachada de negócios – também conhecido como padrão de gerente, fornece um ponto de entrada
simplificado para trabalho complexo. Por exemplo, em um aplicativo de rastreamento de tarefas, você pode
ter uma TaskManager classe com métodos como GetAllTasks() , GetTask(taskID) , SaveTask (task) , etc. A
TaskManager classe fornece uma fachada para os trabalhos internos de realmente salvar/recuperar objetos
de tarefas.
Singleton – o padrão singleton fornece uma maneira na qual apenas uma única instância de um objeto
específico pode existir. Por exemplo, ao usar o SQLite em aplicativos móveis, você sempre desejará uma
instância do banco de dados. Usar o padrão singleton é uma maneira simples de garantir isso.
Provedor – um padrão cunhado pela Microsoft (possivelmente semelhante à estratégia ou injeção de
dependência básica) para incentivar o reuso de código nos aplicativos Silverlight, WPF e WinForms. O código
compartilhado pode ser escrito em uma interface ou classe abstrata, e implementações concretas específicas
da plataforma são escritas e passadas quando o código é usado.
Async – não deve ser confundido com a palavra-chave Async, o padrão assíncrono é usado quando o
trabalho de execução longa precisa ser executado sem manter a interface do usuário ou o processamento
atual. Em sua forma mais simples, o padrão assíncrono simplesmente descreve que tarefas de longa
execução devem ser iniciadas em outro thread (ou abstração de thread semelhante, como uma tarefa),
enquanto o thread atual continua a processar e escuta uma resposta do processo em segundo plano e, em
seguida, atualiza a interface do usuário quando os dados e o estado são retornados.
Cada um dos padrões será examinado em mais detalhes, pois seu uso prático é ilustrado nos estudos de caso. A
Wikipédia tem descrições mais detalhadas dos padrões MVVM, MVC, fachada, singleton, estratégia e provedor
(e de padrões de design geralmente).
Parte 3-Configurando uma solução de plataforma
cruzada do Xamarin
23/04/2020 • 7 minutes to read • Edit Online

Independentemente de quais plataformas estão sendo usadas, os projetos do Xamarin usam o mesmo formato
de arquivo de solução (o formato de arquivo . sln do Visual Studio). As soluções podem ser compartilhadas
entre ambientes de desenvolvimento, mesmo quando projetos individuais não podem ser carregados (como
um projeto do Windows no Visual Studio para Mac).
Ao criar um novo aplicativo de plataforma cruzada, a primeira etapa é criar uma solução em branco. Esta seção
explica o que acontece em seguida: Configurando os projetos para criar aplicativos móveis de plataforma
cruzada.

Compartilhando código
Consulte o documento Opções de compartilhamento de código para obter uma descrição detalhada de como
implementar o compartilhamento de código entre plataformas.
.NET Standard
Os projetos de .net Standard fornecem uma maneira fácil de compartilhar código entre plataformas, produzindo
assemblies que podem ser usados em todas as plataformas do Windows, Xamarin (Ios, Android, Mac) e Linux.
Essa é a maneira recomendada para compartilhar código para soluções Xamarin.
Outras opções
Historicamente, o Xamarin usava PCLs (bibliotecas de classes portáteis)e projetos compartilhados. Nenhum
deles é recomendado para novos projetos; e você deve considerar a migração de aplicativos existentes para usar
.NET Standard.

Populando a solução
Independentemente de qual método é usado para compartilhar código, a estrutura geral da solução deve
implementar uma arquitetura em camadas que incentiva o compartilhamento de código. A abordagem do
Xamarin é agrupar o código em dois tipos de projeto:
Projeto de núcleo (ou "compar tilhado") – escreva o código reutilizável em um único lugar, para ser
compartilhado entre diferentes plataformas. Use os princípios de encapsulamento para ocultar detalhes de
implementação sempre que possível.
Projetos de aplicativos específicos da plataforma – consuma o código reutilizável com o mínimo de
acoplamento possível. Os recursos específicos da plataforma são adicionados nesse nível, criados em
componentes expostos no projeto principal.
Projeto principal
Os projetos principais que compartilham o código devem ser .NET Standard e apenas os assemblies de
referência que estão disponíveis em todas as plataformas – por ex. os namespaces comuns do Common
Framework, como System , System.Core e System.Xml .
Os projetos principais devem implementar o máximo possível de funcionalidade que não seja de interface do
usuário, o que pode incluir as seguintes camadas:
Camada de dados – código que cuida do armazenamento de dados físicos, por exemplo. SQLite-net ou até
mesmo arquivos XML. As classes da camada de dados normalmente são usadas apenas pela camada de
acesso a dados.
Camada de acesso a dados – define uma API que dá suporte às operações de dados necessárias para a
funcionalidade do aplicativo, como métodos para acessar listas de dados, itens de dados individuais e
também criar, editar e excluí-los.
Camada de acesso ao ser viço – uma camada opcional para fornecer serviços de nuvem para o aplicativo.
Contém o código que acessa recursos de rede remota (serviços Web, downloads de imagens, etc.) e,
possivelmente, Caching dos resultados.
Camada de negócios – definição das classes de modelo e das classes de fachada ou gerente que expõem a
funcionalidade para os aplicativos específicos da plataforma.
Projetos de aplicativos específicos da plataforma
Os projetos específicos da plataforma devem referenciar os assemblies necessários para associar ao SDK de
cada plataforma (Xamarin. iOS, Xamarin. Android, Xamarin. Mac ou Windows), bem como ao projeto .NET
Standard.
Os projetos específicos da plataforma devem implementar:
Camada de aplicativo – funcionalidade específica da plataforma e vinculação/conversão entre os objetos
da camada de negócios e a interface do usuário.
Camada de interface do usuário – telas, controles de interface do usuário personalizados, apresentação
da lógica de validação.

Referências de projeto
As referências de projeto refletem as dependências de um projeto. Os projetos principais limitam suas
referências a assemblies comuns para que o código seja fácil de compartilhar. Os projetos de aplicativos
específicos da plataforma fazem referência ao projeto .NET Standard, além de quaisquer outros assemblies
específicos da plataforma de que precisam para aproveitar a plataforma de destino.
Exemplos específicos de como os projetos devem ser estruturados são fornecidos nos estudos de caso.

Adicionando arquivos
Compilar ação
É importante definir a ação de compilação correta para determinados tipos de arquivo. Esta lista mostra a ação
de Build para alguns tipos de arquivo comuns:
Todos C# os arquivos – ação de compilação: compilar
Imagens no Xamarin. iOS & Windows – ação de compilação: conteúdo
Arquivos XIB e stor yboard no Xamarin. Ios – ação de compilação: InterfaceDefinition
Imagens e layouts XML no Android – ação de compilação: AndroidResource
Arquivos XAML em projetos do Windows – ação de compilação: página
Arquivos XAML do Xamarin. Forms – ação de compilação: EmbeddedResource
Geralmente, o IDE detectará o tipo de arquivo e sugerirá a ação de compilação correta.
Diferenciação de maiúsculas e minúsculas
Finalmente, lembre-se de que algumas plataformas têm sistemas de arquivos que diferenciam maiúsculas de
minúsculas (por exemplo iOS e Android), portanto, use um padrão de nomenclatura de arquivo consistente e
certifique-se de que os nomes de arquivo usados no código correspondam exatamente ao sistema de arquivos.
Isso é especialmente importante para imagens e outros recursos que você referencia no código.
Parte 4 – Lidar com várias plataformas
23/04/2020 • 15 minutes to read • Edit Online

Lidando com recursos de & divergência de plataforma


A divergência não é apenas um problema de "plataforma cruzada"; os dispositivos na plataforma ' mesma ' têm
recursos diferentes (especialmente a ampla variedade de dispositivos Android que estão disponíveis). O mais
óbvio e básico é o tamanho da tela, mas outros atributos de dispositivo podem variar e exigir que um aplicativo
Verifique certos recursos e se comporte de forma diferente com base em sua presença (ou ausência).
Isso significa que todos os aplicativos precisam lidar com a degradação normal da funcionalidade, ou então
apresentar um conjunto de recursos do denominador mais baixo e incomum. A profunda integração do
Xamarin com os SDKs nativos de cada plataforma permite que os aplicativos tirem proveito da funcionalidade
específica da plataforma, de modo que faz sentido criar aplicativos para usar esses recursos.
Consulte a documentação de recursos da plataforma para obter uma visão geral de como as plataformas
diferem na funcionalidade.

Exemplos de divergência de plataforma


Elementos fundamentais que existem entre plataformas
Há algumas características de aplicativos móveis que são universais. Esses são conceitos de nível superior que
geralmente são verdadeiros de todos os dispositivos e, portanto, podem formar a base do design do seu
aplicativo:
Seleção de recursos por meio de guias ou menus
Listas de dados e rolagem
Exibições únicas de dados
Editando exibições únicas de dados
Navegando de volta
Ao projetar seu fluxo de tela de alto nível, você pode basear uma experiência de usuário comum nesses
conceitos.
Atributos específicos da plataforma
Além dos elementos básicos que existem em todas as plataformas, você precisará abordar as principais
diferenças de plataforma no seu design. Talvez seja necessário considerar (e escrever código especificamente
para manipular) essas diferenças:
Tamanhos de tela – algumas plataformas (como Ios e versões de Windows Phone anteriores) têm
tamanhos de tela padronizados que são relativamente simples de direcionar. Os dispositivos Android têm
uma grande variedade de dimensões de tela, que exigem mais esforço para dar suporte ao seu aplicativo.
Metáforas de navegação – diferem entre plataformas (por exemplo, botão "voltar" do hardware, controle
de interface do usuário do panorama) e em plataformas (Android 2 e 4, iPhone vs iPad).
Teclados – alguns dispositivos Android têm placas físicas, enquanto outras têm apenas um Keyboard de
software. O código que detecta quando um teclado suave está ocultando parte da tela precisa ser sensível a
essas diferenças.
Toque e gestos – o suporte do sistema operacional para reconhecimento de gestos varia, especialmente
em versões mais antigas de cada sistema operacional. As versões anteriores do Android têm suporte muito
limitado para operações de toque, o que significa que o suporte a dispositivos mais antigos pode exigir
código separado
Notificações por push – há diferentes recursos/implementações em cada plataforma (por exemplo, Blocos
dinâmicos no Windows).
Recursos específicos do dispositivo
Determine quais os recursos mínimos necessários para o aplicativo devem ser; ou quando decidir quais
recursos adicionais aproveitar em cada plataforma. O código será necessário para detectar recursos e desabilitar
a funcionalidade ou as alternativas de oferta (por exemplo, uma alternativa para localização geográfica poderia
ser permitir que o usuário digite um local ou escolha em um mapa):
Câmera – a funcionalidade difere em dispositivos: alguns dispositivos não têm uma câmera, outros têm
câmeras frente e traseira. Algumas câmeras são capazes de gravar vídeo.
Mapas de & de localização geográfica – suporte para GPS ou local Wi-Fi não está presente em todos os
dispositivos. Os aplicativos também precisam atender aos diferentes níveis de precisão com suporte em cada
método.
Acelerômetro, giroscópio e bússola – esses recursos geralmente são encontrados em apenas uma
seleção de dispositivos em cada plataforma, de modo que os aplicativos quase sempre precisam fornecer um
fallback quando o hardware não tem suporte.
Twitter e Facebook – somente "interno" em IOS5 e iOS6, respectivamente. Em versões anteriores e outras
plataformas, você precisará fornecer suas próprias funções e interface de autenticação diretamente com a
API de cada serviço.
NFC (comunicação a cur ta distância) – somente em (alguns) telefones Android (no momento da
gravação).

Lidando com a divergência de plataforma


Há duas abordagens diferentes para dar suporte a várias plataformas da mesma base de código, cada uma com
seu próprio conjunto de benefícios e desvantagens.
Abstração de plataforma – padrão de fachada de negócios, fornece um acesso unificado entre
plataformas e abstrai as implementações de plataforma específicas em uma única API unificada.
Implementação divergente – invocação de recursos específicos da plataforma por meio de
implementações divergentes por meio de ferramentas arquitetônicas, como interfaces e herança ou
compilação condicional.

Abstração de plataforma
Abstração de classe
Usando interfaces ou classes base definidas no código compartilhado e implementadas ou estendidas em
projetos específicos da plataforma. Escrever e estender código compartilhado com abstrações de classe é
especialmente adequado para bibliotecas de classes portáteis porque eles têm um subconjunto limitado da
estrutura disponível para eles e não podem conter diretivas de compilador para dar suporte a ramificações de
código específicas da plataforma.
Interfaces
O uso de interfaces permite que você implemente classes específicas da plataforma que ainda podem ser
passadas para suas bibliotecas compartilhadas para tirar proveito do código comum.
A interface é definida no código compartilhado e passada para a biblioteca compartilhada como um parâmetro
ou propriedade.
Os aplicativos específicos da plataforma podem então implementar a interface e ainda aproveitar o código
compartilhado para "Process".
Vantagens
A implementação pode conter código específico da plataforma e até mesmo referenciar bibliotecas externas
específicas da plataforma.
Desvantagens
Ter que criar e passar implementações no código compartilhado. Se a interface for usada em profundidade no
código compartilhado, ela acabará sendo passada por meio de vários parâmetros de método ou, de outra
forma, por Push por meio da cadeia de chamadas. Se o código compartilhado usar muitas interfaces diferentes,
todos eles deverão ser criados e definidos no código compartilhado em algum lugar.
Herança
O código compartilhado pode implementar classes abstratas ou virtuais que poderiam ser estendidas em um
ou mais projetos específicos da plataforma. Isso é semelhante ao uso de interfaces, mas com algum
comportamento já implementado. Há diferentes pontos de vista sobre se as interfaces ou herança são uma
opção de design melhor: C# em particular porque só permite a herança única que pode determinar a maneira
como suas APIs podem ser projetadas no futuro. Use a herança com cuidado.
As vantagens e desvantagens das interfaces se aplicam igualmente à herança, com a vantagem adicional de que
a classe base pode conter algum código de implementação (talvez uma implementação independente de
plataforma inteira que possa ser opcionalmente estendida).

Xamarin.Forms
Consulte a documentação do Xamarin. Forms .
Outras bibliotecas de plataforma cruzada
Essas bibliotecas também oferecem funcionalidade de plataforma cruzada C# para desenvolvedores:
Xamarin. Essentials – APIs de plataforma cruzada para recursos comuns.
SkiaSharp – gráficos 2D entre plataformas.

{1>Compilação condicional<1}
Há algumas situações em que seu código compartilhado ainda precisará trabalhar de forma diferente em cada
plataforma, possivelmente acessando classes ou recursos que se comportam de forma diferente. A compilação
condicional funciona melhor com projetos de ativos compartilhados, em que o mesmo arquivo de origem está
sendo referenciado em vários projetos que têm diferentes símbolos definidos.
Os projetos do Xamarin sempre definem __MOBILE__ que é verdadeiro para projetos de aplicativos iOS e
Android (Observe os dois pontos de pontuação dupla pré e pós-correção desses símbolos).

#if __MOBILE__
// Xamarin iOS or Android-specific code
#endif

iOS
O Xamarin. iOS define __IOS__ que você pode usar para detectar dispositivos iOS.

#if __IOS__
// iOS-specific code
#endif

Também há símbolos específicos de inspeção e de TV:


#if __TVOS__
// tv-specific stuff
#endif

#if __WATCHOS__
// watch-specific stuff
#endif

Android
O código que só deve ser compilado em aplicativos Xamarin. Android pode usar o seguinte

#if __ANDROID__
// Android-specific code
#endif

Cada versão de API também define uma nova diretiva de compilador, portanto, um código como esse permitirá
que você adicione recursos se as APIs mais novas forem destinadas. Cada nível de API inclui todos os símbolos
de nível "inferior". Esse recurso não é realmente útil para dar suporte a várias plataformas; Normalmente, o
símbolo de __ANDROID__ será suficiente.

#if __ANDROID_11__
// code that should only run on Android 3.0 Honeycomb or newer
#endif

Mac
O Xamarin. Mac define __MACOS__ que você pode usar para compilar apenas para macOS:

#if __MACOS__
// macOS-specific code
#endif

UWP (Plataforma Universal do Windows )


Use WINDOWS_UWP . Não há nenhum sublinhado ao redor da cadeia de caracteres como os símbolos da
plataforma Xamarin.

#if WINDOWS_UWP
// UWP-specific code
#endif

Usando a compilação condicional


Um exemplo simples de estudo de caso de compilação condicional é definir o local do arquivo do banco de
dados SQLite. As três plataformas têm requisitos um pouco diferentes para especificar o local do arquivo:
Ios – a Apple prefere que os dados de não-usuário sejam colocados em um local específico (o diretório de
biblioteca), mas não há nenhuma constante de sistema para esse diretório. O código específico da
plataforma é necessário para criar o caminho correto.
Android – o caminho do sistema retornado por Environment.SpecialFolder.Personal é um local aceitável
para armazenar o arquivo de banco de dados.
Windows Phone – o mecanismo de armazenamento isolado não permite que um caminho completo seja
especificado, apenas um caminho relativo e um nome de arquivo.
Plataforma universal do Windows – usa APIs de Windows.Storage .
O código a seguir usa a compilação condicional para garantir que a DatabaseFilePath esteja correta para cada
plataforma:
public static string DatabaseFilePath
{
get
{
var filename = "TodoDatabase.db3";
#if SILVERLIGHT
// Windows Phone 8
var path = filename;
#else

#if __ANDROID__
string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
#else
#if __IOS__
// we need to put in /Library/ on iOS5.1 to meet Apple's iCloud terms
// (they don't want non-user-generated data in Documents)
string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents
folder
string libraryPath = Path.Combine (documentsPath, "..", "Library");
#else
// UWP
string libraryPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
#endif
#endif
var path = Path.Combine(libraryPath, filename);
#endif
return path;
}
}

O resultado é uma classe que pode ser criada e usada em todas as plataformas, colocando o arquivo de banco
de dados SQLite em um local diferente em cada plataforma.
Parte 5 – Estratégias práticas de compartilhamento
de código
02/11/2020 • 26 minutes to read • Edit Online

Esta seção fornece exemplos de como compartilhar código para cenários de aplicativos comuns.

Camada de dados
A camada de dados consiste em um mecanismo de armazenamento e métodos para ler e gravar informações.
Para obter desempenho, flexibilidade e compatibilidade entre plataformas, o mecanismo de banco de dados
SQLite é recomendado para aplicativos de plataforma cruzada do Xamarin. Ele é executado em uma ampla
variedade de plataformas, incluindo Windows, Android, iOS e Mac.
SQLite
O SQLite é uma implementação de banco de dados de código aberto. A origem e a documentação podem ser
encontradas em SQLite.org. O suporte do SQLite está disponível em cada plataforma móvel:
Ios – interno ao sistema operacional.
Android – integrado ao sistema operacional desde o Android 2,2 (nível de API 10).
Windows – consulte a extensão do SQLite para plataforma universal do Windows.
Mesmo com o mecanismo de banco de dados disponível em todas as plataformas, os métodos nativos para
acessar o banco de dados são diferentes. O iOS e o Android oferecem APIs internas para acessar o SQLite que
poderia ser usado no Xamarin. iOS ou Xamarin. Android, no entanto, usar os métodos nativos do SDK não
oferece capacidade de compartilhar código (além de talvez as consultas SQL propriamente ditas, supondo que
elas sejam armazenadas como cadeias de caracteres). Para obter detalhes sobre a pesquisa de funcionalidade de
banco de dados nativa CoreData na classe do Ios ou Android SQLiteOpenHelper ; como essas opções não são de
plataforma cruzada, elas estão além do escopo deste documento.
ADO.NET
Suporte para Xamarin. iOS e Xamarin. Android System.Data e Mono.Data.Sqlite (consulte a documentação do
xamarin. Ios para obter mais informações). O uso desses namespaces permite que você escreva o código
ADO.NET que funciona em ambas as plataformas. Edite as referências do projeto para incluir System.Data.dll e
Mono.Data.Sqlite.dll e adicione-as usando instruções ao seu código:

using System.Data;
using Mono.Data.Sqlite;

Em seguida, o seguinte código de exemplo funcionará:


string dbPath = Path.Combine (
Environment.GetFolderPath (Environment.SpecialFolder.Personal),
"items.db3");
bool exists = File.Exists (dbPath);
if (!exists)
SqliteConnection.CreateFile (dbPath);
var connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
if (!exists) {
// This is the first time the app has run and/or that we need the DB.
// Copy a "template" DB from your assets, or programmatically create one like this:
var commands = new[]{
"CREATE TABLE [Items] (Key ntext, Value ntext);",
"INSERT INTO [Items] ([Key], [Value]) VALUES ('sample', 'text')"
};
foreach (var command in commands) {
using (var c = connection.CreateCommand ()) {
c.CommandText = command;
c.ExecuteNonQuery ();
}
}
}
// use `connection`... here, we'll just append the contents to a TextView
using (var contents = connection.CreateCommand ()) {
contents.CommandText = "SELECT [Key], [Value] from [Items]";
var r = contents.ExecuteReader ();
while (r.Read ())
Console.Write("\n\tKey={0}; Value={1}",
r ["Key"].ToString (),
r ["Value"].ToString ());
}
connection.Close ();

As implementações do mundo real de ADO.NET obviamente seriam divididas em diferentes métodos e classes
(Este exemplo é apenas para fins de demonstração).
SQLite -NET – ORM de plataforma cruzada
Um ORM (ou um mapeador relacional de objeto) tenta simplificar o armazenamento de dados modelados em
classes. Em vez de escrever manualmente consultas SQL que criam tabelas ou SELECIONAm, INSEREM e
EXCLUem dados que são extraídos manualmente de campos de classe e propriedades, um ORM adiciona uma
camada de código que faz isso para você. Usando a reflexão para examinar a estrutura de suas classes, um ORM
pode criar automaticamente tabelas e colunas que correspondam a uma classe e gerar consultas para ler e
gravar os dados. Isso permite que o código do aplicativo simplesmente envie e recupere instâncias de objeto
para o ORM, o que cuida de todas as operações do SQL nos bastidores.
O SQLite-NET atua como um ORM simples que permitirá que você salve e recupere suas classes no SQLite. Ele
oculta a complexidade do acesso do SQLite de plataforma cruzada com uma combinação de diretivas de
compilador e outros truques.
Recursos do SQLite-NET:
As tabelas são definidas adicionando atributos a classes de modelo.
Uma instância de banco de dados é representada por uma subclasse de SQLiteConnection , a classe principal
na biblioteca SQLite-net.
Os dados podem ser inseridos, consultados e excluídos usando objetos. Nenhuma instrução SQL é
necessária (embora seja possível escrever instruções SQL, se necessário).
Consultas básicas do LINQ podem ser executadas nas coleções retornadas pelo SQLite-NET.
O código-fonte e a documentação do SQLite-NET estão disponíveis em SQLite-net no GitHub e foram
implementados em ambos os estudos de caso. Um exemplo simples de código SQLite-NET (do estudo de caso
do profissional da tarefa ) é mostrado abaixo.
Primeiro, a TodoItem classe usa atributos para definir um campo para ser uma chave primária de banco de
dados:

public class TodoItem : IBusinessEntity


{
public TodoItem () {}
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public bool Done { get; set; }
}

Isso permite que uma TodoItem tabela seja criada com a seguinte linha de código (e nenhuma instrução SQL)
em uma SQLiteConnection instância:

CreateTable<TodoItem> ();

Os dados na tabela também podem ser manipulados com outros métodos no SQLiteConnection (novamente,
sem a necessidade de instruções SQL):

Insert (TodoItem); // 'task' is an instance with data populated in its properties


Update (TodoItem); // Primary Key field must be populated for Update to work
Table<TodoItem>.ToList(); // returns all rows in a collection

Consulte o código-fonte do estudo de caso para obter exemplos completos.

Acesso a arquivos
O acesso ao arquivo é uma parte importante de qualquer aplicativo. Exemplos comuns de arquivos que podem
ser parte de um aplicativo incluem:
Arquivos de banco de dados SQLite.
Dados gerados pelo usuário (texto, imagens, som, vídeo).
Dados baixados para cache (imagens, arquivos HTML ou PDF).
Acesso direto ao System.IO
O Xamarin. iOS e o Xamarin. Android permitem o acesso ao sistema de arquivos usando classes no System.IO
namespace.
Cada plataforma tem restrições de acesso diferentes que devem ser levadas em consideração:
os aplicativos iOS são executados em uma área restrita com acesso muito restrito ao sistema de arquivos. A
Apple dita ainda mais como você deve usar o sistema de arquivos especificando determinados locais que são
submetidos a backup (e outros que não são). Consulte o guia trabalhando com o sistema de arquivos no
Xamarin. Ios para obter mais detalhes.
O Android também restringe o acesso a determinados diretórios relacionados ao aplicativo, mas também
oferece suporte à mídia externa (por exemplo, Cartões SD) e acesso a dados compartilhados.
O Windows Phone 8 (Silverlight) não permite acesso direto a arquivos – os arquivos só podem ser
manipulados usando IsolatedStorage .
Os projetos UWP Windows 8.1 WinRT e Windows 10 oferecem apenas operações de arquivo assíncronas por
meio Windows.Storage de APIs, que são diferentes das outras plataformas.
Exemplo para iOS e Android
Um exemplo trivial que grava e lê um arquivo de texto é mostrado abaixo. Environment.GetFolderPath O uso
permite que o mesmo código seja executado no Ios e no Android, que retornam um diretório válido com base
em suas convenções de sistema de arquivos.

string filePath = Path.Combine (


Environment.GetFolderPath (Environment.SpecialFolder.Personal),
"MyFile.txt");
System.IO.File.WriteAllText (filePath, "Contents of text file");
Console.WriteLine (System.IO.File.ReadAllText (filePath));

Consulte o Xamarin. iOS trabalhando com o documento do sistema de arquivos para obter mais informações
sobre a funcionalidade de sistema de arquivos específica do Ios. Ao escrever código de acesso a arquivos entre
plataformas, lembre-se de que alguns sistemas de arquivos diferenciam maiúsculas de minúsculas e têm
separadores de diretório diferentes. É recomendável sempre usar o mesmo uso de maiúsculas e minúsculas
para nomes de arquivos e o Path.Combine() método ao construir caminhos de arquivo ou diretório.
Windows. Storage para Windows 8 e Windows 10
O livro criando aplicativos móveis com Xamarin. Forms , capítulo 20. Async e e/s de arquivo incluem amostras
para Windows 8.1 e Windows 10.
Usar um é DependencyService possível ler e arquivos de arquivo nessas plataformas usando as APIs com
suporte:

StorageFolder localFolder = ApplicationData.Current.LocalFolder;


IStorageFile storageFile = await localFolder.CreateFileAsync("MyFile.txt",
CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(storageFile, "Contents of text file");

Consulte o capítulo de livros para obter mais detalhes.


Armazenamento isolado no Windows Phone 7 & 8 (Silverlight)
O armazenamento isolado é uma API comum para salvar e carregar arquivos em todas as plataformas de
Windows Phone iOS, Android e mais antigas.
É o mecanismo padrão de acesso a arquivos no Windows Phone (Silverlight) que foi implementado em
Xamarin. iOS e Xamarin. Android para permitir que o código de acesso a arquivos comum seja gravado. A
System.IO.IsolatedStorage classe pode ser referenciada em todas as três plataformas em um projeto
compartilhado.
Consulte visão geral do armazenamento isolado para obter Windows Phone para obter mais informações.
As APIs de armazenamento isolado não estão disponíveis em bibliotecas de classes portáteis. Uma alternativa
para o PCL é o NuGet do PCLStorage
Acesso a arquivos entre plataformas no PCLs
Também há um NuGet- PCLStorage compatível com PCL – que orienta o acesso a arquivos entre plataformas
para plataformas com suporte para Xamarin e as APIs do Windows mais recentes.

Operações de rede
A maioria dos aplicativos móveis terá um componente de rede, por exemplo:
Baixando imagens, vídeo e áudio (por exemplo, miniaturas, fotos, música).
Baixando documentos (por exemplo, HTML, PDF).
Carregando dados do usuário (como fotos ou texto).
Acessando serviços Web ou APIs de terceiros (incluindo SOAP, XML ou JSON).
O .NET Framework fornece algumas classes diferentes para acessar recursos de rede: HttpClient , WebClient e
HttpWebRequest .

HttpClient
A HttpClient classe no System.Net.Http namespace está disponível no Xamarin. Ios, Xamarin. Android e na
maioria das plataformas do Windows. Há um NuGet de biblioteca de cliente http da Microsoft que pode ser
usado para colocar essa API em bibliotecas de classes portáteis (e Windows Phone 8 Silverlight).

var client = new HttpClient();


var request = new HttpRequestMessage(HttpMethod.Get, "https://xamarin.com");
var response = await myClient.SendAsync(request);

Clientes web
A WebClient classe fornece uma API simples para recuperar dados remotos de servidores remotos.
Plataforma Universal do Windows operações devem ser assíncronas, mesmo que o Xamarin. Ios e o Xamarin.
Android ofereçam suporte a operações síncronas (o que pode ser feito em threads em segundo plano).
O código para uma operação simples de assíncrona WebClient é:

var webClient = new WebClient ();


webClient.DownloadStringCompleted += (sender, e) =>
{
var resultString = e.Result;
// do something with downloaded string, do UI interaction on main thread
};
webClient.Encoding = System.Text.Encoding.UTF8;
webClient.DownloadStringAsync (new Uri ("http://some-server.com/file.xml"));

WebClient também tem DownloadFileCompleted e DownloadFileAsync para recuperar dados binários.


HttpWebRequest
HttpWebRequest oferece mais personalização do que WebClient e como resultado requer mais código a ser
usado.
O código para uma operação síncrona simples HttpWebRequest é:

var request = HttpWebRequest.Create(@"http://some-server.com/file.xml ");


request.ContentType = "text/xml";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
// do something with downloaded string, do UI interaction on main thread
}
}

Há um exemplo em nossa documentação de serviços Web.


Acessibilidade
Os dispositivos móveis operam em uma variedade de condições de rede de conexões rápidas de Wi-Fi ou 4G
para áreas de recepção deficiente e links de dados de borda lentos. Por isso, é uma boa prática detectar se a rede
está disponível e, em caso afirmativo, que tipo de rede está disponível, antes de tentar se conectar a servidores
remotos.
As ações que um aplicativo móvel pode tomar nessas situações incluem:
Se a rede não estiver disponível, recomende o usuário. Se eles o desabilitaram manualmente (por exemplo,
No modo avião ou desligando o Wi-Fi), eles podem resolver o problema.
Se a conexão for 3G, os aplicativos podem se comportar de forma diferente (por exemplo, a Apple não
permite que aplicativos maiores do que 20 MB sejam baixados por 3G). Os aplicativos podem usar essas
informações para avisar o usuário sobre tempos de download excessivos ao recuperar arquivos grandes.
Mesmo que a rede esteja disponível, é uma boa prática verificar a conectividade com o servidor de destino
antes de iniciar outras solicitações. Isso impedirá que as operações de rede do aplicativo atinjam o tempo
limite repetidamente e também permitirá que uma mensagem de erro mais informativa seja exibida ao
usuário.

WebServices
Consulte nossa documentação sobre como trabalhar com serviços Web, que aborda o acesso a pontos de
extremidade REST, SOAP e WCF usando o Xamarin. Ios. É possível criar solicitações de serviço da Web
manualmente e analisar as respostas, no entanto, há bibliotecas disponíveis para tornar isso muito mais
simples, incluindo o Azure, o RestSharp e o perstack. Até mesmo as operações básicas do WCF podem ser
acessadas em aplicativos Xamarin.
Azure
O Microsoft Azure é uma plataforma de nuvem que fornece uma ampla variedade de serviços para aplicativos
móveis, incluindo armazenamento de dados e sincronização e notificações por push.
Visite Azure.Microsoft.com para testá-lo gratuitamente.
RestSharp
O RestSharp é uma biblioteca .NET que pode ser incluída em aplicativos móveis para fornecer um cliente REST
que simplifica o acesso aos serviços da Web. Ele ajuda a fornecer uma API simples para solicitar dados e
analisar a resposta REST. RestSharp pode ser útil
O site do RestSharp contém documentação sobre como implementar um cliente REST usando o RestSharp. O
RestSharp fornece exemplos de Xamarin. iOS e Xamarin. Android no GitHub.
Também há um trecho de código do Xamarin. iOS em nossa documentação de serviços Web.
Perstack
Ao contrário de RestSharp, o perstack é uma solução do lado do servidor para hospedar um serviço Web, bem
como uma biblioteca de cliente que pode ser implementada em aplicativos móveis para acessar esses serviços.
O site do perstack explica a finalidade do projeto e links para documentos e exemplos de código. Os exemplos
incluem uma implementação completa do lado do servidor de um serviço Web, bem como vários aplicativos do
lado do cliente que podem acessá-lo.
WCF
As ferramentas do Xamarin podem ajudá-lo a consumir alguns serviços de Windows Communication
Foundation (WCF). Em geral, o Xamarin dá suporte ao mesmo subconjunto do WCF do lado do cliente que é
fornecido com o tempo de execução do Silverlight. Isso inclui as implementações mais comuns de codificação e
protocolo do WCF: mensagens SOAP codificadas por texto sobre o protocolo de transporte HTTP usando o
BasicHttpBinding .

Devido ao tamanho e à complexidade da estrutura do WCF, pode haver implementações de serviço atuais e
futuras que ficarão fora do escopo com suporte do domínio de subconjunto do cliente do Xamarin. Além disso,
o suporte do WCF requer o uso de ferramentas disponíveis somente em um ambiente do Windows para gerar o
proxy.

Threading
A capacidade de resposta do aplicativo é importante para aplicativos móveis – os usuários esperam que os
aplicativos sejam carregados e executados rapidamente. Uma tela "congelada" que para de aceitar a entrada do
usuário aparecerá para indicar que o aplicativo falhou, portanto, é importante não vincular o thread da interface
do usuário com chamadas de bloqueio de execução longa, como solicitações de rede ou operações locais lentas
(como descompactar um arquivo). Em particular, o processo de inicialização não deve conter tarefas de longa
execução – todas as plataformas móveis eliminarão um aplicativo que leva muito tempo para carregar.
Isso significa que a sua interface do usuário deve implementar uma interface "do indicador de progresso" ou de
outra forma "utilizável" que seja rápida de exibir e tarefas assíncronas para executar operações em segundo
plano. A execução de tarefas em segundo plano requer o uso de threads, o que significa que as tarefas em
segundo plano precisam de uma maneira de se comunicar de volta com o thread principal para indicar o
progresso ou quando eles foram concluídos.
Biblioteca de tarefas paralelas
As tarefas criadas com a biblioteca de tarefas paralelas podem ser executadas de forma assíncrona e retornadas
em seu thread de chamada, tornando-as muito úteis para disparar operações de longa execução sem bloquear a
interface do usuário.
Uma operação de tarefa paralela simples pode ser parecida com esta:

using System.Threading.Tasks;
void MainThreadMethod ()
{
Task.Factory.StartNew (() => wc.DownloadString ("http://...")).ContinueWith (
t => label.Text = t.Result, TaskScheduler.FromCurrentSynchronizationContext()
);
}

A chave é TaskScheduler.FromCurrentSynchronizationContext() que reutilizará o SynchronizationContext. Current


do thread que chama o método (aqui o thread principal que está em execução MainThreadMethod ) como uma
maneira de realizar o marshaling de chamadas para esse thread. Isso significa que se o método for chamado no
thread da interface do usuário, ele executará a ContinueWith operação de volta no thread da interface do
usuário.
Se o código estiver iniciando tarefas de outros threads, use o padrão a seguir para criar uma referência ao
thread da interface do usuário e a tarefa ainda poderá retornar a ela:

static Context uiContext = TaskScheduler.FromCurrentSynchronizationContext();

Invocando no thread de interface do usuário


Para o código que não utiliza a biblioteca de tarefas paralelas, cada plataforma tem sua própria sintaxe para
realizar o marshaling de operações de volta para o thread da interface do usuário:
Ios – owner.BeginInvokeOnMainThread(new NSAction(action))
Android – owner.RunOnUiThread(action)
Xamarin. Forms – Device.BeginInvokeOnMainThread(action)
Windows – Deployment.Current.Dispatcher.BeginInvoke(action)

A sintaxe do iOS e do Android requer que uma classe ' Context ' esteja disponível, o que significa que o código
precisa passar esse objeto para quaisquer métodos que exijam um retorno de chamada no thread da interface
do usuário.
Para fazer chamadas de thread de interface do usuário em código compartilhado, siga o exemplo de
IDispatchOnUIThread (cortesia de @follesoe ). Declare e programe para uma IDispatchOnUIThread interface no
código compartilhado e, em seguida, implemente as classes específicas da plataforma, conforme mostrado aqui:

// program to the interface in shared code


public interface IDispatchOnUIThread {
void Invoke (Action action);
}
// iOS
public class DispatchAdapter : IDispatchOnUIThread {
public readonly NSObject owner;
public DispatchAdapter (NSObject owner) {
this.owner = owner;
}
public void Invoke (Action action) {
owner.BeginInvokeOnMainThread(new NSAction(action));
}
}
// Android
public class DispatchAdapter : IDispatchOnUIThread {
public readonly Activity owner;
public DispatchAdapter (Activity owner) {
this.owner = owner;
}
public void Invoke (Action action) {
owner.RunOnUiThread(action);
}
}
// WP7
public class DispatchAdapter : IDispatchOnUIThread {
public void Invoke (Action action) {
Deployment.Current.Dispatcher.BeginInvoke(action);
}
}

Os desenvolvedores do Xamarin. Forms devem usar Device.BeginInvokeOnMainThread em código comum


(projetos compartilhados ou PCL).

Recursos e degradação da plataforma e do dispositivo


Mais exemplos específicos de como lidar com recursos diferentes são fornecidos na documentação de recursos
da plataforma. Ele lida com a detecção de diferentes recursos e como degradar um aplicativo de forma tranqüila
para fornecer uma boa experiência do usuário, mesmo quando o aplicativo não puder operar com todo o
potencial.
Parte 6 – Teste e aprovações da app store
02/11/2020 • 25 minutes to read • Edit Online

Testando
Muitos aplicativos (até mesmo aplicativos Android, em algumas lojas) terão que passar um processo de
aprovação antes de serem publicados; Portanto, o teste é essencial para garantir que seu aplicativo chegue ao
mercado (o que sozinha é bem sucedido com seus clientes). O teste pode assumir muitas formas, desde testes
de unidade de nível de desenvolvedor até o gerenciamento de testes beta em uma ampla variedade de
hardware.
Testar em todas as plataformas
Há pequenas diferenças entre o que o .NET dá suporte em dispositivos Windows Phone, Tablet e desktop, bem
como limitações no iOS que impedem que o código dinâmico seja gerado de forma dinâmica. Planeje o teste do
código em várias plataformas enquanto você o desenvolve, ou agende o tempo para Refatorar e atualize a parte
do modelo do seu aplicativo no final do projeto.
É sempre uma boa prática usar o simulador/emulador para testar várias versões do sistema operacional e
também recursos/configurações de dispositivo diferentes.
Você também deve testar o máximo possível de dispositivos de hardware físicos diferentes.
Dispositivos na nuvem
O celular e o ecossistema do Tablet estão crescendo o tempo todo, tornando impossível testar o número cada
vez maior de dispositivos disponíveis. Para resolver esse problema, vários serviços oferecem a capacidade de
controlar remotamente vários dispositivos diferentes para que os aplicativos possam ser instalados e testados
sem a necessidade de investir diretamente em muitos hardwares.
O App Center Test oferece uma maneira fácil de testar aplicativos iOS e Android em centenas de dispositivos
diferentes. Para obter mais informações, consulte preparando aplicativos xamarin. Android e preparando
aplicativos xamarin. Ios.
Gerenciamento de testes
Ao testar aplicativos dentro de sua organização ou gerenciar um programa beta com usuários externos, há dois
desafios:
Distribuição – gerenciar o processo de provisionamento (especialmente para dispositivos IOS) e obter
versões atualizadas do software para os testadores.
Comentários – coleta de informações sobre o uso do aplicativo e informações detalhadas sobre quaisquer
erros que possam ocorrer.
Há vários serviços que ajudam a resolver esses problemas, fornecendo a infraestrutura incorporada ao seu
aplicativo para coletar e relatar o uso e os erros, além de simplificar o processo de provisionamento para ajudar
a inscrever e gerenciar testadores e seus dispositivos.
O Visual Studio app Center oferece uma solução para esses problemas, fornecendo distribuição de versão de
teste, relatório de falhas e informações sofisticadas de uso do aplicativo.
Automação de teste
O Xamarin UITest pode ser usado para criar scripts de teste da interface do usuário automatizados que podem
ser executados localmente ou carregados no teste de App Center.
Teste de unidade
Touch.Unit
O Xamarin. iOS inclui uma estrutura de teste de unidade chamada Touch. Unit que segue os testes de escrita de
estilo JUnit/NUnit.
Consulte nosso teste de unidade com a documentação do Xamarin. Ios para obter detalhes sobre como escrever
testes e executar Touch. Unit.
Andr. Unit
Há um equivalente de código-fonte aberto de Touch. Unit para Android chamado Andr. Unit. Você pode baixá-lo
do GitHub e ler sobre o @spouliot blog daferramenta no.

Aprovações da loja de aplicativos


A Apple e a Microsoft operam a única loja em suas plataformas: a loja de aplicativos e o Marketplace,
respectivamente. Ambos bloqueiam seus dispositivos e implementam um processo de revisão de aplicativo
rigoroso para controlar a qualidade dos aplicativos disponíveis para download. A natureza aberta do Android
significa que há várias opções de armazenamento que vão desde a reprodução do Google, que é amplamente
disponível e não tem nenhum processo de análise, até o AppStore da Amazon para esforços específicos de
hardware e Android, como aplicativos Samsung que têm distribuição mais limitada e implementam um
processo de aprovação.
Esperar que um aplicativo seja revisado pode ser muito estressante-as pressões de negócios geralmente
significam que os aplicativos são enviados para aprovação com muito pouca margem de erros antes de uma
data de lançamento "direcionada". O próprio processo pode levar até duas semanas e não é necessariamente
transparente: há comentários limitados sobre o progresso do seu aplicativo até que ele seja finalmente rejeitado
ou aprovado. A rejeição pode significar falta de uma janela de marketing de oportunidade, especialmente se
ocorrer mais de uma vez e semanas passarem entre a data de início original e quando o aplicativo for
finalmente aprovado.
Estar preparado
A primeira peça de aviso: planeje o início do aplicativo com antecedência e faça concessões para uma possível
rejeição e reenvio. Cada loja exige que você crie uma conta antes de enviar seu aplicativo-faça isso o mais cedo
possível. Embora a inscrição de Google Play leve apenas alguns minutos se seus aplicativos forem gratuitos, o
processo ficará muito mais envolvido se você estiver vendendo-los e precisar fornecer informações bancárias e
fiscais. Os processos da Apple e da Microsoft são muito mais envolvidos do que o Google, pode levar uma
semana ou mais para que sua conta seja aprovada, portanto, dessa vez em seus planos de lançamento.
Depois que sua conta tiver sido aprovada, você estará pronto para enviar um aplicativo. O processo real para
enviar aplicativos é abordado na seguinte documentação:
Publicação na iOS App Store da Apple
Preparando um aplicativo para Google Play
Os desenvolvedores do Windows devem visitar o centro de desenvolvimento do Windows para ler sobre
como enviar seus aplicativos.
O restante desta seção aborda as coisas que você deve levar em consideração para garantir que seu aplicativo
seja aprovado sem nenhum quaisquer sustos.
Qualidade
Parece óbvio, mas os aplicativos muitas vezes são rejeitados porque não atendem a um determinado nível de
qualidade: afinal, esse é o motivo pelo qual os armazenamentos organizados têm um processo de aprovação
em primeiro lugar!
Falhas são um motivo comum para rejeição. Se for muito fácil fazer o aplicativo falhar, é garantido que ele seja
rejeitado. A maioria dos desenvolvedores não enviam seus aplicativos com a expectativa de que eles falham,
ainda assim, geralmente fazem. Teste seu aplicativo cuidadosamente antes de enviá-lo, concentrando-se não
apenas em garantir que tudo funcione, mas também que você lida com cenários de erro de dispositivos móveis
comuns, como problemas de rede e restrições de recursos, como memória ou espaço de armazenamento. Use o
simulador e os dispositivos físicos para testar, independentemente de como o código seja executado em um
simulador, apenas um dispositivo pode demonstrar o desempenho real de um aplicativo. Use tantos dispositivos
diferentes quantos você encontrar e inscreva uma equipe de testadores beta se você puder-os serviços de
terceiros podem ajudar a gerenciar a distribuição beta e os comentários.
Todos os sistemas operacionais móveis eliminarão um aplicativo que não inicia com rapidez suficiente. O
período de tempo permitido varia, mas, em geral, os aplicativos devem ser responsivos em alguns segundos e
usar tarefas em segundo plano para realizar qualquer trabalho que demore mais. Os aplicativos que levam
muito tempo para carregar ou não estão respondendo o suficiente no uso regular serão rejeitados. Sempre
forneça comentários do usuário quando algo estiver acontecendo em segundo plano ou o aplicativo parece ter
falhado e, mais uma vez, ser rejeitado.
Verifique seus casos de borda
Uma interceptação comum para os desenvolvedores está falhando em lidar com casos de borda, especialmente
aqueles que exigem a reconfiguração de seu simulador ou dispositivo para serem testados corretamente. Pode
ser fácil esquecer que nem todos os clientes vão "permitir" que seu aplicativo acesse sua localização porque,
depois que o desenvolvedor aceitou a solicitação uma vez, ele nunca será solicitado novamente. As permissões
e o uso de rede são especificamente focados durante o processo de aprovação, o que significa que uma
pequena supervisão nessas áreas pode resultar em rejeição.
A lista a seguir é um bom ponto de partida para verificar os casos de borda que podem ter sido perdidos:
Os clientes podem ' negar ' acesso aos ser viços – especialmente no Ios, o acesso a dados como
informações de localização geográfica só será fornecido se o usuário conceder permissão para seu aplicativo.
Os testadores de aplicativos devem reinstalar frequentemente o aplicativo em seu estado inicial e não
permitir nenhuma solicitação de permissão para garantir que o aplicativo se comporta adequadamente.
Ative e desative a permissão para verificar o comportamento correto à medida que os clientes mudarem de
ideia.
Os clientes estão em qualquer lugar – não presuma que um aplicativo será usado apenas na cidade ou
no país em que foi desenvolvido! O código que funciona com coordenadas de GPS, valores de data e hora e
moedas pode ser afetado pelo local e pelas configurações de localidade do cliente. Todas as plataformas
oferecem um simulador que permite especificar locais e localidades diferentes – usá-lo para testar locais em
outros hemisférios e com culturas que formatam datas e moedas de maneira diferente. Os valores de
latitude e longitude podem ser positivos ou negativos, o separador decimal pode ser um ponto ou uma
vírgula, e as datas podem ser formatadas de inúmeras formas.
Conexões de rede lentas – os desenvolvedores de aplicativos geralmente trabalham em um ' mundo ideal
' de conectividade de rede rápida e sempre em funcionamento, o que obviamente não é o caso no mundo
real. O teste com conectividade de rede lenta (como uma conexão 3G ruim), bem como sem acesso à rede, é
essencial para garantir que você não envie um aplicativo de bugs. O processo de aprovação sempre incluirá
um teste com o dispositivo no modo avião, portanto, certifique-se de que você já testou isso por conta
própria.
Variação de hardware – Lembre-se de testar o hardware mais antigo e mais lento para o qual você planeja
dar suporte. Há dois aspectos que podem afetar seu aplicativo: desempenho, que pode ser inutilizável em
um dispositivo mais antigo e suporte para recursos de hardware, como uma câmera, microfone, GPS,
giroscópio ou outro componente opcional. Os aplicativos devem degradar normalmente (e não falhar)
quando um componente não está disponível.
As diretrizes são mais do que apenas um ' guia '
A Apple é famosa por ser estrito sobre a adesão às suas diretrizes de interface humana, uma vez que uma das
principais forças de sua plataforma é a consistência (e o aumento percebido na usabilidade). A Microsoft adotou
uma abordagem semelhante com os aplicativos do Windows que implementam o sistema de design fluente. O
processo de aprovação para ambas as plataformas envolverá seu aplicativo sendo avaliado para sua adesão à
filosofia de design relevante.
Isso não quer dizer que a inovação da interface do usuário não é suportada nem incentivada, mas há certas
coisas que você não deve fazer "ou seu aplicativo será rejeitado.
No iOS, isso inclui o uso inadequado de ícones internos ou o uso de outras metáforas bem estabelecidas de
maneira não consistente; por exemplo, usando o ícone ' compor ' para qualquer coisa que não seja a criação de
um novo conteúdo.
Os desenvolvedores do Windows devem ter um cuidado semelhante. um erro comum é a falha em dar suporte
corretamente ao botão voltar do hardware de acordo com as diretrizes da Microsoft.
Incentive seus designers a ler e seguir as diretrizes de design para cada plataforma.
Implementando recursos específicos da plataforma
As coisas são um pouco mais rígidas quando se trata de implementar serviços específicos da plataforma,
especialmente no iOS. Para evitar a rejeição automática da Apple, há algumas regras a serem seguidas com os
seguintes recursos do iOS:
Compras no aplicativo – os aplicativos não devem implementar mecanismos de pagamento externos para
produtos digitais, incluindo a moeda do jogo, recursos do aplicativo, assinaturas da revista e muito mais. os
aplicativos iOS devem usar o serviço do iTunes da Apple para esse tipo de funcionalidade. Há um brecha
como o leitor de Kindle e alguns aplicativos baseados em assinatura permitem que você compre conteúdo
em outro lugar que é anexado a uma "conta" que você pode acessar por meio do aplicativo. no entanto,
nesse caso, o aplicativo não deve conter links ou referências ao processo de compra fora do aplicativo (ou,
mais uma vez, ele será rejeitado).
backup do icloud – com o advento do icloud, os revisores da Apple são muito mais estritos em relação a
como os aplicativos usam o armazenamento (para garantir que a experiência de backup remoto do cliente
seja agradável). Os aplicativos que desperdiçam espaço de armazenamento capaz de fazer backup podem
ser rejeitados, portanto, use a pasta de cache adequadamente e siga as outras diretrizes relacionadas ao
armazenamento da Apple.
Newsstand – os aplicativos de jornal e de revista são uma ótima opção para o Newsstand da Apple, no
entanto, os aplicativos devem implementar pelo menos uma assinatura de renovação automática e dar
suporte ao download em segundo plano para serem aprovados.
Mapas – é cada vez mais comum adicionar sobreposições e outros recursos aos mapas móveis, no entanto,
tenha cuidado para não obscurecer as informações de "créditos" do mapa (como o logotipo do Google no
iOS5), pois isso resultará em rejeição.
Gerenciar seus metadados
Além dos problemas técnicos óbvios que podem resultar em um aplicativo sendo rejeitado, há alguns aspectos
mais sutis de seu envio que podem resultar em rejeição, especialmente em relação aos metadados (descrição,
palavras-chave e imagens de marketing) que você envia com seu aplicativo para exibição na loja de aplicativos
ou no Marketplace.
Imagens – siga as diretrizes da plataforma para ícones de aplicativos e armazene imagens. Não use imagens
marcadas, nós vimos que os aplicativos são rejeitados porque seus ícones apresentavam um desenho de um
iPhone!
Marcas registradas – Evite usar marcas comerciais diferentes da sua. Os aplicativos foram negados para
mencionar marcas registradas na descrição do aplicativo ou mesmo nas palavras-chave na loja de aplicativos
da Apple.
Descrição – não use a palavra ' beta ' ou, de qualquer forma, indique que o aplicativo não está pronto para
o momento principal. Não mencione outras plataformas móveis (mesmo que seu aplicativo seja entre
plataformas). Mais importante, verifique se o aplicativo faz exatamente o que você diz que ele faz. Se você
listar vários recursos em sua descrição, ele teria mais óbvio como usar cada um desses recursos ou você
receberá uma rejeição "o recurso mencionado na descrição do aplicativo não está implementado".
Coloque o máximo de esforço nos metadados do aplicativo como em desenvolvimento e teste. Os aplicativos
são rejeitados para violações secundárias nos metadados, portanto, vale a pena dedicar o tempo para obtê-lo
certo.
Lojas de aplicativos: não para todos
O foco principal dos armazenamentos em cada plataforma é a distribuição do consumidor-a capacidade de
alcançar o máximo possível de clientes. No entanto, nem todos os aplicativos são destinados a consumidores, há
uma base rápida em crescimento de aplicativos internos e de extranet que exigem distribuição limitada para
funcionários, fornecedores ou clientes. Esses aplicativos não são "para venda" e não precisam de aprovação, já
que o desenvolvedor controla a distribuição para um grupo de usuários fechado. O suporte para esse tipo de
implantação varia de acordo com a plataforma.
O Android oferece mais flexibilidade nesse aspecto: os aplicativos podem ser instalados diretamente de uma
URL ou anexo de email (contanto que a configuração do dispositivo permita isso). Isso significa que é trivial criar
e distribuir aplicativos corporativos internos ou publicar aplicativos para clientes ou fornecedores específicos.
A Apple fornece uma opção de implantação interna para os desenvolvedores registrados no programa
corporativo do desenvolvedor do iOS, que ignora o processo de aprovação da loja de aplicativos e permite que
as empresas distribuam aplicativos internos para seus funcionários. Infelizmente, essa licença não atende à
necessidade de distribuição de aplicativo semelhante à extranet para outros grupos fechados de clientes ou
fornecedores. Implantação Enterprise (e ad hoc)
Resumo da loja de aplicativos
O processo de revisão pode ser assustador, mas como o restante do ciclo de vida de desenvolvimento, você
pode ajudar a garantir o sucesso com um pouco de planejamento e atenção para os detalhes. Tudo isso se
resume a algumas etapas simples: ler e entender as diretrizes de interface do usuário que você deve obedecer,
siga as regras se estiver implementando recursos específicos da plataforma, teste totalmente (e teste mais
alguns) e, finalmente, verifique se os metadados do aplicativo estão corretos antes de enviar.
Uma última palavra de conselhos para os desenvolvedores que estão publicando na Google Play: a falta de
processo de aprovação pode parecer que torna seu trabalho mais fácil, mas seus clientes serão ainda mais
exigentes do que uma equipe de análise. Siga estas diretrizes como se seu aplicativo pudesse ser rejeitado, caso
contrário, será seus clientes fazendo a rejeição.
Estudo de caso de aplicativo de plataforma
cruzada: tarefa
02/11/2020 • 33 minutes to read • Edit Online

A tarefa portátil é um aplicativo simples de lista de tarefas pendentes. Este documento discute como ele foi
projetado e criado, seguindo as orientações do documento criando aplicativos para várias plataformas . A
discussão aborda as seguintes áreas:

Processo de design
É aconselhável criar um mapa de estrada para o que você deseja obter antes de começar a codificar. Isso é
especialmente verdadeiro para o desenvolvimento de plataforma cruzada, em que você está criando
funcionalidades que serão expostas de várias maneiras. Começar com uma clara ideia do que você está criando
economiza tempo e esforço posteriormente no ciclo de desenvolvimento.
Requisitos
A primeira etapa na criação de um aplicativo é identificar os recursos desejados. Elas podem ser metas de alto
nível ou casos de uso detalhados. A tarefa tem requisitos funcionais diretos:
Exibir uma lista de tarefas
Adicionar, editar e excluir tarefas
Definir o status de uma tarefa como ' done '
Você deve considerar o uso de recursos específicos da plataforma. A tarefa pode aproveitar os blocos dinâmicos
de isolamento de iOS ou Windows Phone? Mesmo que você não use recursos específicos da plataforma na
primeira versão, planeje antecipadamente para garantir que seus negócios & camadas de dados possam
acomodá-los.
Design da interface do usuário
Comece com um design de alto nível que pode ser implementado nas plataformas de destino. Tome cuidado
para observar as restrições da interface do usuário da plataforma específico. Por exemplo, um TabBarController
no IOS pode exibir mais de cinco botões, enquanto o equivalente Windows Phone pode exibir até quatro.
Desenhe o fluxo de tela usando a ferramenta de sua escolha (papel funciona).
Modelo de dados
Saber quais dados precisam ser armazenados ajudará a determinar qual mecanismo de persistência será usado.
Consulte acesso a dados entre plataformas para obter informações sobre os mecanismos de armazenamento
disponíveis e ajudar a decidir entre eles. Para este projeto, vamos usar SQLite.NET.
A tarefa precisa armazenar três propriedades para cada ' TaskItem ':
Name – Cadeia de caracteres
Obser vações – cadeia de caracteres
Concluído – booliano
Funcionalidade principal
Considere a API que a interface do usuário precisará consumir para atender aos requisitos. Uma lista de tarefas
pendentes requer as seguintes funções:
Listar todas as tarefas – para exibir a lista de tela principal de todas as tarefas disponíveis
Obter uma tarefa – quando uma linha de tarefa é tocada
Salvar uma tarefa – quando uma tarefa é editada
Excluir uma tarefa – quando uma tarefa é excluída
Criar tarefa vazia – quando uma nova tarefa é criada
Para obter a reutilização de código, essa API deve ser implementada uma vez na biblioteca de classes portátil.
Implementação
Depois que o design do aplicativo tiver sido acordado, considere como ele pode ser implementado como um
aplicativo de plataforma cruzada. Isso se tornará a arquitetura do aplicativo. Seguindo as orientações no
documento criando aplicativos entre plataformas , o código do aplicativo deve ser dividido nas seguintes partes:
Código comum – um projeto comum que contém código reutilizado para armazenar os dados da tarefa;
expor uma classe de modelo e uma API para gerenciar o salvamento e o carregamento de dados.
Código específico da plataforma – projetos específicos da plataforma que implementam uma interface
do usuário nativa para cada sistema operacional, utilizando o código comum como o ' back-end '.
Essas duas partes são descritas nas seções a seguir.

Código comum (PCL)


A tarefa portátil usa a estratégia de biblioteca de classes portátil para compartilhar código comum. Consulte o
documento Opções de código de compartilhamento para obter uma descrição das opções de
compartilhamento de código.
Todo o código comum, incluindo a camada de acesso a dados, o código e os contratos dele, é colocado no
projeto de biblioteca.
O projeto PCL completo é ilustrado abaixo. Todo o código na biblioteca portátil é compatível com cada
plataforma de destino. Quando implantado, cada aplicativo nativo fará referência a essa biblioteca.

O diagrama de classe abaixo mostra as classes agrupadas por camada. A SQLiteConnection classe é um código
clichê do pacote SQLite-net. O restante das classes é o código personalizado para a tarefa. As TaskItemManager
TaskItem classes e representam a API que é exposta aos aplicativos específicos da plataforma.
O uso de namespaces para separar as camadas ajuda a gerenciar referências entre cada camada. Os projetos
específicos da plataforma devem precisar incluir apenas uma using instrução para a camada de negócios. A
camada de acesso a dados e a camada de dados devem ser encapsuladas pela API que é exposta pelo
TaskItemManager na camada de negócios.

Referências
Bibliotecas de classes portáteis precisam ser utilizáveis em várias plataformas, cada uma com níveis variados de
suporte para recursos de plataforma e estrutura. Por isso, há limitações em quais pacotes e bibliotecas de
estrutura podem ser usadas. Por exemplo, o Xamarin. iOS não oferece suporte à dynamic palavra-chave c#,
portanto, uma biblioteca de classes portátil não pode usar nenhum pacote que dependa de código dinâmico,
mesmo que esse código funcione no Android. Visual Studio para Mac impedirá a adição de pacotes e referências
incompatíveis, mas você desejará manter as limitações em mente para evitar surpresas posteriormente.
Observação: você verá que seus projetos fazem referência a bibliotecas de estrutura que você não usou. Essas
referências são incluídas como parte dos modelos de projeto do Xamarin. Quando os aplicativos são
compilados, o processo de vinculação removerá o código não referenciado, portanto, embora System.Xml tenha
sido referenciado, ele não será incluído no aplicativo final porque não estamos usando nenhuma função XML.
Camada de dados (DL )
A camada de dados contém o código que faz o armazenamento físico de dados – seja para um banco de dado,
arquivos simples ou outro mecanismo. A camada de dados tarefa consiste em duas partes: a biblioteca SQLite-
NET e o código personalizado adicionado para conectá-lo.
A tarefa depende do pacote de NuGet do SQLite-net (publicado por Frank Krueger) para inserir o código SQLite-
NET que fornece uma interface de banco de dados de ORM (mapeamento relacional de objeto). A
TaskItemDatabase classe herda de SQLiteConnection e adiciona os métodos CRUD (criar, ler, atualizar, excluir)
necessários para ler e gravar dados no SQLite. É uma implementação padronizada simples de métodos CRUD
genéricos que podem ser reutilizados em outros projetos.
O TaskItemDatabase é um singleton, garantindo que todo o acesso ocorra na mesma instância. Um bloqueio é
usado para impedir o acesso simultâneo de vários threads.
SQLite em Windows Phone
Embora o iOS e o Android sejam fornecidos com o SQLite como parte do sistema operacional, Windows Phone
não inclui um mecanismo de banco de dados compatível. Para compartilhar o código entre todas as três
plataformas, é necessário ter uma versão nativa do SQLite do Windows Phone. Consulte trabalhando com um
banco de dados local para obter mais informações sobre como configurar seu projeto de Windows Phone para
SQLite.
Usando uma interface para generalizar o acesso a dados
A camada de dados assume uma dependência BL.Contracts.IBusinessIdentity para que possa implementar
métodos de acesso a dados abstratos que exigem uma chave primária. Qualquer classe de camada comercial
que implementa a interface pode ser persistida na camada de dados.
A interface especifica apenas uma propriedade Integer para atuar como a chave primária:

public interface IBusinessEntity {


int ID { get; set; }
}

A classe base implementa a interface e adiciona os atributos SQLite-NET para marcá-lo como uma chave
primária de incremento automático. Qualquer classe na camada de negócios que implementa essa classe base
pode ser persistida na camada de dados:

public abstract class BusinessEntityBase : IBusinessEntity {


public BusinessEntityBase () {}
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
}

Um exemplo dos métodos genéricos na camada de dados que usam a interface é esse GetItem<T> método:

public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()


{
lock (locker) {
return Table<T>().FirstOrDefault(x => x.ID == id);
}
}

Bloqueio para impedir o acesso simultâneo


Um bloqueio é implementado dentro da TaskItemDatabase classe para impedir o acesso simultâneo ao banco
de dados. Isso é para garantir o acesso simultâneo de threads diferentes é serializado (caso contrário, um
componente de interface do usuário pode tentar ler o banco de dados ao mesmo tempo em que um thread em
segundo plano está atualizando). Um exemplo de como o bloqueio é implementado é mostrado aqui:

static object locker = new object ();


public IEnumerable<T> GetItems<T> () where T : BL.Contracts.IBusinessEntity, new ()
{
lock (locker) {
return (from i in Table<T> () select i).ToList ();
}
}
public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()
{
lock (locker) {
return Table<T>().FirstOrDefault(x => x.ID == id);
}
}

A maior parte do código da camada de dados pode ser reutilizada em outros projetos. O único código específico
do aplicativo na camada é a CreateTable<TaskItem> chamada no TaskItemDatabase Construtor.
Camada de acesso a dados (DAL )
A TaskItemRepository classe encapsula o mecanismo de armazenamento de dados com uma API fortemente
tipada que permite que os TaskItem objetos sejam criados, excluídos, recuperados e atualizados.
Usando a compilação condicional
A classe usa a compilação condicional para definir o local do arquivo – este é um exemplo de implementação de
divergência de plataforma. A propriedade que retorna o caminho é compilada para código diferente em cada
plataforma. As diretivas de compilador específicas do código e da plataforma são mostradas aqui:

public static string DatabaseFilePath {


get {
var sqliteFilename = "TaskDB.db3";
#if SILVERLIGHT
// Windows Phone expects a local path, not absolute
var path = sqliteFilename;
#else
#if __ANDROID__
// Just use whatever directory SpecialFolder.Personal returns
string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); ;
#else
// we need to put in /Library/ on iOS5.1+ to meet Apple's iCloud terms
// (they don't want non-user-generated data in Documents)
string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents
folder
string libraryPath = Path.Combine (documentsPath, "..", "Library"); // Library folder
#endif
var path = Path.Combine (libraryPath, sqliteFilename);
#endif
return path;
}
}

Dependendo da plataforma, a saída será " /library/TaskDB.DB3" para IOS, " /Documents/TaskDB.DB3" para
Android ou apenas "TaskDB. DB3" para Windows Phone.
Camada de negócios (BL )
A camada de negócios implementa as classes de modelo e uma fachada para gerenciá-las. Em tarefa, o modelo
é a TaskItem classe e TaskItemManager implementa o padrão de fachada para fornecer uma API para gerenciar
TaskItems .

Fachada
TaskItemManager encapsula o DAL.TaskItemRepository para fornecer os métodos get, Save e Delete que serão
referenciados pelas camadas do aplicativo e da interface do usuário.
As regras de negócio e a lógica seriam colocadas aqui, se necessário, por exemplo, todas as regras de validação
que devem ser satisfeitas antes que um objeto seja salvo.
API para código específico da plataforma
Depois que o código comum tiver sido escrito, a interface do usuário deverá ser criada para coletar e exibir os
dados expostos por ele. A TaskItemManager classe implementa o padrão de fachada para fornecer uma API
simples para o código do aplicativo acessar.
O código escrito em cada projeto específico da plataforma geralmente será rigidamente acoplado ao SDK nativo
do dispositivo e acessará apenas o código comum usando a API definida pelo TaskItemManager . Isso inclui os
métodos e as classes de negócios que ele expõe, como TaskItem .
As imagens não são compartilhadas entre plataformas, mas adicionadas de forma independente a cada projeto.
Isso é importante porque cada plataforma manipula imagens de forma diferente, usando nomes de arquivo,
diretórios e resoluções diferentes.
As seções restantes abordam os detalhes de implementação específicos da plataforma da interface do usuário.
Aplicativo iOS
Há apenas algumas classes necessárias para implementar o aplicativo de tarefa do iOS usando o projeto PCL
comum para armazenar e recuperar dados. O projeto do Xamarin. iOS completo do iOS é mostrado abaixo:

As classes são mostradas neste diagrama, agrupadas em camadas.

Referências
O aplicativo iOS faz referência às bibliotecas de SDK específicas da plataforma – por exemplo, Xamarin. iOS e
MonoTouch. caixa de diálogo-1.
Ele também deve fazer referência ao TaskyPortableLibrary projeto PCL. A lista de referências é mostrada aqui:

A camada de aplicativo e a camada de interface do usuário são implementadas neste projeto usando essas
referências.
Camada de aplicativo (AL )
A camada de aplicativo contém classes específicas da plataforma necessárias para "associar" os objetos
expostos pelo PCL à interface do usuário. O aplicativo específico para iOS tem duas classes para ajudar a exibir
tarefas:
Editingion – essa classe é usada para associar listas de tarefas à interface do usuário. Como
MonoTouch.Dialog o foi usado para a lista de tarefas, precisamos implementar esse auxiliar para habilitar a
funcionalidade de passar para a exclusão no UITableView . Passar o dedo para exclusão é comum no iOS,
mas não no Android ou Windows Phone, portanto, o projeto específico do iOS é o único que o implementa.
TaskDialog – essa classe é usada para associar uma única tarefa à interface do usuário. Ele usa a
MonoTouch.Dialog API de reflexão para "encapsular" o TaskItem objeto com uma classe que contém os
atributos corretos para permitir que a tela de entrada seja formatada corretamente.
A TaskDialog classe usa MonoTouch.Dialog atributos para criar uma tela com base nas propriedades de uma
classe. A classe é parecida com esta:

public class TaskDialog {


public TaskDialog (TaskItem task)
{
Name = task.Name;
Notes = task.Notes;
Done = task.Done;
}
[Entry("task name")]
public string Name { get; set; }
[Entry("other task info")]
public string Notes { get; set; }
[Entry("Done")]
public bool Done { get; set; }
[Section ("")]
[OnTap ("SaveTask")] // method in HomeScreen
[Alignment (UITextAlignment.Center)]
public string Save;
[Section ("")]
[OnTap ("DeleteTask")] // method in HomeScreen
[Alignment (UITextAlignment.Center)]
public string Delete;
}

Observe que os OnTap atributos exigem um nome de método – esses métodos devem existir na classe em que
o MonoTouch.Dialog.BindingContext é criado (nesse caso, a HomeScreen classe discutida na próxima seção).
Camada da interface do usuário (IU )
A camada da interface do usuário consiste nas seguintes classes:
1. AppDelegate – contém chamadas para a API de aparência para estilizar as fontes e cores usadas no
aplicativo. A tarefa é um aplicativo simples, portanto, não há outras tarefas de inicialização em execução no
FinishedLaunching .
2. Telas – subclasses de UIViewController que definem cada tela e seu comportamento. As telas reúnem a
interface do usuário com classes de camada de aplicativo e a API comum ( TaskItemManager ). Neste
exemplo, as telas são criadas no código, mas elas podem ter sido projetadas usando Interface Builder do
Xcode ou o designer do storyboard.
3. Imagens – os elementos visuais são uma parte importante de cada aplicativo. A tarefa tem imagens de tela
inicial e ícone, que para o iOS deve ser fornecida em resolução regular e retina.
Tela de Início
A tela inicial é uma MonoTouch.Dialogtela que exibe uma lista de tarefas do banco de dados SQLite. Ele herda de
DialogViewController e implementa o código para definir o Root para conter uma coleção de TaskItem
objetos para exibição.
Os dois métodos principais relacionados à exibição e interação com a lista de tarefas são:
1. Populable – usa o método da camada de negócios TaskManager.GetTasks para recuperar uma coleção de
TaskItem objetos a serem exibidos.
2. Selecionado – quando uma linha é tocada, o exibe a tarefa em uma nova tela.
Tela de detalhes da tarefa
Detalhes da tarefa é uma tela de entrada que permite que as tarefas sejam editadas ou excluídas.
O taskal usa a MonoTouch.Dialog API de reflexão para exibir a tela, portanto, não há nenhuma UIViewController
implementação. Em vez disso, a HomeScreen classe instancia e exibe um DialogViewController usando a
TaskDialog classe da camada de aplicativo.

Esta captura de tela mostra uma exibição vazia que demonstra o Entry atributo definindo o texto da marca d'
água nos campos Name e Notes :
A funcionalidade da tela de detalhes da tarefa (como salvar ou excluir uma tarefa) deve ser implementada na
HomeScreen classe, pois é onde o MonoTouch.Dialog.BindingContext é criado. Os métodos a seguir HomeScreen
dão suporte à tela de detalhes da tarefa:
1. ShowTaskDetails – cria um MonoTouch.Dialog.BindingContext para renderizar uma tela. Ele cria a tela de
entrada usando reflexão para recuperar os nomes e tipos de propriedade da TaskDialog classe. Informações
adicionais, como o texto de marca d' água para as caixas de entrada, são implementadas com atributos nas
propriedades.
2. SaveTask – esse método é referenciado na TaskDialog classe por meio de um OnTap atributo. Ele é
chamado quando Save é pressionado e usa um MonoTouch.Dialog.BindingContext para recuperar os dados
inseridos pelo usuário antes de salvar as alterações usando TaskItemManager .
3. DeleteTask – esse método é referenciado na TaskDialog classe por meio de um OnTap atributo. Ele usa
TaskItemManager para excluir os dados usando a chave primária (Propriedade ID).

Aplicativo do Android
O projeto Xamarin. Android completo é mostrado abaixo:

O diagrama de classe, com classes agrupadas por camada:


Referências
O projeto de aplicativo do Android deve fazer referência ao assembly Xamarin. Android específico da plataforma
para acessar classes do SDK do Android.
Ele também deve fazer referência ao projeto PCL (por exemplo, TaskyPortableLibrary) para acessar os dados
comuns e o código da camada de negócios.

Camada de aplicativo (AL )


Semelhante à versão do iOS que vimos anteriormente, a camada de aplicativo na versão do Android contém
classes específicas da plataforma necessárias para "associar" os objetos expostos pelo núcleo à interface do
usuário.
TaskListAdapter – para exibir uma lista <T> de objetos, precisamos implementar um adaptador para exibir
objetos personalizados em um ListView . O adaptador controla qual layout é usado para cada item na lista –
nesse caso, o código usa um layout interno do Android SimpleListItemChecked .
Interface do Usuário (IU )
A camada de interface do usuário do aplicativo Android é uma combinação de código e marcação XML.
Recursos/layout – layouts de tela e o design de célula de linha implementados como arquivos AXML. A
AXML pode ser escrita manualmente ou disposta visualmente usando o designer de interface do usuário do
Xamarin para Android.
Recursos/desenháveis – imagens (ícones) e botão personalizado.
Telas – subclasses de atividade que definem cada tela e seu comportamento. Une a interface do usuário com
classes de camada de aplicativo e a API comum ( TaskItemManager ).
Tela de Início
A tela inicial consiste em uma subclasse de atividade HomeScreen e o HomeScreen.axml arquivo que define o
layout (posição do botão e da lista de tarefas). A tela é parecida com esta:
O código da tela inicial define os manipuladores para clicar no botão e clicar em itens na lista, bem como
preencher a lista no OnResume método (para que ele reflita as alterações feitas na tela de detalhes da tarefa). Os
dados são carregados usando a camada de negócios TaskItemManager e a TaskListAdapter da camada de
aplicativo.
Tela de detalhes da tarefa
A tela de detalhes da tarefa também consiste em uma Activity subclasse e um arquivo de layout AXML. O
layout determina o local dos controles de entrada e a classe C# define o comportamento para carregar e salvar
TaskItem objetos.

Todas as referências à biblioteca PCL são por meio da TaskItemManager classe.


Windows Phone aplicativo
O projeto de Windows Phone completo:

O diagrama a seguir apresenta as classes agrupadas em camadas:

Referências
O projeto específico da plataforma deve fazer referência às bibliotecas específicas da plataforma necessárias
(como Microsoft.Phone e System.Windows ) para criar um aplicativo de Windows Phone válido.
Ele também deve fazer referência ao projeto PCL (por exemplo, TaskyPortableLibrary ) para utilizar a TaskItem
classe e o banco de dados.

Camada de aplicativo (AL )


Novamente, assim como nas versões iOS e Android, a camada de aplicativo consiste em elementos não visuais
que ajudam a associar dados à interface do usuário.
ViewModels
Os ViewModels encapsulam dados do PCL ( TaskItemManager ) e os apresentam de forma que podem ser
consumidos pela ligação de dados do Silverlight/XAML. Este é um exemplo de comportamento específico da
plataforma (conforme discutido no documento aplicativos de plataforma cruzada).
Interface do Usuário (IU )
O XAML tem um recurso de vinculação de dados exclusivo que pode ser declarado na marcação e reduzir a
quantidade de código necessária para exibir objetos:
1. Páginas – arquivos XAML e seu code-behind definem a interface do usuário e referenciam os ViewModels e
o projeto PCL para exibir e coletar dados.
2. Imagens – tela inicial, imagens de plano de fundo e ícone são uma parte importante da interface do usuário.
MainPage
A classe MainPage usa o TaskListViewModel para exibir dados usando os recursos de associação de dados do
XAML. A página DataContext é definida como o modelo de exibição, que é preenchido de forma assíncrona. A
{Binding} sintaxe no XAML determina como os dados são exibidos.

TaskDetailsPage
Cada tarefa é exibida ligando o TaskViewModel ao XAML definido no TaskDetailsPage. XAML. Os dados da tarefa
são recuperados por meio do TaskItemManager na camada de negócios.

Resultados
Os aplicativos resultantes têm esta aparência em cada plataforma:
iOS
O aplicativo usa o design de interface do usuário padrão iOS, como o botão "Adicionar" posicionado na barra de
navegação e usando o ícone de adição (+) interno. Ele também usa o UINavigationController comportamento
de botão "voltar" padrão e dá suporte a "passar o dedo para exclusão" na tabela.

.
Android
O aplicativo do Android usa controles internos, incluindo o layout interno para linhas que exigem um ' tique '
exibido. O comportamento de retorno de hardware/sistema é suportado além de um botão voltar na tela.

Windows Phone
O aplicativo Windows Phone usa o layout padrão, preenchendo a barra de aplicativos na parte inferior da tela,
em vez de uma barra de navegação na parte superior.

Resumo
Este documento forneceu uma explicação detalhada de como os princípios de design de aplicativos em camadas
foram aplicados a um aplicativo simples para facilitar o reutilização de código em três plataformas móveis: iOS,
Android e Windows Phone.
Ele descreveu o processo usado para criar as camadas do aplicativo e discutiu qual & funcionalidade de código
foi implementada em cada camada.
O código pode ser baixado do GitHub.

Links Relacionados
Criando aplicativos de plataforma cruzada (documento principal)
Aplicativo de exemplo portátil para tarefas (github)
Compartilhando código em várias plataformas
23/04/2020 • 4 minutes to read • Edit Online

Estes artigos explicam as diferentes opções disponíveis para o compartilhamento de código entre plataformas,
incluindo Windows, Android, iOS e muito mais.

Visão geral de compartilhamento de código


Saiba mais sobre as diferentes opções de compartilhamento de código disponíveis para projetos do Xamarin,
incluindo bibliotecas de .NET Standard e projetos compartilhados. As bibliotecas de classes portáteis também
têm suporte, no entanto, elas são consideradas preteridas em favor da .NET Standard.

.NET Standard
.NET Standard é a opção preferida para compartilhar código entre plataformas. O código é criado com base em
uma versão específica (2,0 fornece a melhor compatibilidade de API com o código de .NET Framework existente)
e, em seguida, pode ser consumido por outros projetos que dão suporte a esse nível ou mais. .NET Standard
projetos têm suporte no Visual Studio 2019 e no Visual Studio 2019 para Mac.

Projetos compartilhados
Projetos compartilhados permitem que você escreva código comum que é referenciado por vários projetos de
aplicativo diferentes. O código é compilado como parte de cada projeto de referência e pode incluir diretivas de
compilador para ajudar a incorporar a funcionalidade específica da plataforma na base de código
compartilhada. Este artigo discute como os projetos compartilhados funcionam e como criá-los e usá-los com
projetos do Xamarin.

Bibliotecas de classes portáteis


Os projetos de biblioteca de classes portáteis permitem criar e distribuir assemblies que contêm código
compartilhado para serem executados em várias plataformas. Para criar uma biblioteca de classes portátil (ou
"PCL"), primeiro selecione as plataformas a serem direcionadas e, em seguida, escreva o código em um
subconjunto do .NET Framework que está disponível no perfil definido para essas plataformas. PCLs são
considerados preteridos nas versões mais recentes do Visual Studio; os desenvolvedores são incentivados a
usar o .NET Standard 2,0 em vez disso.

Projetos do NuGet: bibliotecas multiplataforma para o


compartilhamento de código
Os pacotes NuGet podem ser gerados automaticamente de projetos PCL ou .NET Standard; e os projetos
compartilhados podem ser empacotados em pacotes NuGet "bait and switch" usando o tipo de projeto do
NuGet separado. Esta seção explica como criar pacotes NuGet para cada cenário de compartilhamento de
código.

Criando manualmente pacotes NuGet para o Xamarin


Dicas para criar pacotes NuGet que funcionam com a plataforma Xamarin.

Usar C/C++ Libraries em projetos Xamarin de plataforma cruzada


Essa técnica permite que você Desassocie a evolução de suas bibliotecas CC++ /, uma C# associação em um
NuGet e seus aplicativos Xamarin. A funcionalidade é fornecida pela plataforma C/C++ biblioteca nativa, mas
todo o código específico da plataforma é isolado do (s) aplicativo (es) final do Xamarin, permitindo o melhor
desempenho possível sem duplicação de código.
Visão geral do código de compartilhamento
02/11/2020 • 9 minutes to read • Edit Online

Este documento compara os diferentes métodos de compartilhamento de código entre projetos de plataforma
cruzada: .NET Standard, projetos compartilhados e bibliotecas de classes portáteis, incluindo os benefícios e as
desvantagens de cada um.
Há três métodos para compartilhar código entre aplicativos de plataforma cruzada:
Bibliotecas de .net Standard – .net Standard projetos podem implementar o código a ser compartilhado
entre várias plataformas e pode acessar um grande número de APIs do .net (dependendo da versão). .NET
Standard 1,0-1,6 implementar conjuntos de APIs de forma progressiva maior, enquanto .NET Standard 2,0
fornece a melhor cobertura do .NET BCL (incluindo as APIs .NET disponíveis em aplicativos Xamarin).
Projetos compar tilhados – use o tipo de projeto de ativo compartilhado para organizar seu código-fonte
e use as #if diretivas do compilador conforme necessário para gerenciar requisitos específicos da
plataforma.
Bibliotecas de classes por táteis (preteridas) – PCLs (bibliotecas de classes portáteis) podem direcionar
várias plataformas com uma superfície de API comum e usar interfaces para fornecer funcionalidade
específica da plataforma. Os PCLs são preteridos nas versões mais recentes do Visual Studio – . em vez disso,
use .net Standard.
O objetivo de uma estratégia de compartilhamento de código é dar suporte à arquitetura mostrada neste
diagrama, em que uma única codebase pode ser utilizada por várias plataformas.

Este artigo compara os métodos disponíveis para ajudá-lo a escolher o tipo de projeto certo para seus
aplicativos.

Bibliotecas de .NET Standard


As bibliotecas de .net Standard fornecem um conjunto bem definido de bibliotecas de classes base que podem
ser referenciadas em diferentes tipos de projeto, incluindo projetos de plataforma cruzada, como Xamarin.
Android e Xamarin. Ios. .NET Standard 2,0 é recomendado para compatibilidade máxima com o código de .NET
Framework existente.

Vantagens
Permite que você compartilhe código entre vários projetos.
As operações de refatoração sempre atualizam todas as referências afetadas.
Uma área de superfície maior da BCL (biblioteca de classes base) do .NET está disponível para perfis PCL. Em
particular, .NET Standard 2,0 tem quase a mesma superfície de API que a .NET Framework e é recomendada
para novos aplicativos e portar PCLs existentes.
Desvantagens
Não é possível usar diretivas de compilador como #if __IOS__ .
Comentários
.NET Standard é semelhante a PCL, mas com um modelo mais simples para suporte de plataforma e um
número maior de classes da BCL.

Projetos compartilhados
Projetos compartilhados contêm arquivos de código e ativos que são incluídos em qualquer projeto que os
referencia. Os projetos de compartilhamento não produzem a saída compilada por conta própria.
Esta captura de tela mostra um arquivo de solução que contém três projetos de aplicativo (para Android, iOS e
Windows), com um projeto compar tilhado que contém arquivos de código-fonte C# comuns:

A arquitetura conceitual é mostrada no diagrama a seguir, onde cada projeto inclui todos os arquivos de origem
compartilhados:
Exemplo
Um aplicativo de plataforma cruzada que dá suporte a iOS, Android e Windows exigiria um projeto de aplicativo
para cada plataforma. O código comum reside no projeto compartilhado.
Uma solução de exemplo conteria as seguintes pastas e projetos (nomes de projeto foram escolhidos para fins
expressivos, seus projetos não precisam seguir essas diretrizes de nomenclatura):
Compar tilhado – projeto compartilhado que contém o código comum a todos os projetos.
AppAndroid – projeto de aplicativo Xamarin. Android.
AppiOS – projeto de aplicativo Xamarin. Ios.
AppWindows – projeto de aplicativo do Windows.
Dessa forma, os três projetos de aplicativo estão compartilhando o mesmo código-fonte (os arquivos C# em
compartilhado). Todas as edições no código compartilhado serão compartilhadas entre todos os três projetos.
Vantagens
Permite que você compartilhe código entre vários projetos.
O código compartilhado pode ser ramificado com base na plataforma usando as diretivas do compilador
(por exemplo, usando #if __ANDROID__ o, conforme discutido no documento criando aplicativos de
plataforma cruzada .
Os projetos de aplicativo podem incluir referências específicas à plataforma que o código compartilhado
pode utilizar (como usar Community.CsharpSqlite.WP7 no exemplo de tarefa para Windows Phone).
Desvantagens
Refatoração que afetam o código dentro de diretivas de compilador ' inativas ' não atualizarão o código
dentro dessas diretivas.
Ao contrário da maioria dos outros tipos de projeto, um projeto compartilhado não tem nenhum assembly
de ' saída '. Durante a compilação, os arquivos são tratados como parte do projeto de referência e
compilados nesse assembly. Se você deseja compartilhar seu código como um assembly, .NET Standard ou
bibliotecas de classe portátil são uma solução melhor.
Comentários
Uma boa solução para desenvolvedores de aplicativos que escrevem código destinado apenas ao
compartilhamento em seus aplicativos (e não a distribuição a outros desenvolvedores).
Bibliotecas de Classes Portáteis
TIP
.NET Standard bibliotecas 2,0 são recomendadas em relação às bibliotecas de classes portáteis.

As bibliotecas de classes portáteis são discutidas em detalhes aqui.

Vantagens
Permite que você compartilhe código entre vários projetos.
As operações de refatoração sempre atualizam todas as referências afetadas.
Desvantagens
Preteridas nas versões mais recentes do Visual Studio, em vez disso, as bibliotecas de .NET Standard são
recomendadas. Consulte esta explicação das diferenças entre o PCL e o .net Standard.
Não é possível usar diretivas de compilador.
Somente um subconjunto do .NET Framework está disponível para uso, determinado pelo perfil selecionado
(consulte a introdução ao PCL para obter mais informações).
Comentários
O modelo PCL é considerado preterido nas versões mais recentes do Visual Studio.

Resumo
A estratégia de compartilhamento de código que você escolher será orientada pelas plataformas de destino.
Escolha um método que funcione melhor para seu projeto.
.NET Standard é a melhor opção para criar bibliotecas de código compartilháveis (especialmente a publicação
no NuGet). Projetos compartilhados funcionam bem para desenvolvedores de aplicativos que planejam usar
muitas funcionalidades específicas da plataforma em seus aplicativos de plataforma cruzada.
Embora os projetos PCL continuem a ter suporte no Visual Studio, .NET Standard é recomendada para novos
projetos.
Links relacionados
Criando aplicativos de plataforma cruzada (documento principal)
Bibliotecas de Classes Portáteis
Projetos compartilhados
.NET Standard
Estudo de caso: Tasky
Exemplo de tarefa (github)
Exemplo de tarefa usando PCL (github)
Compartilhamento de código de biblioteca .NET
Standard
02/11/2020 • 4 minutes to read • Edit Online

As bibliotecas de .NET Standard têm uma API uniforme para todas as plataformas .NET, incluindo o Xamarin e o
.NET Core. Crie uma única biblioteca de .NET Standard e use-a de qualquer tempo de execução que ofereça
suporte à plataforma .NET Standard. Consulte este gráfico para obter detalhes das plataformas com suporte.
Embora .NET Standard versões 1,0 a 1,6 forneçam subconjuntos incrementalmente maiores do .NET Framework,
.NET Standard 2,0 fornece o melhor nível de suporte para aplicativos Xamarin e para portar bibliotecas de
classes portáteis existentes.
Visual Studio para Mac
Visual Studio

Visual Studio para Mac


Esta seção explica como criar e usar uma biblioteca de .NET Standard usando Visual Studio para Mac.
Criando uma biblioteca de .NET Standard
Você pode adicionar uma biblioteca de .NET Standard à sua solução com estas etapas:
1. Na caixa de diálogo Adicionar novo projeto , selecione a categoria .NET Core e, em seguida, selecione
.net Standard biblioteca :

2. Na próxima tela, escolha o Framework de destino- .NET Standard 2,0 é recomendado:


3. Na tela final, digite o nome do projeto e clique em criar .
4. O projeto de biblioteca .NET Standard aparecerá conforme mostrado na Gerenciador de Soluções. O nó
de dependências indicará que a biblioteca usa o netstandard. library.

Editando .NET Standard configurações da biblioteca


As configurações da biblioteca .NET Standard podem ser exibidas e alteradas clicando com o botão direito do
mouse no projeto e selecionando Options conforme mostrado nesta captura de tela:
Dentro de você, você pode alterar sua versão do netstandard alterando o Target Framework valor da lista
suspensa.
Além disso: Você pode editar o .csproj diretamente para alterar esse valor.

.NET Standard e Xamarin. Forms para o desenvolvedor do .NET (vídeo)

Links Relacionados
.Net Standard -informações detalhadas e comparação com o PCL.
Compartilhamento de código de projetos
compartilhados
02/11/2020 • 12 minutes to read • Edit Online

Projetos compartilhados permitem que você escreva código comum que é referenciado por vários projetos de
aplicativo diferentes. O código é compilado como parte de cada projeto de referência e pode incluir diretivas de
compilador para ajudar a incorporar a funcionalidade específica da plataforma à base de código compartilhada.
Projetos compartilhados (às vezes chamados de projetos de ativos compartilhados) permitem que você escreva
o código que é compartilhado entre vários projetos de destino, incluindo aplicativos Xamarin.
Eles dão suporte a diretivas de compilador para que você possa incluir condicionalmente o código específico da
plataforma a ser compilado em um subconjunto dos projetos que fazem referência ao projeto compartilhado.
Também há suporte para IDE para ajudar a gerenciar as diretivas do compilador e visualizar como o código será
examinado em cada aplicativo.
Se você usou a vinculação de arquivos no passado para compartilhar código entre projetos, projetos
compartilhados funciona de forma semelhante, mas com suporte a IDE muito aprimorado.

O que é um projeto compartilhado?


Ao contrário da maioria dos outros tipos de projeto, um projeto compartilhado não tem nenhuma saída (no
formato de DLL), em vez disso, o código é compilado em cada projeto que faz referência a ele. Isso é ilustrado
no diagrama abaixo – conceitualmente, todo o conteúdo do projeto compartilhado é "copiado para" cada
projeto de referência e compilado como se fosse parte dele.

O código em um projeto compartilhado pode conter diretivas de compilador que habilitarão ou desabilitarão
seções de código, dependendo de qual projeto de aplicativo está usando o código, que é sugerido pelas caixas
de plataforma colorida no diagrama.
Um projeto compartilhado não é compilado por conta própria, ele existe puramente como um agrupamento de
arquivos de código-fonte que podem ser incluídos em outros projetos. Quando referenciado por outro projeto,
o código é efetivamente compilado como parte desse projeto. Projetos compartilhados não podem fazer
referência a nenhum outro tipo de projeto (incluindo outros projetos compartilhados).
Observe que os projetos de aplicativo Android não podem fazer referência a outros projetos de aplicativo
Android, por exemplo, um projeto de teste de unidade Android não pode fazer referência a um projeto de
aplicativo Android. Para obter mais informações sobre essa limitação, consulte esta discussão sobre o Fórum.
Visual Studio para Mac
Visual Studio

Passo a passo do Visual Studio para Mac


Esta seção explica como criar e usar um projeto compartilhado usando Visual Studio para Mac. Consulte a seção
exemplo de projeto compartilhado para obter um exemplo completo.

Criando um projeto compartilhado


Para criar um novo projeto compartilhado, navegue até arquivo > nova solução... (ou clique com o botão
direito do mouse em uma solução existente e escolha Adicionar > adicionar novo projeto...):

Na próxima tela, escolha o nome do projeto e clique em criar .


Um novo projeto compartilhado é mostrado abaixo-Observe que não há referências ou nós de componentes;
Eles não têm suporte para projetos compartilhados.

Para que um projeto compartilhado seja útil, ele precisa ser referenciado por pelo menos um projeto que possa
ser compilado (como um aplicativo ou uma biblioteca do iOS ou Android, ou um projeto PCL). Um projeto
compartilhado não é compilado quando não tem nada fazendo referência a ele; portanto, a sintaxe (ou qualquer
outro) erros não será realçada até que tenha sido referenciada por outra coisa.
A adição de uma referência a um projeto compartilhado é feita da mesma forma que faz referência a um projeto
de biblioteca regular. Esta captura de tela mostra um projeto Xamarin. iOS que faz referência a um projeto
compartilhado.
Depois que o projeto compartilhado é referenciado por outra biblioteca ou aplicativo, você pode criar a solução
e exibir todos os erros no código. Quando o projeto compartilhado é referenciado por dois ou mais projetos,
um menu é exibido no canto superior esquerdo do editor de código-fonte, que mostra quais projetos fazem
referência a esse arquivo.

Opções de projeto compartilhado


Quando você clica com o botão direito do mouse em um projeto compartilhado e escolhe Opções , há menos
configurações do que outros tipos de projeto. Como os projetos compartilhados não são compilados (por conta
própria), você não pode definir opções de saída ou de compilador, configurações de projeto, assinatura de
assembly ou comandos personalizados. O código em um projeto compartilhado efetivamente herda esses
valores de qualquer um que faça referência a eles.
A tela de Opções é mostrada abaixo-o nome do projeto e o namespace padrão são as duas únicas
configurações que geralmente serão alteradas.

Exemplo de projeto compartilhado


O exemplo de tarefa usa um projeto compartilhado para conter o código comum usado pelos aplicativos Ios,
Android e Windows Phone. Os SQLite.cs arquivos de TaskRepository.cs código-fonte e as diretivas de
compilador Utilise (por exemplo, #if __ANDROID__ ) para produzir uma saída diferente para cada um dos
aplicativos que fazem referência a eles.
A estrutura de solução completa é mostrada abaixo (no Visual Studio para Mac e no Visual Studio,
respectivamente):
Visual Studio para Mac
Visual Studio

O projeto Windows Phone pode ser navegado em Visual Studio para Mac, mesmo que esse tipo de projeto não
tenha suporte para compilação no Visual Studio para Mac.
Os aplicativos em execução são mostrados abaixo:
Resumo
Este documento descreveu como funcionam os projetos compartilhados, como eles podem ser criados e usados
tanto no Visual Studio para Mac quanto no Visual Studio, e introduzimos um aplicativo de exemplo simples que
demonstra um projeto compartilhado em ação.

Links Relacionados
Aplicativo de exemplo de tarefa
Bibliotecas de classes portáteis (exemplo)
Opções de código de compartilhamento (exemplo)
PCL (Bibliotecas de classe portáteis)
02/11/2020 • 23 minutes to read • Edit Online

TIP
As PCLs (bibliotecas de classes portáteis) são consideradas preteridas nas versões mais recentes do Visual Studio. Embora
você ainda possa abrir, editar e compilar PCLs, para novos projetos, é recomendável usar .net Standard bibliotecas para
acessar uma área de superfície de API maior.

Um componente fundamental da criação de aplicativos de plataforma cruzada é a capacidade de compartilhar


código em vários projetos específicos da plataforma. No entanto, isso é complicado pelo fato de que diferentes
plataformas geralmente usam um subconjunto diferente da BCL (base Class Library) do .NET e, portanto, são, na
verdade, compiladas em um perfil de biblioteca do .NET Core diferente. Isso significa que cada plataforma só
pode usar bibliotecas de classes destinadas ao mesmo perfil para que pareçam exigir projetos de biblioteca de
classes separados para cada plataforma.
Há três abordagens principais para o compartilhamento de código que abordam esse problema: projetos de
.net Standard , projetos de ativos compar tilhados e projetos PCL (biblioteca de classes por táteis) .
.Net Standard projetos são a abordagem preferida para compartilhar código .net, leia mais sobre .net
Standard projetos e Xamarin.
Os projetos de ativos compar tilhados usam um único conjunto de arquivos e oferecem uma maneira
rápida e simples de compartilhar código em uma solução e geralmente emprega diretivas de compilação
condicional para especificar caminhos de código para várias plataformas que o usarão (para obter mais
informações, consulte o artigo projetos compartilhados).
Os projetos PCL visam perfis específicos que dão suporte a um conjunto conhecido de classes/recursos de
BCL. No entanto, o lado para o PCL é que eles geralmente exigem um esforço de arquitetura extra para
separar o código específico do perfil em suas próprias bibliotecas.
Esta página explica como criar um projeto PCL que tem como alvo um perfil específico, que pode ser
referenciado por vários projetos específicos da plataforma.

O que é uma biblioteca de classes portátil?


Quando você cria um projeto de aplicativo ou um projeto de biblioteca, a DLL resultante é restrita ao trabalho
na plataforma específica para a qual é criada. Isso impede que você grave um assembly para um aplicativo do
Windows e, em seguida, reutilize-o em Xamarin. iOS e Xamarin. Android.
No entanto, quando você cria uma biblioteca de classes portátil, pode escolher uma combinação de plataformas
nas quais você deseja que seu código seja executado. As opções de compatibilidade que você faz ao criar uma
biblioteca de classes portátil são convertidas em um identificador de "perfil", que descreve as plataformas às
quais a biblioteca dá suporte.
A tabela a seguir mostra alguns dos recursos que variam de acordo com a plataforma .NET. Para gravar um
assembly PCL com garantia de execução em dispositivos/plataformas específicas, você simplesmente escolhe
qual suporte é necessário ao criar o projeto.
. N ET A P L IC AT IVO S W IN DO W S
REC URSO F RA M EW O RK UW P SILVERL IGH T PH ONE XA M A RIN

Núcleo S S S S S

LINQ S S S S S

IQueryable S S S 7,5 + S

Serialização S S S S S

Anotações de 4.0.3 + S S S
dados

A coluna Xamarin reflete o fato de que o Xamarin. iOS e o Xamarin. Android dão suporte a todos os perfis
fornecidos com o Visual Studio, e a disponibilidade dos recursos em qualquer biblioteca que você criar será
limitada somente pelas outras plataformas que você escolher para dar suporte.
Isso inclui perfis que são combinações de:
.NET 4 ou .NET 4,5
Silverlight 5
Windows Phone 8
Aplicativos UWP
Você pode ler mais sobre os recursos de perfis diferentes no site da Microsoft e ver o Resumo do perfil PCL de
outro membro da Comunidade, que inclui informações de estrutura com suporte e outras observações.
Benefícios
1. Compartilhamento de código centralizado – escrever e testar código em um único projeto que pode ser
consumido por outras bibliotecas ou aplicativos.
2. As operações de refatoração afetarão todo o código carregado na solução (a biblioteca de classes portátil e
os projetos específicos da plataforma).
3. O projeto PCL pode ser facilmente referenciado por outros projetos em uma solução, ou o assembly de saída
pode ser compartilhado para que outras pessoas façam referência em suas soluções.
Desvantagens
1. Como a mesma biblioteca de classes portátil é compartilhada entre vários aplicativos, bibliotecas específicas
de plataforma não podem ser referenciadas (por exemplo, Community. CsharpSqlite. WP7).
2. O subconjunto da biblioteca de classes portátil pode não incluir classes que, de outra forma, estarão
disponíveis tanto em MonoTouch quanto em mono para Android (como DllImport ou System. IO. File).

NOTE
As bibliotecas de classes portáteis foram preteridas na versão mais recente do Visual Studio e, em vez disso, as bibliotecas
de .net Standard são recomendadas.

Até certo ponto, ambas as desvantagens podem ser burladas usando o padrão do provedor ou injeção de
dependência para codificar a implementação real nos projetos da plataforma em relação a uma interface ou
classe base que é definida na biblioteca de classes portátil.
Este diagrama mostra a arquitetura de um aplicativo de plataforma cruzada usando uma biblioteca de classes
portátil para compartilhar código, mas também usando injeção de dependência para transmitir recursos
dependentes da plataforma:

Visual Studio para Mac


Visual Studio

Instruções Visual Studio para Mac


Esta seção explica como criar e usar uma biblioteca de classes portátil usando Visual Studio para Mac. Consulte
a seção exemplo de PCL para obter uma implementação completa.
Criando um PCL
Adicionar uma biblioteca de classes portátil à sua solução é muito semelhante a adicionar um projeto de
biblioteca regular.
1. Na caixa de diálogo novo projeto , selecione a opção biblioteca de > multiplataforma > a biblioteca
por tátil :
2. Quando um PCL é criado no Visual Studio para Mac ele é configurado automaticamente com um perfil
que funciona para Xamarin. iOS e Xamarin. Android. O projeto PCL será exibido conforme mostrado
nesta captura de tela:

A PCL agora está pronta para que o código seja adicionado. Ele também pode ser referenciado por outros
projetos (projetos de aplicativo, projetos de biblioteca e até mesmo outros projetos PCL).
Editando configurações de PCL
Para exibir e alterar as configurações de PCL para este projeto, clique com o botão direito do mouse no projeto e
escolha opções > compilação > geral para ver a tela mostrada aqui:

Clique em alterar... para alterar o perfil de destino para esta biblioteca de classes portátil.
Se o perfil for alterado depois que o código já tiver sido adicionado ao PCL, é possível que a biblioteca não seja
mais compilada se o código fizer referência a recursos que não fazem parte do perfil selecionado recentemente.
Trabalhando com um PCL
Quando o código é escrito em uma biblioteca PCL, o editor de Visual Studio para Mac reconhecerá as limitações
do perfil selecionado e ajustará adequadamente as opções de preenchimento automático. Por exemplo, esta
captura de tela mostra as opções de preenchimento automático para System.IO usando o perfil padrão
(Profile136) usado em Visual Studio para Mac – Observe que a barra de rolagem que indica cerca de metade
das classes disponíveis é exibida (na verdade, há apenas 14 classes disponíveis).

Compare isso com a conclusão automática de System.IO em um projeto Xamarin. iOS ou Xamarin. Android – há
40 classes disponíveis, incluindo classes comumente usadas, como File e Directory que não estão em
nenhum perfil PCL.

Isso reflete a compensação subjacente de usar PCL – a capacidade de compartilhar código diretamente em
várias plataformas significa que determinadas APIs não estão disponíveis para você porque não têm
implementações comparáveis em todas as plataformas possíveis.
Usando PCL
Depois que um projeto PCL tiver sido criado, você poderá adicionar uma referência a ele de qualquer aplicativo
compatível ou projeto de biblioteca da mesma maneira que normalmente adiciona referências. Em Visual Studio
para Mac, clique com o botão direito do mouse no nó referências e escolha Editar referências... em seguida,
alterne para a guia projetos , conforme mostrado:
A captura de tela a seguir mostra o painel de solução para o aplicativo de exemplo TaskyPortable, mostrando a
biblioteca PCL na parte inferior e uma referência a essa biblioteca PCL no projeto Xamarin. iOS.

A saída de uma PCL (por ex., a DLL do assembly resultante) também pode ser adicionada como uma referência à
maioria dos projetos. Isso torna o PCL uma maneira ideal de fornecer componentes e bibliotecas entre
plataformas.

Exemplo de PCL
O aplicativo de exemplo TaskyPortable demonstra como uma biblioteca de classes portátil pode ser usada com
o Xamarin. Aqui estão algumas capturas de tela dos aplicativos resultantes em execução no iOS e no Android:

Ele compartilha vários dados e classes lógicas que são puramente códigos portáteis e também demonstra como
incorporar requisitos específicos da plataforma usando injeção de dependência para a implementação do banco
de dados SQLite.
A estrutura da solução é mostrada abaixo (no Visual Studio para Mac e no Visual Studio, respectivamente):
Como o código SQLite-NET tem partes específicas da plataforma (para trabalhar com as implementações do
SQLite em cada sistema operacional diferente) para fins de demonstração, ele foi refatorado em uma classe
abstrata que pode ser compilada em uma biblioteca de classes portátil e o código real implementado como
subclasses nos projetos iOS e Android.
TaskyPortableLibrary
A biblioteca de classes portátil é limitada aos recursos do .NET aos quais ele pode dar suporte. Como ele é
compilado para ser executado em várias plataformas, ele não pode fazer uso da [DllImport] funcionalidade
que é usada no SQLite-net. Em vez disso, o SQLite-NET é implementado como uma classe abstrata e, em
seguida, referenciado por meio do restante do código compartilhado. Uma extração da API abstrata é mostrada
abaixo:
public abstract class SQLiteConnection : IDisposable {

public string DatabasePath { get; private set; }


public bool TimeExecution { get; set; }
public bool Trace { get; set; }
public SQLiteConnection(string databasePath) {
DatabasePath = databasePath;
}
public abstract int CreateTable<T>();
public abstract SQLiteCommand CreateCommand(string cmdText, params object[] ps);
public abstract int Execute(string query, params object[] args);
public abstract List<T> Query<T>(string query, params object[] args) where T : new();
public abstract TableQuery<T> Table<T>() where T : new();
public abstract T Get<T>(object pk) where T : new();
public bool IsInTransaction { get; protected set; }
public abstract void BeginTransaction();
public abstract void Rollback();
public abstract void Commit();
public abstract void RunInTransaction(Action action);
public abstract int Insert(object obj);
public abstract int Update(object obj);
public abstract int Delete<T>(T obj);

public void Dispose()


{
Close();
}
public abstract void Close();

O restante do código compartilhado usa a classe abstrata para "armazenar" e "recuperar" objetos do banco de
dados. Em qualquer aplicativo que usa essa classe abstrata, devemos passar uma implementação completa que
fornece a funcionalidade real do banco de dados.
TaskyAndroid e TaskyiOS
Os projetos de aplicativos iOS e Android contêm a interface do usuário e outros códigos específicos da
plataforma usados para conectar o código compartilhado no PCL.
Esses projetos também contêm uma implementação da API de banco de dados abstrata que funciona nessa
plataforma. No iOS e Android, o mecanismo de banco de dados SQLite é integrado ao sistema operacional, de
modo que a implementação pode usar [DllImport] conforme mostrado para fornecer a implementação
concreta da conectividade de banco de dados. Um trecho do código de implementação específico da plataforma
é mostrado aqui:

[DllImport("sqlite3", EntryPoint = "sqlite3_open")]


public static extern Result Open(string filename, out IntPtr db);

[DllImport("sqlite3", EntryPoint = "sqlite3_close")]


public static extern Result Close(IntPtr db);

A implementação completa pode ser vista no código de exemplo.

Resumo
Este artigo abordou brevemente os benefícios e as armadilhas das bibliotecas de classes portáteis, demonstrou
como criar e consumir PCLs de dentro Visual Studio para Mac e Visual Studio; e, finalmente, introduziu um
aplicativo de exemplo completo – TaskyPortable – que mostra uma PCL em ação.
Links relacionados
TaskyPortable (exemplo)
Compilar aplicativos de plataforma cruzada
Visual Basic portátil
Projetos compartilhados
Opções de código de compartilhamento
Desenvolvimento de plataforma cruzada com o .NET Framework (Microsoft)
Projetos de biblioteca multiplataforma do NuGet
(Nugetizer 3000)
02/11/2020 • 3 minutes to read • Edit Online

Crie pacotes NuGet automaticamente para compartilhar código entre plataformas usando o ' Nugetizer 3000 '!
É possível criar automaticamente pacotes NuGet para compartilhar código entre plataformas usando o
Nugetizer 3000. Isso torna possível criar pacotes NuGet a partir de projetos de biblioteca existentes ou criando
um novo projeto de biblioteca multiplataforma .
Visual Studio para Mac
Visual Studio
O Nugetizer 3000 está incluído com Visual Studio para Mac – procurar a biblioteca > tipo de projeto de
biblioteca Mulitplatform no arquivo > nova janela:

Criando pacotes NuGet


Uma vez configurado, cada compilação do projeto gera um pacote NuGet completo, que pode ser usado para
compartilhar código internamente com outros aplicativos ou carregado no NuGet.org.
Há três cenários para usar esse recurso:
Projetos de biblioteca existentes
Crie um pacote NuGet a partir de projetos PCL (ou .NET Standard) existentes.
Criando um novo projeto de biblioteca multiplataforma
Crie uma nova biblioteca para compartilhar código comum por meio do NuGet usando um PCL ou .NET
Standard.
Criando novos projetos de biblioteca específicos da plataforma
Crie uma nova biblioteca e NuGet que inclua o código específico da plataforma para iOS e Android e use
um projeto compartilhado para conter o código comum e os projetos específicos da plataforma para dar
suporte à funcionalidade específica para iOS ou Android.
Consulte o Guia de metadados para obter detalhes sobre os metadados necessários e opcionais que devem ser
adicionados a qualquer pacote NuGet.

Informações adicionais do NuGet


Leia mais sobre como criar manualmente o NuGets para Xamarin e como incluir um pacote NuGet em um
aplicativo.
A documentação do NuGet da Microsoft contém informações mais detalhadas sobre o formato . nupkg e o uso
de pacotes NuGet no Visual Studio.
A discussão de design para projetos de pacote NuGet (também conhecido como NuGetizer 3000) está
disponível no repositório GitHub do NuGet.

Links Relacionados
Casos de uso de NuGetizer-3000
Criar manualmente pacotes NuGet para o Xamarin
Documentação do NuGet
Criando um NuGet de projetos de biblioteca
existentes
02/11/2020 • 2 minutes to read • Edit Online

As bibliotecas PCL ou .NET Standard existentes podem ser transformadas em NuGets por meio da janela
Opções do projeto :
1. Clique com o botão direito do mouse no projeto de biblioteca no painel de soluções e escolha
Opções .
2. Vá para a seção pacote NuGet > metadados e insira todas as informações necessárias na guia geral :

3. Opcionalmente, Adicione metadados adicionais na guia detalhes .


4. Depois que os metadados são configurados, você pode clicar com o botão direito do mouse no projeto e
escolher criar pacote NuGet e o arquivo de pacote NuGet . nupkg será salvo na pasta /bin/ (debug ou
Release, dependendo da configuração).

5. Para criar o pacote NuGet em cada compilação ou implantação, vá para o pacote NuGet > seção de
compilação e tique criar um pacote NuGet ao compilar o projeto :

NOTE
A criação do pacote NuGet pode retardar o processo de compilação. Se essa caixa não estiver marcada, você ainda poderá
gerar um pacote NuGet manualmente a qualquer momento no menu de contexto do projeto (mostrado na etapa 4
acima).

Verificando a saída
Os pacotes NuGet também são arquivos ZIP, portanto, é possível inspecionar a estrutura interna do pacote
gerado.
Esta captura de tela mostra o conteúdo de um NuGet baseado em PCL – apenas um único assembly PCL está
incluído:

Links Relacionados
Guia de metadados
Criando uma nova biblioteca multiplataforma para
NuGet
02/11/2020 • 4 minutes to read • Edit Online

Criar um projeto de biblioteca multiplataforma que usa PCL ou .NET Standard significa que o NuGet resultante
pode ser adicionado a qualquer projeto .NET que ofereça suporte ao perfil de destino, incluindo projetos
ASP.NET ou aplicativos de área de trabalho usando WinForms, WPF ou UWP.
A biblioteca pode conter apenas o código suportado pelo perfil PCL ou .NET Standard selecionado, bem como
qualquer outro NuGets que seja adicionado. Isso é adequado à lógica de negócios e aos algoritmos que podem
ser expressos inteiramente na biblioteca de classes base do .NET.
Um único assembly é criado e compilado em um pacote NuGet.
Se você precisar mais tarde da funcionalidade específica da plataforma, os projetos específicos da plataforma
poderão ser adicionados.

Etapas para criar um NuGet de biblioteca multiplataforma


1. Selecione arquivo > nova solução (ou clique com o botão direito do mouse em uma solução existente
e escolha Adicionar > novo projeto ).
2. Escolha biblioteca multiplataforma na seção biblioteca de > de várias plataformas :

3. Insira um nome e uma Descrição e escolha único para todas as plataformas :

4. Conclua o assistente. Um único projeto de biblioteca é criado na solução.


5. Clique com o botão direito do mouse no novo projeto de biblioteca e selecione Opções . A seção Build >
geral permite que a estrutura de destino seja definida – escolha um perfil PCL portátil do .net ou uma
versão .net Standard:
6. Também na janela Opções do projeto , abra a seção de metadados > pacote NuGet e insira os
metadados necessários (bem como os metadados opcionais):

7. Clique com o botão direito do mouse no projeto de biblioteca e escolha criar pacote NuGet (ou
compilar ou implantar a solução) e o arquivo de pacote NuGet . nupkg será salvo na pasta /bin/ (debug
ou Release, dependendo da configuração):

Verificando a saída
Os pacotes NuGet também são arquivos ZIP, portanto, é possível inspecionar a estrutura interna do pacote
gerado.
Esta captura de tela mostra o conteúdo de um NuGet baseado em PCL – apenas um único assembly PCL está
incluído:
Adicionando código específico da plataforma
Projetos baseados em PCL e projetos baseados em .NET Standard não podem conter referências específicas à
plataforma (como a funcionalidade iOS ou Android).
Se um projeto PCL ou .NET Standard projeto existente precisar ser expandido para incluir o código específico da
plataforma, isso poderá ser feito clicando com o botão direito do mouse no projeto e selecionando adicionar >
adicionar a implementação da plataforma...:

Um ou mais projetos de plataforma podem ser adicionados à solução, e a biblioteca PCL ou .NET Standard
existente pode, opcionalmente, ser convertida em um projeto compartilhado:

Depois de converter para um projeto compartilhado, visite a seção Opções do projeto > pacote NuGet >
assemblies de referência section e verifique se todos os perfis necessários estão selecionados (para que o
NuGet continue a ser compatível com os projetos em que ele foi usado anteriormente).

Links Relacionados
Guia de metadados
Criando novos projetos de biblioteca específicos da
plataforma para NuGet
02/11/2020 • 4 minutes to read • Edit Online

Os projetos de biblioteca multiplataforma que visam plataformas específicas, como iOS e Android, funcionam
melhor com projetos compartilhados.
O NuGet pode conter código específico para iOS e Android, bem como o código .NET comum para ambos.
Vários assemblies são criados e incorporados em um único pacote NuGet. Os padrões do NuGet garantem que
o pacote possa ser adicionado a todos os tipos de projeto com suporte, como o Xamarin. iOS e os projetos
Android.

Etapas para criar um NuGet de biblioteca de plataforma cruzada


1. Selecione arquivo > nova solução (ou clique com o botão direito do mouse em uma solução existente
e escolha Adicionar > novo projeto ).
2. Escolha biblioteca multiplataforma na seção biblioteca de > de várias plataformas :

3. Insira um nome e uma Descrição e escolha a plataforma específica :

4. Conclua o assistente. Os projetos a seguir são adicionados à solução:


Projeto Android – o código específico do Android pode, opcionalmente, ser adicionado a este
projeto.
projeto do IOS – o código específico do IOS pode opcionalmente ser adicionado a este projeto.
Projeto NuGet – nenhum código é adicionado a este projeto. Ele faz referência a outros projetos e
contém a configuração de metadados para a saída do pacote NuGet.
Projeto compar tilhado – o código comum deve ser adicionado a este projeto, incluindo o código
específico da plataforma dentro de #if diretivas do compilador.
5. Clique com o botão direito do mouse no projeto NuGet e escolha Opções e abra a seção pacote NuGet
> metadados e insira os metadados necessários (bem como quaisquer metadados opcionais):

6. Também na janela Opções do projeto , abra a seção assemblies de referência e escolha a quais
perfis PCL a biblioteca compartilhada dará suporte por meio de "Bait e switch":

NOTE
"Bait e switch" significa que os assemblies PCL conterão apenas a API exposta pela biblioteca (ele não pode conter
o código específico da plataforma). Quando o NuGet é adicionado a um projeto Xamarin, as bibliotecas
compartilhadas serão compiladas no PCL, mas os assemblies específicos da plataforma conterão o código que é
realmente usado pelo projeto iOS ou Android.

7. Clique com o botão direito do mouse no projeto e escolha criar pacote NuGet (ou compilar ou
implantar a solução) e o arquivo de pacote NuGet . nupkg será salvo na pasta /bin/ (debug ou Release,
dependendo da configuração).
Verificando a saída
Os pacotes NuGet também são arquivos ZIP, portanto, é possível inspecionar a estrutura interna do pacote
gerado.
Esta captura de tela mostra o conteúdo de um NuGet específico da plataforma que dá suporte a iOS e Android e
tinha dois assemblies de referência selecionados:

Links Relacionados
Guia de metadados
Editando metadados do NuGet
02/11/2020 • 3 minutes to read • Edit Online

Usar as opções de projeto para editar metadados do NuGet para bibliotecas multiplataforma
Tipos de projeto de biblioteca (como PCL ou .NET Standard ou o novo tipo de projeto NuGet) têm uma seção
pacote NuGet na janela Opções do projeto .
A seção de metadados configura os valores usados no arquivo de manifesto do pacote NuGet . nuspec .

Informações necessárias
A guia geral contém quatro campos que devem ser inseridos para gerar um pacote NuGet:

ID – o identificador do pacote, que deve ser exclusivo no NuGet.org (ou onde quer que o pacote seja
distribuído). Siga este guia e use apenas caracteres que sejam válidos em uma URL (sem espaços e evite a
maioria dos caracteres especiais).
Versão – escolha um número de versão consistente com as regras de controle de versão do NuGet.
Autores – lista de nomes separados por vírgulas.
Descrição – visão geral dos recursos do pacote que são exibidos quando os usuários estão selecionando o
pacote.

NOTE
Lembre-se de incrementar o número de versão ao criar novas versões para distribuição para o NuGet ou outros usuários.

Para obter mais informações, consulte a referência de elementos necessários para obter mais informações, bem
como essas instruções detalhadas sobre como escolher um identificador de pacote exclusivo e definir o número
de versão e definir um tipo de pacote.

IMPORTANT
Todos os campos nessa guia devem ser inseridos; caso contrário, uma mensagem de erro será exibida: "o projeto não tem
metadados NuGet, portanto, um pacote NuGet não será criado. Os metadados do pacote NuGet podem ser especificados
na seção de metadados em opções do projeto "

Metadados opcionais
A guia detalhes contém campos opcionais a serem incluídos no arquivo de manifesto do pacote NuGet.
Consulte a referência de elementos opcionais para obter mais informações sobre os campos obrigatórios e
opcionais.

NOTE
Se o pacote NuGet estiver sendo distribuído no NuGet.org , é recomendável fornecer o máximo possível de informações.

Links Relacionados
Referência de. nuspec
Criando manualmente pacotes NuGet para o
Xamarin
02/11/2020 • 5 minutes to read • Edit Online

Esta página contém algumas dicas para ajudar a criar pacotes NuGet direcionados para a plataforma Xamarin.

NOTE
Xamarin Studio 6,2 (e Visual Studio para Mac) inclui a capacidade de gerar automaticamente pacotes do NuGet por meio
de projetos PCL, .net Standard ou compartilhados. Consulte o guia de compartilhamento de bibliotecas multiplataforma
para o código para obter mais detalhes.

Perfis do Xamarin Package do NuGet


O suporte do site do NuGet para várias versões e perfis de .NET Framework discute como dar suporte a
diferentes estruturas e perfis da Microsoft, mas não inclui os nomes de estrutura de destino usados pelo
Xamarin.
As principais estruturas de destino do Xamarin em uso hoje são:
Monoandroid -Xamarin. Android
Xamarin. Ios -Xamarin. Ios API unificada (dá suporte a 64 bits)
Xamarin. Mac – o perfil móvel do Xamarin. Mac, que é equivalente à superfície da API do Xamarin. Ios e
Xamarin. Android.
Também há um destino para o API clássicado Ios mais antigo:
API Clássica do MonoTouch – Ios
Um arquivo . nuspec direcionado a todos eles teria uma aparência semelhante a:

<files>
<file src="Mac\bin\Release\*.dll" target="lib\Xamarin.Mac20" />
<file src="iOS\bin\Release\*.dll" target="lib\Xamarin.iOS10" />
<file src="Android\bin\Release\*.dll" target="lib\MonoAndroid10" />
<file src="iOSClassic\bin\Release\*.dll" target="lib\MonoTouch10" />
</files>

O acima ignora todas as bibliotecas de classes portáteis.


Os arquivos mais . nuspec especificam o número de versão da estrutura de destino, mas é opcional se o
assembly funcionar com todas as versões da estrutura de destino. Portanto, se o seu destino foi
lib\MonoAndroid isso significa que ele funciona com qualquer versão do Xamarin. Android.
Você pode especificar a versão com um conjunto de números sem um ponto decimal ou pode especificá-la
usando pontos decimais. Sem o ponto decimal, o NuGet simplesmente pegará cada número e o transformará
em uma versão inserindo um '. ' entre cada dígito.
Na acima, "MonoAndroid10" significa "Android 1,0". Isso apenas significa que a estrutura de destino do projeto
precisa ser o monoandroid versão 1,0 ou superior. A versão é especificada no <TargetFrameworkVersion>
elemento no arquivo de projeto.
Para esclarecer:
MonoAndroid403 corresponde ao Android 4.0.3 e mais recente (API do IE nível 15)
O xamarin. iOS10 corresponde ao Xamarin. Ios 1,0 e mais recente
O xamarin. Ios 1.0 também corresponde ao Xamarin. Ios 1,0 e mais recente

NuGets PCL com dependências de plataforma


Os perfis PCL são limitados em quais APIs do .NET Framework eles podem acessar e certamente não podem
acessar o código específico da plataforma. Esses links de terceiros abordam abordagens diferentes para a
criação de pacotes NuGet que usam o PCL e APIs nativas para fornecer compatibilidade com o Xamarin e outras
plataformas:
Como tornar as bibliotecas de classes portáteis funcionam para você
O truque Bait e switch PCL
Criando uma PCL do NuGet que funciona com o Xamarin. iOS
Essa lista externa de perfis PCL com o nome de destino do NuGet também é uma referência útil.

Exemplos
Alguns exemplos de código-fonte aberto para os quais você pode se referir:
ModernHttpClient – escreva seu aplicativo usando System .net. http, mas remova essa biblioteca no e ela
será drasticamente mais rápida (Exibir fonte).
Fragmentação – uma biblioteca para tornar as coisas entre plataformas que devem ser (Exibir fonte).
NGraphics -uma biblioteca de plataforma cruzada para renderizar gráficos vetoriais no .net (Exibir fonte).

Links Relacionados
Criação automatizada de NuGet Nugetizer-3000
Incluindo um NuGet em seu projeto
Usar bibliotecas C/C++ com o Xamarin
02/11/2020 • 42 minutes to read • Edit Online

Visão geral
O Xamarin permite que os desenvolvedores criem aplicativos móveis nativos de plataforma cruzada com o
Visual Studio. Em geral, as associações do C# são usadas para expor componentes de plataforma existentes aos
desenvolvedores. No entanto, há ocasiões em que os aplicativos Xamarin precisam trabalhar com bases de
código existentes. Às vezes, as equipes simplesmente não têm tempo, orçamento ou recursos para portar uma
base de código grande, bem testada e altamente otimizada para C#.
Visual C++ para o desenvolvimento móvel de plataforma cruzada permite que o código C/C++ e C# seja criado
como parte da mesma solução, oferecendo muitas vantagens, incluindo uma experiência de depuração
unificada. A Microsoft usou o C/C++ e o Xamarin desta forma para fornecer aplicativos, como hiperlapsar
câmera móvel e PIX.
No entanto, em alguns casos, há um desejo (ou requisito) para manter as ferramentas e os processos existentes
do C/C++ em vigor e manter o código da biblioteca dissociado do aplicativo, tratando a biblioteca como se
fosse semelhante a um componente de terceiros. Nessas situações, o desafio não está apenas expondo os
membros relevantes para o C#, mas Gerenciando a biblioteca como uma dependência. E, é claro, automatizar o
máximo possível do processo.
Esta postagem descreve uma abordagem de alto nível para esse cenário e percorre um exemplo simples.

Segundo plano
O c/C++ é considerado uma linguagem de plataforma cruzada, mas deve-se tomar muito cuidado para garantir
que o código-fonte seja realmente entre plataformas, usando apenas o C/C++ com suporte de todos os
compiladores de destino e que contenham pouca ou nenhuma plataforma ou código específico do compilador.
Em última análise, o código deve ser compilado e executado com êxito em todas as plataformas de destino,
portanto, isso se resume à semelhança entre as plataformas (e os compiladores) que estão sendo direcionados.
Os problemas ainda podem surgir de pequenas diferenças entre compiladores e, portanto, testes completos
(preferencialmente automatizado) em cada plataforma de destino se tornam cada vez mais importantes.

Abordagem de alto nível


A ilustração a seguir representa a abordagem de quatro estágios usada para transformar o código-fonte C/C++
em uma biblioteca Xamarin de plataforma cruzada que é compartilhada via NuGet e, em seguida, é consumida
em um aplicativo Xamarin. Forms.
Os quatro estágios são:
1. Compilando o código-fonte C/C++ em bibliotecas nativas específicas da plataforma.
2. Encapsulando as bibliotecas nativas com uma solução do Visual Studio.
3. Empacotando e enviando por push um pacote NuGet para o wrapper .NET.
4. Consumindo o pacote NuGet de um aplicativo Xamarin.
Estágio 1: Compilando o código -fonte C/C++ em bibliotecas nativas específicas da plataforma
O objetivo deste estágio é criar bibliotecas nativas que podem ser chamadas pelo wrapper do C#. Isso pode ou
não ser relevante, dependendo da sua situação. As várias ferramentas e processos que podem ser trazidos neste
cenário comum estão além do escopo deste artigo. As principais considerações são manter a base de código
C/C++ sincronizada com qualquer código wrapper nativo, teste de unidade suficiente e automação de
compilação.
As bibliotecas no passo a passo foram criadas usando Visual Studio Code com um script de shell que o
acompanha. Uma versão estendida desse passo a passo pode ser encontrada no repositório GitHub de Cat
móvel que aborda essa parte do exemplo em maior profundidade. As bibliotecas nativas estão sendo tratadas
como uma dependência de terceiros nesse caso, no entanto, esse estágio é ilustrado para o contexto.
Para simplificar, a instrução tem como alvo apenas um subconjunto de arquiteturas. Para o iOS, ele usa o
utilitário lipo para criar um binário único de Fat a partir dos binários específicos da arquitetura individual. O
Android usará binários dinâmicos com um. portanto, a extensão e o iOS usarão um binário Fat estático com
uma extensão. a.
Etapa 2: encapsulando as bibliotecas nativas com uma solução do Visual Studio
O próximo estágio é encapsular as bibliotecas nativas para que elas sejam facilmente usadas no .NET. Isso é feito
com uma solução do Visual Studio com quatro projetos. Um projeto compartilhado contém o código comum.
Os projetos destinados a cada Xamarin. Android, Xamarin. iOS e .NET Standard permitem que a biblioteca seja
referenciada de maneira independente da plataforma.
O wrapper usa 'o Bait e o truque do comutador'. Essa não é a única maneira, mas facilita a referência à
biblioteca e evita a necessidade de gerenciar explicitamente as implementações específicas da plataforma no
próprio aplicativo de consumo. O truque é, essencialmente, garantir que os destinos (.NET Standard, Android,
iOS) compartilhem o mesmo namespace, nome do assembly e estrutura de classe. Como o NuGet sempre
prefere uma biblioteca específica da plataforma, a versão .NET Standard nunca é usada em tempo de execução.
A maior parte do trabalho nesta etapa se concentrará no uso de P/Invoke para chamar os métodos de biblioteca
nativos e gerenciar as referências aos objetos subjacentes. O objetivo é expor a funcionalidade da biblioteca
para o consumidor e, ao mesmo tempo, abstrair qualquer complexidade. Os desenvolvedores do Xamarin.
Forms não precisam ter conhecimento prático sobre o funcionamento interno da biblioteca não gerenciada.
Deve parecer que estão usando qualquer outra biblioteca C# gerenciada.
Por fim, a saída desse estágio é um conjunto de bibliotecas .NET, uma por destino, junto com um documento
nuspec que contém as informações necessárias para criar o pacote na próxima etapa.
Estágio 3: empacotando e enviando por push um pacote NuGet para o wrapper .NET
O terceiro estágio é criar um pacote NuGet usando os artefatos de compilação da etapa anterior. O resultado
desta etapa é um pacote NuGet que pode ser consumido de um aplicativo Xamarin. A instrução usa um
diretório local para servir como o feed do NuGet. Em produção, essa etapa deve publicar um pacote em um feed
do NuGet público ou privado e deve ser totalmente automatizada.
Estágio 4: consumindo o pacote NuGet de um aplicativo Xamarin. Forms
A etapa final é fazer referência e usar o pacote NuGet de um aplicativo Xamarin. Forms. Isso requer a
configuração do feed do NuGet no Visual Studio para usar o feed definido na etapa anterior.
Depois que o feed é configurado, o pacote precisa ser referenciado de cada projeto no aplicativo Xamarin.
Forms de plataforma cruzada. ' O truque bait-and-switch fornece interfaces idênticas, portanto, a funcionalidade
da biblioteca nativa pode ser chamada usando o código definido em um único local.
O repositório de código-fonte contém uma lista de leituras adicionais que inclui artigos sobre como configurar
um feed do NuGet privado no Azure DevOps e como enviar por push o pacote para esse feed. Embora exijam
um pouco mais de tempo de configuração do que um diretório local, esse tipo de feed é melhor em um
ambiente de desenvolvimento de equipe.

Passo a passo
As etapas fornecidas são específicas para Visual Studio para Mac , mas a estrutura funciona no Visual
Studio 2017 também.
Pré -requisitos
Para acompanhar, o desenvolvedor precisará de:
Linha de comando do NuGet (CLI)
Visual Studio para Mac

NOTE
Uma conta de desenvolvedor Apple ativa é necessária para implantar aplicativos em um iPhone.

Criando as bibliotecas nativas (estágio 1)


A funcionalidade da biblioteca nativa se baseia no exemplo de passo a passo: Criando e usando uma biblioteca
estática (C++).
Este passo a passos ignora o primeiro estágio, criando as bibliotecas nativas, pois a biblioteca é fornecida como
uma dependência de terceiros nesse cenário. As bibliotecas nativas pré-compiladas são incluídas juntamente
com o código de exemplo ou podem ser baixadas diretamente.
Trabalhando com a biblioteca nativa
O exemplo MathFuncsLib original inclui uma única classe chamada MyMathFuncs com a seguinte definição:
namespace MathFuncs
{
class MyMathFuncs
{
public:
double Add(double a, double b);
double Subtract(double a, double b);
double Multiply(double a, double b);
double Divide(double a, double b);
};
}

Uma classe adicional define funções de wrapper que permitem a um consumidor .NET criar, descartar e interagir
com a MyMathFuncs classe nativa subjacente.

#include "MyMathFuncs.h"
using namespace MathFuncs;

extern "C" {
MyMathFuncs* CreateMyMathFuncsClass();
void DisposeMyMathFuncsClass(MyMathFuncs* ptr);
double MyMathFuncsAdd(MyMathFuncs *ptr, double a, double b);
double MyMathFuncsSubtract(MyMathFuncs *ptr, double a, double b);
double MyMathFuncsMultiply(MyMathFuncs *ptr, double a, double b);
double MyMathFuncsDivide(MyMathFuncs *ptr, double a, double b);
}

Serão essas funções de invólucro que são usadas no lado do Xamarin .

Encapsulando a biblioteca nativa (estágio 2)


Este estágio requer as bibliotecas pré-compiladas descritas na seção anterior.
Criando a solução do Visual Studio
1. Em Visual Studio para Mac , clique em novo projeto (na página de boas-vindas ) ou em nova
solução (no menu arquivo ).
2. Na janela novo projeto , escolha projeto compar tilhado (de dentro da biblioteca de >
multiplataforma ) e clique em Avançar .
3. Atualize os campos a seguir e clique em criar :
Nome do projeto: MathFuncs. Shared
Nome da solução: MathFuncs
Local: Usar o local de salvamento padrão (ou escolher uma alternativa)
Crie um projeto dentro do diretório da solução: Defina esta opção como marcada
4. Em Gerenciador de soluções , clique duas vezes no projeto MathFuncs. Shared e navegue até
configurações principais .
5. Remover . Compar tilhado do namespace padrão para que ele seja definido somente como
MathFuncs e, em seguida, clique em OK .
6. Abra MyClass.cs (criado pelo modelo), em seguida, renomeie a classe e o nome de arquivo como
MyMathFuncsWrapper e altere o namespace para MathFuncs .
7. Controle + clique na solução MathFuncs , em seguida, escolha Adicionar novo projeto... no menu
Adicionar .
8. Na janela novo projeto , escolha .net Standard biblioteca (de dentro da biblioteca > multiplataforma
) e clique em Avançar .
9. Escolha .NET Standard 2,0 e clique em Avançar .
10. Atualize os campos a seguir e clique em criar :
Nome do projeto: MathFuncs. Standard
Local: Usar o mesmo local de salvamento que o projeto compartilhado
11. Em Gerenciador de soluções , clique duas vezes no projeto MathFuncs. Standard .
12. Navegue até configurações principais e, em seguida, atualize o namespace padrão para
MathFuncs .
13. Navegue até as configurações de saída e, em seguida, atualize o nome do assembly para MathFuncs .
14. Navegue até as configurações do compilador , altere a configuração para liberar , definindo
informações de depuração somente para símbolos e clique em OK .
15. Exclua o Class1.cs/Getting iniciado do projeto (se um deles tiver sido incluído como parte do modelo).
16. Controle + clique na pasta dependências/referências do projeto e escolha Editar referências .
17. Selecione MathFuncs. Shared na guia projetos e clique em OK .
18. Repita as etapas 7-17 (ignorando a etapa 9) usando as seguintes configurações:

N O M E DO P RO JETO N O M E DO M O DELO M EN U N O VO P RO JETO

MathFuncs. Android Biblioteca de Classes Biblioteca de > do Android

MathFuncs. iOS Biblioteca de associação Biblioteca de > do iOS

19. Em Gerenciador de soluções , clique duas vezes no projeto MathFuncs. Android e navegue até as
configurações do compilador .
20. Com a configuração definida como depurar , edite definir símbolos para incluir Android; .
21. Altere a configuração para liberação e edite definir símbolos para incluir também Android; .
22. Repita as etapas de 19-20 para MathFuncs. Ios , editando os símbolos para incluir o Ios; em vez do
Android; em ambos os casos.
23. Compile a solução na configuração de versão ( Control + Command + B ) e valide que todos os três
assemblies de saída (Android, Ios, .net Standard) (nas respectivas pastas bin do projeto) compartilham o
mesmo nome MathFuncs.dll .
Neste estágio, a solução deve ter três destinos, um cada para Android, iOS e .NET Standard e um projeto
compartilhado que é referenciado por cada um dos três destinos. Eles devem ser configurados para usar o
mesmo namespace padrão e assemblies de saída com o mesmo nome. Isso é necessário para a abordagem '
Bait e switch ' mencionada anteriormente.
Adicionando as bibliotecas nativas
O processo de adicionar as bibliotecas nativas à solução de wrapper varia ligeiramente entre o Android e o iOS.
Referências nativas para MathFuncs. Android
1. Controle + clique no projeto MathFuncs. Android e, em seguida, escolha nova pasta no menu
Adicionar nomeando-o bibliotecas .
2. Para cada Abi (interface binária de aplicativo), controle + clique na pasta bibliotecas , em seguida,
escolha nova pasta no menu Adicionar , nomeando-a depois dessa respectiva Abi . Nesse caso:
arm64-v8a
armeabi-v7a
x86
x86_64

NOTE
Para obter uma visão geral mais detalhada, consulte o tópico arquiteturas e CPUs do Guia do desenvolvedor NDK,
especificamente a seção sobre como endereçar código nativo em pacotes de aplicativos.

3. Verifique a estrutura de pastas:

- lib
- arm64-v8a
- armeabi-v7a
- x86
- x86_64

4. Adicione as bibliotecas . so correspondentes a cada uma das pastas da Abi com base no seguinte
mapeamento:
arm64-V8A: bibliotecas/Android/arm64
ARMEABI-v7a: bibliotecas/Android/ARM
x86: bibliotecas/Android/x86
x86_64: bibliotecas/Android/x86_64

NOTE
Para adicionar arquivos, controle + clique na pasta que representa o respectivo Abi e, em seguida, escolha
Adicionar arquivos... no menu Adicionar . Escolha a biblioteca apropriada (no diretório PrecompiledLibs ) e
clique em abrir e, em seguida, clique em OK deixando a opção padrão para copiar o arquivo para o diretório .

5. Para cada um dos arquivos . so , controle + clique e, em seguida, escolha a opção


EmbeddedNativeLibrar y no menu de ação de Build .
Agora, a pasta bibliotecas deve aparecer da seguinte maneira:

- lib
- arm64-v8a
- libMathFuncs.so
- armeabi-v7a
- libMathFuncs.so
- x86
- libMathFuncs.so
- x86_64
- libMathFuncs.so

Referências nativas para MathFuncs. iOS


1. Controle + clique no projeto MathFuncs. Ios e escolha Adicionar referência nativa no menu
Adicionar .
2. Escolha a biblioteca libMathFuncs. a (de bibliotecas/Ios no diretório PrecompiledLibs ) e clique em
abrir
3. Control + clique no arquivo libMathFuncs (dentro da pasta referências nativas e, em seguida,
escolha a opção Propriedades no menu
4. Configure as propriedades de referência nativa para que elas sejam marcadas (mostrando um ícone de
tique) no painel de Propriedades :
Forçar carga
É C++
Smart link

NOTE
Usar um tipo de projeto de biblioteca de associação junto com uma referência nativa incorpora a biblioteca
estática e permite que ela seja automaticamente vinculada ao aplicativo Xamarin. Ios que faz referência a ela
(mesmo quando ela é incluída por meio de um pacote NuGet).

5. Abra ApiDefinition.cs , excluindo o código comentado do modelo (deixando apenas o MathFuncs


namespace) e, em seguida, execute a mesma etapa para structs.cs

NOTE
Um projeto de biblioteca de associação requer esses arquivos (com as ações de compilação
ObjCBindingApiDefinition e ObjCBindingCoreSource ) para compilar. No entanto, escreveremos o código para
chamar nossa biblioteca nativa, fora desses arquivos de uma maneira que possa ser compartilhada entre destinos
de biblioteca do Android e iOS usando P/Invoke padrão.

Gravando o código da biblioteca gerenciada


Agora, escreva o código C# para chamar a biblioteca nativa. O objetivo é ocultar qualquer complexidade
subjacente. O consumidor não deve precisar de nenhum conhecimento funcional dos conceitos internos da
biblioteca nativa nem dos principais aspectos do P/Invoke.
Criando um SafeHandle
1. Controle + clique no projeto MathFuncs. Shared e, em seguida, escolha Adicionar arquivo... no
menu Adicionar .
2. Escolha classe vazia na janela novo arquivo , nomeie-a MyMathFuncsSafeHandle e clique em novo
3. Implemente a classe MyMathFuncsSafeHandle :
using System;
using Microsoft.Win32.SafeHandles;

namespace MathFuncs
{
internal class MyMathFuncsSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public MyMathFuncsSafeHandle() : base(true) { }

public IntPtr Ptr => handle;

protected override bool ReleaseHandle()


{
// TODO: Release the handle here
return true;
}
}
}

NOTE
Um SafeHandle é a maneira preferida de trabalhar com recursos não gerenciados em código gerenciado. Isso
abstrai muitos códigos clichês relacionados à finalização crítica e ao ciclo de vida do objeto. O proprietário desse
identificador pode tratá-lo posteriormente como qualquer outro recurso gerenciado e não precisará implementar
o padrão descartávelcompleto.

Criando a classe wrapper interna


1. Abrir MyMathFuncsWrapper.cs , alterá-lo para uma classe estática interna

namespace MathFuncs
{
internal static class MyMathFuncsWrapper
{
}
}

2. No mesmo arquivo, adicione a seguinte instrução condicional à classe:

#if Android
const string DllName = "libMathFuncs.so";
#else
const string DllName = "__Internal";
#endif

NOTE
Isso define o valor constante DllName com base em se a biblioteca está sendo compilada para Android ou Ios .
Isso é para resolver as diferentes convenções de nomenclatura usadas por cada plataforma respectiva, mas
também o tipo de biblioteca que está sendo usado nesse caso. O Android está usando uma biblioteca dinâmica e,
portanto, espera um nome de arquivo, incluindo a extensão. Para iOS, ' __Internal ' é necessário porque estamos
usando uma biblioteca estática.

3. Adicione uma referência a System. Runtime. InteropSer vices na parte superior do arquivo
MyMathFuncsWrapper.cs
using System.Runtime.InteropServices;

4. Adicione os métodos de wrapper para manipular a criação e a alienação da classe MyMathFuncs :

[DllImport(DllName, EntryPoint = "CreateMyMathFuncsClass")]


internal static extern MyMathFuncsSafeHandle CreateMyMathFuncs();

[DllImport(DllName, EntryPoint = "DisposeMyMathFuncsClass")]


internal static extern void DisposeMyMathFuncs(MyMathFuncsSafeHandle ptr);

NOTE
Estamos passando nossa constante DllName para o atributo DllImpor t junto com o Entr yPoint , que informa
explicitamente ao tempo de execução do .net o nome da função a ser chamada dentro dessa biblioteca.
Tecnicamente, não precisamos fornecer o valor de Entr yPoint se nossos nomes de método gerenciado fossem
idênticos ao não gerenciado. Se um não for fornecido, o nome do método gerenciado será usado como o
Entr yPoint em vez disso. No entanto, é melhor ser explícito.

5. Adicione os métodos de wrapper para permitir que possamos trabalhar com a classe MyMathFuncs
usando o seguinte código:

[DllImport(DllName, EntryPoint = "MyMathFuncsAdd")]


internal static extern double Add(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsSubtract")]


internal static extern double Subtract(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsMultiply")]


internal static extern double Multiply(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsDivide")]


internal static extern double Divide(MyMathFuncsSafeHandle ptr, double a, double b);

NOTE
Estamos usando tipos simples para os parâmetros neste exemplo. Como o Marshalling é uma cópia de bit que
não requer nenhum trabalho adicional em nossa parte. Observe também o uso da classe
MyMathFuncsSafeHandle em vez do IntPtr padrão. O IntPtr é mapeado automaticamente para o
SafeHandle como parte do processo de Marshalling.

6. Verifique se a classe MyMathFuncsWrapper concluída aparece como abaixo:


using System.Runtime.InteropServices;

namespace MathFuncs
{
internal static class MyMathFuncsWrapper
{
#if Android
const string DllName = "libMathFuncs.so";
#else
const string DllName = "__Internal";
#endif

[DllImport(DllName, EntryPoint = "CreateMyMathFuncsClass")]


internal static extern MyMathFuncsSafeHandle CreateMyMathFuncs();

[DllImport(DllName, EntryPoint = "DisposeMyMathFuncsClass")]


internal static extern void DisposeMyMathFuncs(MyMathFuncsSafeHandle ptr);

[DllImport(DllName, EntryPoint = "MyMathFuncsAdd")]


internal static extern double Add(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsSubtract")]


internal static extern double Subtract(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsMultiply")]


internal static extern double Multiply(MyMathFuncsSafeHandle ptr, double a, double b);

[DllImport(DllName, EntryPoint = "MyMathFuncsDivide")]


internal static extern double Divide(MyMathFuncsSafeHandle ptr, double a, double b);
}
}

Concluindo a classe MyMathFuncsSafeHandle


1. Abra a classe MyMathFuncsSafeHandle , navegue até o comentário de todo o espaço reservado no
método ReleaseHandle :

// TODO: Release the handle here

2. Substitua a linha todo :

MyMathFuncsWrapper.DisposeMyMathFuncs(handle);

Escrevendo a classe MyMathFuncs


Agora que o wrapper foi concluído, crie uma classe MyMathFuncs que gerenciará a referência ao objeto C++
MyMathFuncs não gerenciado.
1. Controle + clique no projeto MathFuncs. Shared e, em seguida, escolha Adicionar arquivo... no
menu Adicionar .
2. Escolha classe vazia na janela novo arquivo , nomeie-a MyMathFuncs e clique em novo
3. Adicione os seguintes membros à classe MyMathFuncs :

readonly MyMathFuncsSafeHandle handle;

4. Implemente o construtor para a classe para que ele crie e armazene um identificador para o objeto
MyMathFuncs nativo quando a classe for instanciada:
public MyMathFuncs()
{
handle = MyMathFuncsWrapper.CreateMyMathFuncs();
}

5. Implemente a interface IDisposable usando o seguinte código:

public class MyMathFuncs : IDisposable


{
...

protected virtual void Dispose(bool disposing)


{
if (handle != null && !handle.IsInvalid)
handle.Dispose();
}

public void Dispose()


{
Dispose(true);
GC.SuppressFinalize(this);
}

// ...
}

6. Implemente os métodos MyMathFuncs usando a classe MyMathFuncsWrapper para executar o


trabalho real nos bastidores passando o ponteiro que armazenamos no objeto não gerenciado
subjacente. O código deve ser o seguinte:

public double Add(double a, double b)


{
return MyMathFuncsWrapper.Add(handle, a, b);
}

public double Subtract(double a, double b)


{
return MyMathFuncsWrapper.Subtract(handle, a, b);
}

public double Multiply(double a, double b)


{
return MyMathFuncsWrapper.Multiply(handle, a, b);
}

public double Divide(double a, double b)


{
return MyMathFuncsWrapper.Divide(handle, a, b);
}

Criando o nuspec
Para que a biblioteca seja empacotada e distribuída via NuGet, a solução precisa de um arquivo nuspec . Isso
identificará quais dos assemblies resultantes serão incluídos para cada plataforma com suporte.
1. Control + clique na solução MathFuncs , em seguida, escolha Adicionar pasta de solução no menu
Adicionar nomeando SolutionItems .
2. Controle + clique na pasta SolutionItems e escolha novo arquivo... no menu Adicionar .
3. Escolha arquivo XML vazio na janela novo arquivo , nomeie-o MathFuncs. nuspec e clique em
novo .
4. Atualize MathFuncs. nuspec com os metadados básicos do pacote a serem exibidos para o consumidor
do NuGet . Por exemplo:

<?xml version="1.0"?>
<package>
<metadata>
<id>MathFuncs</id>
<version>$version$</version>
<authors>Microsoft Mobile Customer Advisory Team</authors>
<description>Sample C++ Wrapper Library</description>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<copyright>Copyright 2018</copyright>
</metadata>
</package>

NOTE
Consulte o documento de referência do nuspec para obter mais detalhes sobre o esquema usado para esse
manifesto.

5. Adicione um <files> elemento como um filho do <package> elemento (logo abaixo <metadata> ),
identificando cada arquivo com um <file> elemento separado:

<files>

<!-- Android -->

<!-- iOS -->

<!-- netstandard2.0 -->

</files>

NOTE
Quando um pacote é instalado em um projeto e onde há vários assemblies especificados pelo mesmo nome, o
NuGet escolherá efetivamente o assembly mais específico para a plataforma fornecida.

6. Adicione os <file> elementos para os assemblies do Android :

<file src="MathFuncs.Android/bin/Release/MathFuncs.dll" target="lib/MonoAndroid81/MathFuncs.dll" />


<file src="MathFuncs.Android/bin/Release/MathFuncs.pdb" target="lib/MonoAndroid81/MathFuncs.pdb" />

7. Adicione os <file> elementos para os assemblies do Ios :

<file src="MathFuncs.iOS/bin/Release/MathFuncs.dll" target="lib/Xamarin.iOS10/MathFuncs.dll" />


<file src="MathFuncs.iOS/bin/Release/MathFuncs.pdb" target="lib/Xamarin.iOS10/MathFuncs.pdb" />

8. Adicione os <file> elementos para os assemblies do netstandard 2.0 :

<file src="MathFuncs.Standard/bin/Release/netstandard2.0/MathFuncs.dll"
target="lib/netstandard2.0/MathFuncs.dll" />
<file src="MathFuncs.Standard/bin/Release/netstandard2.0/MathFuncs.pdb"
target="lib/netstandard2.0/MathFuncs.pdb" />
9. Verifique o manifesto nuspec :

<?xml version="1.0"?>
<package>
<metadata>
<id>MathFuncs</id>
<version>$version$</version>
<authors>Microsoft Mobile Customer Advisory Team</authors>
<description>Sample C++ Wrapper Library</description>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<copyright>Copyright 2018</copyright>
</metadata>
<files>

<!-- Android -->


<file src="MathFuncs.Android/bin/Release/MathFuncs.dll" target="lib/MonoAndroid81/MathFuncs.dll"
/>
<file src="MathFuncs.Android/bin/Release/MathFuncs.pdb" target="lib/MonoAndroid81/MathFuncs.pdb"
/>

<!-- iOS -->


<file src="MathFuncs.iOS/bin/Release/MathFuncs.dll" target="lib/Xamarin.iOS10/MathFuncs.dll" />
<file src="MathFuncs.iOS/bin/Release/MathFuncs.pdb" target="lib/Xamarin.iOS10/MathFuncs.pdb" />

<!-- netstandard2.0 -->


<file src="MathFuncs.Standard/bin/Release/netstandard2.0/MathFuncs.dll"
target="lib/netstandard2.0/MathFuncs.dll" />
<file src="MathFuncs.Standard/bin/Release/netstandard2.0/MathFuncs.pdb"
target="lib/netstandard2.0/MathFuncs.pdb" />

</files>
</package>

NOTE
Esse arquivo especifica os caminhos de saída do assembly de uma compilação de versão , portanto, certifique-se
de criar a solução usando essa configuração.

Neste ponto, a solução contém 3 assemblies .NET e um manifesto nuspec de suporte.

Distribuindo o wrapper do .NET com o NuGet


A próxima etapa é empacotar e distribuir o pacote NuGet para que ele possa ser facilmente consumido pelo
aplicativo e gerenciado como uma dependência. A disposição e o consumo podem ser feitos em uma única
solução, mas distribuir a biblioteca por meio de auxílios do NuGet na dissociação e nos permite gerenciar essas
bases de código de forma independente.
Preparando um diretório de pacotes locais
A forma mais simples de feed do NuGet é um diretório local:
1. No Finder , navegue até um diretório conveniente. Por exemplo, /Users .
2. Escolha nova pasta no menu arquivo , fornecendo um nome significativo, como local-NuGet-feed .
Como criar o pacote
1. Defina a configuração de compilação como liberar e execute uma compilação usando o comando +
B.
2. Abra o terminal e altere o diretório para a pasta que contém o arquivo nuspec .
3. No terminal , execute o comando do pacote NuGet especificando o arquivo nuspec , a versão (por
exemplo, 1.0.0) e o OutputDirector y usando a pasta criada na etapa anterior, ou seja, local-NuGet-
feed . Por exemplo:

nuget pack MathFuncs.nuspec -Version 1.0.0 -OutputDirectory ~/local-nuget-feed

4. Confirme se MathFuncs. 1.0.0. nupkg foi criado no diretório local-NuGet-feed .


ADICIONAL Usando um feed do NuGet privado com o Azure DevOps
Uma técnica mais robusta é descrita em introdução aos pacotes NuGet no Azure DevOps, que mostra como
criar um feed privado e enviar por push o pacote (gerado na etapa anterior) para esse feed.
É ideal que esse fluxo de trabalho seja totalmente automatizado, por exemplo, usando Azure pipelines. Para
obter mais informações, consulte Introdução ao Azure pipelines.

Consumindo o wrapper .NET de um aplicativo Xamarin. Forms


Para concluir o passo a passos, crie um aplicativo Xamarin. Forms para consumir o pacote que acabou de ser
publicado no feed do NuGet local.
Criando o projeto Xamarin. Forms
1. Abra uma nova instância do Visual Studio para Mac . Isso pode ser feito no terminal :

open -n -a "Visual Studio"

2. Em Visual Studio para Mac , clique em novo projeto (na página de boas-vindas ) ou em nova
solução (no menu arquivo ).
3. Na janela novo projeto , escolha aplicativo de formulários em branco (de dentro de
multiplataforma > aplicativo ) e clique em Avançar .
4. Atualize os campos a seguir e clique em Avançar :
Nome do aplicativo: MathFuncsApp.
Identificador da organização: Use um namespace reverso, por exemplo, com. {your_org} .
Plataformas de destino: Use o padrão (destinos Android e iOS).
Código compar tilhado: Defina isso como .NET Standard (uma solução de "biblioteca
compartilhada" é possível, mas além do escopo deste passo a passos).
5. Atualize os campos a seguir e clique em criar :
Nome do projeto: MathFuncsApp.
Nome da solução: MathFuncsApp.
Local: Use o local de salvamento padrão (ou escolha uma alternativa).
6. Em Gerenciador de soluções , controle + clique no destino ( MathFuncsApp. Android ou
MathFuncs. Ios ) para teste inicial e escolha definir como projeto de inicialização .
7. Escolha o dispositivo preferencial ou Simulator / emulador de simulador.
8. Execute a solução ( comando + retorno ) para validar que o projeto Xamarin. Forms do modelo é
compilado e executado corretamente.

NOTE
o Ios (especificamente o simulador) tende a ter o tempo de compilação/implantação mais rápido.
Adicionando o feed do NuGet local à configuração do NuGet
1. No Visual Studio , escolha preferências (no menu do Visual Studio ).
2. Escolha fontes na seção NuGet e clique em Adicionar .
3. Atualize os campos a seguir e clique em Adicionar fonte :
Nome: Forneça um nome significativo, por exemplo, pacotes locais.
Local: Especifique a pasta local NuGet-feed criada na etapa anterior.

NOTE
Nesse caso, não é necessário especificar um nome de usuário e uma senha .

4. Clique em OK .
Referenciando o pacote
Repita as etapas a seguir para cada projeto ( MathFuncsApp , MathFuncsApp. Android e MathFuncsApp.
Ios ).
1. Controle + clique no projeto e, em seguida, escolha adicionar pacotes NuGet... no menu Adicionar .
2. Procure MathFuncs .
3. Verifique se a versão do pacote é 1.0.0 e se os outros detalhes aparecem conforme o esperado, como
título e Descrição , ou seja, MathFuncs e exemplo de biblioteca de invólucro C++ .
4. Selecione o pacote MathFuncs e clique em Adicionar pacote .
Usando as funções de biblioteca
Agora, com uma referência ao pacote MathFuncs em cada um dos projetos, as funções estão disponíveis para
o código C#.
1. Abra MainPage.XAML.cs de dentro do projeto MathFuncsApp do Xamarin. Forms comum
(referenciado por MathFuncsApp. Android e MathFuncsApp. Ios ).
2. Adicione instruções using para System. Diagnostics e MathFuncs na parte superior do arquivo:

using System.Diagnostics;
using MathFuncs;

3. Declare uma instância da MyMathFuncs classe na parte superior da MainPage classe:

MyMathFuncs myMathFuncs;

4. Substitua os OnAppearing OnDisappearing métodos e da ContentPage classe base:

protected override void OnAppearing()


{
base.OnAppearing();
}

protected override void OnDisappearing()


{
base.OnDisappearing();
}

5. Atualize o OnAppearing método para inicializar a myMathFuncs variável declarada anteriormente:


protected override void OnAppearing()
{
base.OnAppearing();
myMathFuncs = new MyMathFuncs();
}

6. Atualize o OnDisappearing método para chamar o Dispose método em myMathFuncs :

protected override void OnDisappearing()


{
base.OnAppearing();
myMathFuncs.Dispose();
}

7. Implemente um método privado chamado TestMathFuncs da seguinte maneira:

private void TestMathFuncs()


{
var numberA = 1;
var numberB = 2;

// Test Add function


var addResult = myMathFuncs.Add(numberA, numberB);

// Test Subtract function


var subtractResult = myMathFuncs.Subtract(numberA, numberB);

// Test Multiply function


var multiplyResult = myMathFuncs.Multiply(numberA, numberB);

// Test Divide function


var divideResult = myMathFuncs.Divide(numberA, numberB);

// Output results
Debug.WriteLine($"{numberA} + {numberB} = {addResult}");
Debug.WriteLine($"{numberA} - {numberB} = {subtractResult}");
Debug.WriteLine($"{numberA} * {numberB} = {multiplyResult}");
Debug.WriteLine($"{numberA} / {numberB} = {divideResult}");
}

8. Por fim, chame TestMathFuncs no final do OnAppearing método:

TestMathFuncs();

9. Execute o aplicativo em cada plataforma de destino e valide a saída no painel de saída do aplicativo
aparece da seguinte maneira:

1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
NOTE
Se você encontrar um ' DLLNotFoundException ' ao testar no Android ou um erro de compilação no Ios,
certifique-se de verificar se a arquitetura de CPU do dispositivo/emulador/simulador que você está usando é
compatível com o subconjunto que escolhemos para dar suporte.

Resumo
Este artigo explicou como criar um aplicativo Xamarin. Forms que usa bibliotecas nativas por meio de um
wrapper comum do .NET distribuído por meio de um pacote NuGet. O exemplo fornecido neste passo a passos
é intencionalmente muito simplista para demonstrar a abordagem com mais facilidade. Um aplicativo real terá
que lidar com complexidades, como tratamento de exceção, retornos de chamada, Marshalling de tipos mais
complexos e vinculação com outras bibliotecas de dependências. Uma consideração importante é o processo
pelo qual a evolução do código C++ é coordenada e sincronizada com o wrapper e os aplicativos cliente. Esse
processo pode variar dependendo se uma ou ambas as preocupações são de responsabilidade de uma única
equipe. De qualquer forma, a automação é um benefício real. Abaixo estão alguns recursos que fornecem uma
leitura adicional sobre alguns dos principais conceitos, juntamente com os downloads relevantes.
Downloads
Ferramentas de linha de comando (CLI) do NuGet
Visual Studio
Exemplos
Enlapsar o desenvolvimento móvel de plataforma cruzada com C++
Microsoft PIX (C++ e Xamarin)
Porta de exemplo do mono San Angeles
Leitura Adicional
Artigos relacionados ao conteúdo desta postagem
Suporte à linguagem de programação no Xamarin
23/04/2020 • 2 minutes to read • Edit Online

C#
Visão geral do suporte assíncrono
A versão 5 C# do introduziu duas novas palavras-chave para expressar operações assíncronas: Async e Await.
Essas palavras-chave permitem escrever código simples que utiliza a biblioteca de tarefas paralelas para
executar operações de longa execução (como acesso à rede) em outro thread e acessar facilmente os resultados
na conclusão. As versões mais recentes do Xamarin. iOS e Xamarin. Android dão suporte a Async e Await-este
documento fornece explicações e um exemplo de como usar a nova sintaxe com o Xamarin.
Recursos de linguagem C# 6
A versão mais recente da C# linguagem – versão 6 – continua a evoluir a linguagem para ter menos nitidez,
maior clareza e mais consistência. Sintaxe de inicialização mais limpa, a capacidade de usar await em blocos de
catch/finally e o operador de ? condicional nulo são especialmente úteis.

F#
Criando aplicativos móveis com F# o e o Xamarin.

Basic.NET Visual portátil


O Visual Studio dá suporte à criação de bibliotecas de classes portáteis usando o Visual Basic.NET, que pode ser
incorporado em aplicativos Xamarin. Este artigo mostra como criar um novo Visual Basic PCL e, em seguida,
usá-lo em um aplicativo de exemplo Xamarin. iOS, Xamarin. Android e Windows Phone.

Criando exibições HTML usando modelos do Razor


O Xamarin permite que os desenvolvedores aproveitem o mecanismo de modelagem do Razor, originalmente
introduzidos C# com o ASP.NET MVC, junto com para combinar facilmente dados com HTML, JavaScript e CSS,
sem a complicação de criar manualmente cadeias de caracteres HTML no código. Este artigo demonstra como
usar modelos do Razor com Xamarin para Android e iOS.
Visão geral do suporte assíncrono
02/11/2020 • 13 minutes to read • Edit Online

O C# 5 introduziu duas palavras-chave para simplificar o programa assíncrono: Async e Await. Essas palavras-
chave permitem escrever código simples que utiliza a biblioteca de tarefas paralelas para executar operações de
longa execução (como acesso à rede) em outro thread e acessar facilmente os resultados na conclusão. As
versões mais recentes do Xamarin. iOS e Xamarin. Android dão suporte a Async e Await-este documento
fornece explicações e um exemplo de como usar a nova sintaxe com o Xamarin.
O suporte assíncrono do Xamarin é criado com base no mono 3,0 Foundation e atualiza o perfil de API a partir
de ser uma versão para dispositivos móveis do Silverlight para ser uma versão amigável para o .NET 4,5.

Visão geral
Este documento apresenta as novas palavras-chave Async e Await, em seguida, percorre alguns exemplos
simples que implementam métodos assíncronos no Xamarin. iOS e Xamarin. Android.
Para obter uma discussão mais completa sobre os novos recursos assíncronos do C# 5 (incluindo vários
exemplos e diferentes cenários de uso), consulte o artigo programação assíncrona.
O aplicativo de exemplo faz uma simples solicitação da Web assíncrona (sem bloquear o thread principal) e, em
seguida, atualiza a interface do usuário com o HTML e a contagem de caracteres baixados.

O suporte assíncrono do Xamarin é criado com base no mono 3,0 Foundation e atualiza o perfil de API a partir
de ser uma versão para dispositivos móveis do Silverlight para ser uma versão amigável para o .NET 4,5.

Requisitos
Os recursos do C# 5 exigem o mono 3,0, que está incluído no Xamarin. iOS 6,4 e no Xamarin. Android 4,8. Você
será solicitado a atualizar seu mono, Xamarin. iOS, Xamarin. Android e Xamarin. Mac para tirar proveito dele.

Usando Async & Await


async e await são novos recursos da linguagem C# que trabalham em conjunto com a biblioteca de tarefas
paralelas para facilitar a gravação de código threaded para executar tarefas de longa execução sem bloquear o
thread principal do seu aplicativo.

async
Declaração
A async palavra-chave é colocada em uma declaração de método (ou em um método lambda ou anônimo)
para indicar que ela contém um código que pode ser executado de forma assíncrona, ou seja, não bloquear o
thread do chamador.
Um método marcado com async deve conter pelo menos uma expressão ou instrução Await. Se nenhuma
await instrução estiver presente no método, ela será executada de forma síncrona (o mesmo que se não
houvesse nenhum async Modificador). Isso também resultará em um aviso do compilador (mas não um erro).
Tipos de retorno
Um método assíncrono deve retornar um Task , Task<TResult> ou void .
Especifique o Task tipo de retorno se o método não retornar nenhum outro valor.
Especifique Task<TResult> se o método precisa retornar um valor, em que TResult é o tipo que está sendo
retornado (como um int , por exemplo).
O void tipo de retorno é usado principalmente para manipuladores de eventos que exigem isso. O código que
chama os métodos assíncronos de retorno nulo não pode await fazer isso.
Parâmetros
Os métodos assíncronos não podem declarar ref ou out parâmetros.

await
O operador Await pode ser aplicado a uma tarefa dentro de um método marcado como Async. Isso faz com que
o método interrompa a execução nesse ponto e aguarde até que a tarefa seja concluída.
O uso de Await não bloqueia o thread do chamador – em vez disso, o controle é retornado para o chamador.
Isso significa que o thread de chamada não é bloqueado, por exemplo, o thread da interface do usuário não
seria bloqueado ao aguardar uma tarefa.
Quando a tarefa é concluída, o método retoma a execução no mesmo ponto no código. Isso inclui retornar ao
escopo try de um bloco try-catch-finally (se houver um). Await não pode ser usado em um bloco catch ou
finally.
Leia mais sobre Await em Microsoft docs.

Tratamento de Exceção
As exceções que ocorrem dentro de um método assíncrono são armazenadas na tarefa e geradas quando a
tarefa é await Ed. Essas exceções podem ser capturadas e manipuladas dentro de um bloco try-catch.

Cancelamento
Os métodos assíncronos que levam muito tempo para serem concluídos devem dar suporte ao cancelamento.
Normalmente, o cancelamento é invocado da seguinte maneira:
Um CancellationTokenSource objeto é criado.
A CancellationTokenSource.Token instância é passada para um método assíncrono cancelável.
O cancelamento é solicitado chamando o CancellationTokenSource.Cancel método.
A tarefa é cancelada e confirma o cancelamento.
Para obter mais informações sobre o cancelamento, consulte Ajuste fino de seu aplicativo assíncrono (C#).

Exemplo
Baixe a solução Xamarin de exemplo (para IOS e Android) para ver um exemplo de trabalho de async e await
em aplicativos móveis. O código de exemplo é discutido mais detalhadamente nesta seção.
Escrevendo um método assíncrono
O método a seguir demonstra como codificar um async método com uma await tarefa Ed:

public async Task<int> DownloadHomepage()


{
var httpClient = new HttpClient(); // Xamarin supports HttpClient!

Task<string> contentsTask = httpClient.GetStringAsync("https://visualstudio.microsoft.com/xamarin"); //


async method!

// await! control returns to the caller and the task continues to run on another thread
string contents = await contentsTask;

ResultEditText.Text += "DownloadHomepage method continues after async call. . . . .\n";

// After contentTask completes, you can calculate the length of the string.
int exampleInt = contents.Length;

ResultEditText.Text += "Downloaded the html and found out the length.\n\n\n";

ResultEditText.Text += contents; // just dump the entire HTML

return exampleInt; // Task<TResult> returns an object of type TResult, in this case int
}

Observe estes pontos:


A declaração do método inclui a async palavra-chave.
O tipo de retorno é Task<int> , portanto, o código de chamada pode acessar o int valor calculado nesse
método.
A instrução Return é return exampleInt; um objeto inteiro – o fato de que o método retorna faz Task<int>
parte das melhorias de idioma.
Chamando um método assíncrono 1
Esse manipulador de eventos de clique no botão pode ser encontrado no aplicativo de exemplo do Android para
chamar o método discutido acima:

GetButton.Click += async (sender, e) => {

Task<int> sizeTask = DownloadHomepage();

ResultTextView.Text = "loading...";
ResultEditText.Text = "loading...\n";

// await! control returns to the caller


var intResult = await sizeTask;

// when the Task<int> returns, the value is available and we can display on the UI
ResultTextView.Text = "Length: " + intResult ;
// "returns" void, since it's an event handler
};
Observações:
O delegado anônimo tem o prefixo de palavra-chave Async.
O método assíncrono DownloadHomepage retorna uma tarefa <int> que é armazenada na variável sizeTask.
O código aguarda na variável sizeTask. Esse é o local em que o método é suspenso e o controle é retornado
para o código de chamada até que a tarefa assíncrona seja concluída em seu próprio thread.
A execução não pausa quando a tarefa é criada na primeira linha do método, apesar da tarefa que está sendo
criada lá. A palavra-chave Await significa o local em que a execução está em pausa.
Quando a tarefa assíncrona é concluída, a intresult é definida e a execução continua no thread original, da
linha Await.
Chamando um método assíncrono 2
No aplicativo de exemplo do iOS, o exemplo é escrito ligeiramente diferente para demonstrar uma abordagem
alternativa. Em vez de usar um delegado anônimo, este exemplo declara um async manipulador de eventos
que é atribuído como um manipulador de eventos regular:

GetButton.TouchUpInside += HandleTouchUpInside;

O método do manipulador de eventos é definido como mostrado aqui:

async void HandleTouchUpInside (object sender, EventArgs e)


{
ResultLabel.Text = "loading...";
ResultTextView.Text = "loading...\n";

// await! control returns to the caller


var intResult = await DownloadHomepage();

// when the Task<int> returns, the value is available and we can display on the UI
ResultLabel.Text = "Length: " + intResult ;
}

Alguns pontos importantes:


O método é marcado como async , mas retorna void . Isso geralmente é feito apenas para manipuladores
de eventos (caso contrário, você retorna um Task ou Task<TResult> ).
A await palavra-chave no DownloadHomepage método atribui diretamente a uma variável ( intResult ), ao
contrário do exemplo anterior, em que usamos uma variável intermediária Task<int> para fazer referência à
tarefa. Esse é o local onde o controle é retornado para o chamador até que o método assíncrono seja
concluído em outro thread.
Quando o método assíncrono é concluído e retorna, a execução é retomada no await que significa que o
resultado inteiro é retornado e, em seguida, renderizado em um widget de interface do usuário.

Resumo
Usar Async e Await simplifica bastante o código necessário para gerar operações de longa execução em threads
em segundo plano sem bloquear o thread principal. Eles também facilitam o acesso aos resultados quando a
tarefa é concluída.
Este documento forneceu uma visão geral das novas palavras-chave de linguagem e exemplos para Xamarin.
iOS e Xamarin. Android.

Links Relacionados
AsyncAwait (exemplo)
Retornos de chamada como a instrução Go de nossas gerações
Dados (iOS) (exemplo)
HttpClient (iOS) (exemplo)
MapKitSearch (iOS) (exemplo)
Programação assíncrona
Ajuste fino de seu aplicativo assíncrono (C#)
Await, interface do usuário e deadlocks! Meu Oh!
Processando tarefas conforme elas são concluídas)
Padrão assíncrono baseado em tarefa (TAP)
Assincronia em C# 5 (blog de Eric Lippert) – sobre a introdução das palavras-chave
C#6 Visão geral dos novos recursos
23/04/2020 • 17 minutes to read • Edit Online

A versão 6 do C# idioma continua a desenvolver a linguagem para ter menos código clichê, maior clareza e
mais consistência. Sintaxe de inicialização mais limpa, a capacidade de usar Await em blocos catch/finally e o
NULL-Conditional? o operador é especialmente útil.

NOTE
Para obter informações sobre a versão mais recente C# do idioma – versão 7 – consulte o artigo novidades em C# 7,0

Este documento apresenta os novos recursos do C# 6. Ele é totalmente suportado pelo compilador mono e os
desenvolvedores podem começar a usar os novos recursos em todas as plataformas de destino do Xamarin.

O que há de C# novo em 6 vídeos

Usando C# 6
O C# compilador 6 é usado em todas as versões recentes do Visual Studio para Mac. Aqueles que usam
compiladores de linha de comando devem confirmar que mcs --version retorna 4,0 ou superior. Visual Studio
para Mac usuários podem verificar se têm o mono 4 (ou mais recente) instalado consultando sobre Visual
Studio para Mac > Visual Studio para Mac > mostrar detalhes .

Menos clichê
usando estático
Enumerações e determinadas classes, como System.Math , são principalmente os proprietários de valores
estáticos e funções. Em C# 6, você pode importar todos os membros estáticos de um tipo com uma única
instrução using static . Compare uma função trigonométrica típica em C# 5 e C# 6:
// Classic C#
class MyClass
{
public static Tuple<double,double> SolarAngleOld(double latitude, double declination, double hourAngle)
{
var tmp = Math.Sin (latitude) * Math.Sin (declination) + Math.Cos (latitude) * Math.Cos
(declination) * Math.Cos (hourAngle);
return Tuple.Create (Math.Asin (tmp), Math.Acos (tmp));
}
}

// C# 6
using static System.Math;

class MyClass
{
public static Tuple<double, double> SolarAngleNew(double latitude, double declination, double hourAngle)
{
var tmp = Asin (latitude) * Sin (declination) + Cos (latitude) * Cos (declination) * Cos
(hourAngle);
return Tuple.Create (Asin (tmp), Acos (tmp));
}
}

using static não faz const campos públicos, como Math.PI e Math.E , acessíveis diretamente:

for (var angle = 0.0; angle <= Math.PI * 2.0; angle += Math.PI / 8) ...
//PI is const, not static, so requires Math.PI

usando estático com métodos de extensão


O using static recurso Opera de maneira um pouco diferente com os métodos de extensão. Embora os
métodos de extensão sejam escritos usando static , eles não fazem sentido sem uma instância na qual operar.
Assim, quando using static é usado com um tipo que define métodos de extensão, os métodos de extensão
ficam disponíveis em seu tipo de destino (o tipo de this do método). Por exemplo,
using static System.Linq.Enumerable pode ser usado para estender a API de objetos IEnumerable<T> sem trazer
todos os tipos de LINQ:

using static System.Linq.Enumerable;


using static System.String;

class Program
{
static void Main()
{
var values = new int[] { 1, 2, 3, 4 };
var evenValues = values.Where (i => i % 2 == 0);
System.Console.WriteLine (Join(",", evenValues));
}
}

O exemplo anterior demonstra a diferença no comportamento: o método de extensão Enumerable.Where está


associado à matriz, enquanto o método estático String.Join pode ser chamado sem referência ao tipo de
String .

Expressões nameof
Às vezes, você deseja fazer referência ao nome em que você atribuiu uma variável ou campo. Em C# 6,
nameof(someVariableOrFieldOrType) retornará a cadeia de caracteres "someVariableOrFieldOrType" . Por exemplo,
ao lançar um ArgumentException é muito provável que você queira nomear qual argumento é inválido:
throw new ArgumentException ("Problem with " + nameof(myInvalidArgument))

A principal vantagem das expressões nameof é que elas são marcadas e são compatíveis com a refatoração
habilitada para ferramentas. O tipo de verificação de expressões nameof é particularmente bem-vindo em
situações em que uma string é usada para associar tipos dinamicamente. Por exemplo, no iOS, um string é
usado para especificar o tipo usado para protótipos de UITableViewCell objetos em um UITableView . nameof
pode garantir que essa associação não falhe devido a uma refatoração incorreta ou impreciso:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)


{
var cell = tableView.DequeueReusableCell (nameof(CellTypeA), indexPath);
cell.TextLabel.Text = objects [indexPath.Row].ToString ();
return cell;
}

Embora você possa passar um nome qualificado para nameof , somente o elemento final (após a última . )é
retornado. Por exemplo, você pode adicionar uma associação de dados no Xamarin. Forms:

var myReactiveInstance = new ReactiveType ();


var myLabelOld.BindingContext = myReactiveInstance;
var myLabelNew.BindingContext = myReactiveInstance;
var myLabelOld.SetBinding (Label.TextProperty, "StringField");
var myLabelNew.SetBinding (Label.TextProperty, nameof(ReactiveType.StringField));

As duas chamadas para SetBinding estão passando valores idênticos: nameof(ReactiveType.StringField) é


"StringField" , não "ReactiveType.StringField" como você pode esperar inicialmente.

Operador NULL-condicional
As atualizações anteriores C# introduziam os conceitos de tipos anuláveis e o operador de união nula ?? para
reduzir a quantidade de código clichê ao manipular valores anuláveis. C#6 continua este tema com o ?.
"operador NULL-Conditional". Quando usado em um objeto no lado direito de uma expressão, o operador
NULL-Conditional retornará o valor do membro se o objeto não for null e null caso contrário:

var ss = new string[] { "Foo", null };


var length0 = ss [0]?.Length; // 3
var length1 = ss [1]?.Length; // null
var lengths = ss.Select (s => s?.Length ?? 0); //[3, 0]

( length0 e length1 são inferidos para serem do tipo int? )


A última linha no exemplo anterior mostra o ? operador condicional nulo em combinação com o operador de
União ?? nulo. O novo C# operador NULL-Conditional nulo retorna null no segundo elemento na matriz, em
que ponto o operador de União nula é ativado e fornece um 0 para a matriz lengths (seja apropriado ou não, é
claro, específico do problema).
O operador NULL-Conditional deve reduzir enormemente a quantidade de verificação de nulos clichê
necessária em muitos aplicativos.
Há algumas limitações no operador NULL-Conditional devido a ambiguidades. Você não pode seguir
imediatamente um ? com uma lista de argumentos entre parênteses, como você pode esperar fazer com um
delegado:
SomeDelegate?("Some Argument") // Not allowed

No entanto, Invoke pode ser usado para separar o ? da lista de argumentos e ainda é uma melhoria marcada
em um bloco de texto clichê de null de verificação:

public event EventHandler HandoffOccurred;


public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity,
UIApplicationRestorationHandler completionHandler)
{
HandoffOccurred?.Invoke (this, userActivity.UserInfo);
return true;
}

Interpolação de cadeia de caracteres


A função String.Format tradicionalmente usava índices como espaços reservados na cadeia de caracteres de
formato, por exemplo, String.Format("Expected: {0} Received: {1}.", expected, received ). É claro que adicionar
um novo valor sempre envolvia uma pequena tarefa incômodo de contar argumentos, renumerar espaços
reservados e inserir o novo argumento na sequência direita na lista de argumentos.
C#o novo recurso de interpolação de cadeia de caracteres de 6 melhora muito na String.Format . Agora, você
pode nomear variáveis diretamente em uma cadeia de caracteres prefixada com um $ . Por exemplo:

$"Expected: {expected} Received: {received}."

As variáveis são, é claro, marcada e uma variável incorreta ou não disponível causará um erro do compilador.
Os espaços reservados não precisam ser variáveis simples, podem ser qualquer expressão. Nesses espaços
reservados, você pode usar aspas sem escapar dessas cotações. Por exemplo, observe o "s" no seguinte:

var s = $"Timestamp: {DateTime.Now.ToString ("s", System.Globalization.CultureInfo.InvariantCulture )}"

A interpolação de cadeia de caracteres dá suporte à sintaxe de alinhamento e formatação de String.Format .


Assim como você escreveu anteriormente {index, alignment:format} , em C# 6, você escreve
{placeholder, alignment:format} :

using static System.Linq.Enumerable;


using System;

class Program
{
static void Main ()
{
var values = new int[] { 1, 2, 3, 4, 12, 123456 };
foreach (var s in values.Select (i => $"The value is { i,10:N2}.")) {
Console.WriteLine (s);
}
Console.WriteLine ($"Minimum is { values.Min(i => i):N2}.");
}
}

resultados em:
The value is 1.00.
The value is 2.00.
The value is 3.00.
The value is 4.00.
The value is 12.00.
The value is 123,456.00.
Minimum is 1.00.

A interpolação de cadeia de caracteres é uma simplificação sintática para String.Format : ela não pode ser usada
com literais de cadeia de caracteres @"" e não é compatível com const , mesmo que nenhum espaço
reservado seja usado:

const string s = $"Foo"; //Error : const requires value

No caso de uso comum de criar argumentos de função com interpolação de cadeia de caracteres, você ainda
precisa ter cuidado com problemas de escape, codificação e cultura. As consultas SQL e URL são, é claro, críticas
para a limpeza. Assim como ocorre com String.Format , a interpolação de cadeia de caracteres usa o
CultureInfo.CurrentCulture . Usar CultureInfo.InvariantCulture é um pouco mais de palavras:

Thread.CurrentThread.CurrentCulture = new CultureInfo ("de");


Console.WriteLine ($"Today is: {DateTime.Now}"); //"21.05.2015 13:52:51"
Console.WriteLine ($"Today is: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}"); //"05/21/2015
13:52:51"

Inicialização
C#6 fornece várias maneiras concisas de especificar propriedades, campos e membros.
Inicialização de propriedade automática
As propriedades automáticas agora podem ser inicializadas da mesma maneira concisa que os campos. As
propriedades automáticas imutáveis podem ser gravadas com apenas um getter:

class ToDo
{
public DateTime Due { get; set; } = DateTime.Now.AddDays(1);
public DateTime Created { get; } = DateTime.Now;

No construtor, você pode definir o valor de uma propriedade automática somente getter:

class ToDo
{
public DateTime Due { get; set; } = DateTime.Now.AddDays(1);
public DateTime Created { get; } = DateTime.Now;
public string Description { get; }

public ToDo (string description)


{
this.Description = description; //Can assign (only in constructor!)
}

Essa inicialização de propriedades automáticas é um recurso de economia de espaço geral e um benefício para
os desenvolvedores que desejam enfatizar a imutabilidade em seus objetos.
Inicializadores de índice
C#6 apresenta inicializadores de índice, que permitem definir a chave e o valor em tipos que têm um indexador.
Normalmente, isso é para estruturas de dados de estilo Dictionary :

partial void ActivateHandoffClicked (WatchKit.WKInterfaceButton sender)


{
var userInfo = new NSMutableDictionary {
["Created"] = NSDate.Now,
["Due"] = NSDate.Now.AddSeconds(60 * 60 * 24),
["Task"] = Description
};
UpdateUserActivity ("com.xamarin.ToDo.edit", userInfo, null);
statusLabel.SetText ("Check phone");
}

Membros da função Expression-apto para


As funções lambda têm vários benefícios, um dos quais está simplesmente economizando espaço. Da mesma
forma, os membros da classe Expression-apto para permitem que pequenas funções sejam expressas um pouco
mais sucintos do C# que era possível nas versões anteriores do 6.
Os membros da função Expression-apto para usam a sintaxe de seta lambda em vez da sintaxe de bloco
tradicional:

public override string ToString () => $"{FirstName} {LastName}";

Observe que a sintaxe da seta lambda não usa um return explícito. Para funções que retornam void ,a
expressão também deve ser uma instrução:

public void Log(string message) => System.Console.WriteLine($"{DateTime.Now.ToString ("s",


System.Globalization.CultureInfo.InvariantCulture )}: {message}");

Os membros do Expression-apto para ainda estão sujeitos à regra que async tem suporte para métodos, mas
não para propriedades:

//A method, so async is valid


public async Task DelayInSeconds(int seconds) => await Task.Delay(seconds * 1000);
//The following property will not compile
public async Task<int> LeisureHours => await Task.FromResult<char>
(DateTime.Now.DayOfWeek.ToString().First()) == 'S' ? 16 : 5;

Exceções
Não há duas maneiras de fazer isso: a manipulação de exceções é difícil de ser adequada. Os novos recursos C#
do 6 tornam o tratamento de exceções mais flexível e consistente.
Filtros de exceção
Por definição, as exceções ocorrem em circunstâncias incomuns e pode ser muito difícil de motivo e código
sobre todas as maneiras que uma exceção de um tipo específico pode ocorrer. C#6 introduz a capacidade de
proteger um manipulador de execução com um filtro avaliado por tempo de execução. Isso é feito adicionando
um padrão de when (bool) após a declaração de catch(ExceptionType) normal. A seguir, um filtro distingue um
erro de análise relacionado ao parâmetro date em oposição a outros erros de análise.
public void ExceptionFilters(string aFloat, string date, string anInt)
{
try
{
var f = Double.Parse(aFloat);
var d = DateTime.Parse(date);
var n = Int32.Parse(anInt);
} catch (FormatException e) when (e.Message.IndexOf("DateTime") > -1) {
Console.WriteLine ($"Problem parsing \"{nameof(date)}\" argument");
} catch (FormatException x) {
Console.WriteLine ("Problem parsing some other argument");
}
}

aguardar no catch... Por fim...


Os recursos de async introduzidos em C# 5 foram um alterador de jogo para a linguagem. Em C# 5, await não
foi permitido em blocos de catch e de finally , um incômodo dado o valor do recurso de async/await . C#6
remove essa limitação, permitindo que os resultados assíncronos sejam esperados consistentemente por meio
do programa, conforme mostrado no trecho a seguir:

async void SomeMethod()


{
try {
//...etc...
} catch (Exception x) {
var diagnosticData = await GenerateDiagnosticsAsync (x);
Logger.log (diagnosticData);
} finally {
await someObject.FinalizeAsync ();
}
}

Resumo
O C# idioma continua a evoluir para tornar os desenvolvedores mais produtivos e também promover boas
práticas e ferramentas de suporte. Este documento forneceu uma visão geral dos novos recursos de linguagem
C# do 6 e demonstrou brevemente como eles são usados.

Links relacionados
Novos recursos de linguagem C# no 6
Usando F # com o Xamarin
02/11/2020 • 2 minutes to read • Edit Online

O F # é uma linguagem de programação de software livre, de plataforma cruzada e funcional para .NET.
O F # combina a suposição, expressividade e capacidade de composição da programação funcional de tipo
inferido, a segurança de tempo de compilação de código fortemente tipado e o suporte de tempo de execução,
bibliotecas, interoperabilidade, ferramentas e modelo de objeto do .NET.
O F # está disponível como uma linguagem de programação para usuários do Xamarin em todas as plataformas
com suporte do Xamarin: Android, macOS e iOS.
Guia do F#
Introdução com F # e Xamarin
Amostras de F # Mobile

Recursos do F # no Visual Studio para Mac


O F # é um idioma com suporte no Visual Studio para Mac. Os recursos com suporte incluem:
Suporte a F # 4,1
Suporte a PCL e .NET Standard de F #
Suporte ao projeto compartilhado F #
Navegação de código
Realce de sintaxe no F# Interativo
Modelos F # para Xamarin. Forms, iOS e Android
Introdução com F#
02/11/2020 • 2 minutes to read • Edit Online

Requisitos
O F # é incluído por padrão no Visual Studio para Mac.
No Windows, você deve instalar as ferramentas autônomas do compilador F #, de acordo com as instruções no
site do FSharp.org.

Criando um projeto de F#
A criação de um novo aplicativo F # é feita na mesma janela de projeto nova usada para C#.
Em Visual Studio para Mac escolha arquivo > nova solução . Na caixa de diálogo novo projeto , selecione
um modelo de projeto. Use a lista suspensa à direita do modelo para escolher o idioma que você deseja usar:

Selecione o tipo de projeto e clique em Avançar para nomeá-lo e criá-lo.


Agora você está pronto para começar a criar alguns ótimos aplicativos em F #!

Aprendendo a usar o F#
Um tutorial de F # também pode ser criado de dentro da caixa de diálogo nova solução no Visual Studio para
Mac. Navegue até outro Tutorial > .net > F # , conforme detalhado na imagem abaixo:
Isso abre uma nova solução interativa. Explorar essa é uma ótima maneira de se familiarizar com os conceitos
básicos da linguagem.

Confira a lista de amostras para ver o F # em ação.

Referências
Há uma infinidade de informações online para se familiarizar com a linguagem F #, cobrindo todas as
proficiências. Listadas abaixo estão algumas das nossas recomendações:
F# Software Foundation
Portal de desenvolvimento do Visual F#
Galeria de códigos de Visual F#
Visual F# programação de matemática/estatísticas
Visual F# gráfico
Exemplos de F # para o Xamarin
02/11/2020 • 2 minutes to read • Edit Online

Esta página contém links para alguns exemplos de F # usando o Xamarin.

iOS
O exemplo de cidade do FSSceneKit mostra como criar uma cidade gerada aleatoriamente usando SceneKit e F
#. Também há uma edição "Oculus Thrift" (Google Enpapelr).

Superficial demonstra uma diversão de toque-interface do usuário criada com F # para Ios.

Xamarin.Forms
Vários exemplos para o livro Xamarin. Forms foram portados para F #. Esses links levam você ao local do
GitHub para cada capítulo:
Capítulo 2. Anatomia de um aplicativo
Capítulo 3. Mais profundo em texto
Capítulo 4. Rolando a pilha
Capítulo 5. Lidando com tamanhos
Capítulo 6. Cliques de botão
Capítulo 7. XAML vs. código
Capítulo 8. Código e XAML em harmonia
Visual Basic e .NET Standard
02/11/2020 • 3 minutes to read • Edit Online

Os projetos do Xamarin Android e iOS não dão suporte nativo a Visual Basic; no entanto, os desenvolvedores
podem usar .net Standard bibliotecas para migrar o código Visual Basic existente para Android e Ios, ou para
gravar uma parte significativa da lógica do aplicativo no Visual Basic. Os aplicativos Xamarin. Forms podem ser
criados inteiramente em Visual Basic (excluindo renderizadores personalizados, serviços de dependência e
code-behind XAML).

Requisitos
Para criar e Compilar Visual Basic bibliotecas de .NET Standard, você deve usar o Visual Studio no Windows
(Visual Studio 2017 ou mais recente).

NOTE
Visual Basic bibliotecas só podem ser criadas e compiladas usando o Visual Studio. O xamarin. Android e o Xamarin. iOS
não dão suporte ao idioma Visual Basic.
Se você trabalhar apenas no Visual Studio, poderá fazer referência ao projeto Visual Basic de projetos Xamarin. Android e
Xamarin. iOS.
Se seus projetos Android e iOS também devem ser carregados em Visual Studio para Mac você deve referenciar o
assembly de saída do assembly Visual Basic.

Criando uma biblioteca de .NET Standard Visual Basic.NET


Esta seção explica como criar uma biblioteca Visual Basic .NET Standard usando o Visual Studio 2019. A
biblioteca pode então ser referenciada em outros projetos, incluindo aplicativos Xamarin. Android, Xamarin. iOS
e Xamarin. Forms.
Ao adicionar um Visual Basic .NET Standard biblioteca no Visual Studio, você deve ter cuidado para escolher o
tipo de projeto correto:
1. No Visual Studio 2019, escolha criar um novo projeto .
2. Digite Visual Basic biblioteca para filtrar as opções de projeto e escolha a opção biblioteca de
classes (.net Standard) com o ícone de Visual Basic:
3. Na próxima tela, digite um nome para o projeto e pressione criar .
4. O projeto Visual Basic aparecerá conforme mostrado na Gerenciador de soluções assim:

O projeto agora está pronto para que Visual Basic código seja adicionado. .NET Standard projetos podem ser
referenciados por outros projetos (projetos de aplicativo ou projetos de biblioteca).

Resumo
Este artigo demonstrou como consumir Visual Basic código em aplicativos Xamarin usando o Visual Studio.
Embora o Xamarin não ofereça suporte a Visual Basic diretamente, a compilação de Visual Basic em uma
biblioteca .NET Standard permite que o código escrito com Visual Basic seja incluído nos aplicativos Android e
iOS.
As páginas a seguir descrevem como usar o Visual Basic.NET .NET Standard bibliotecas em aplicativos nativos
ou Xamarin. Forms:
Compilando aplicativos Xamarin. iOS e Xamarin. Android nativos que usam o VB
Criando aplicativos Xamarin. Forms com VB

Links Relacionados
TaskyVB (exemplo)
XamarinFormsVB (exemplo)
.NET Standard e Xamarin
.NET Standard
Visual Basic no Xamarin Android e iOS
15/01/2021 • 8 minutes to read • Edit Online

Baixar o exemplo
O aplicativo de exemplo TaskyVB demonstra como Visual Basic código compilado em uma biblioteca .net
Standard pode ser usado com o Xamarin. Aqui estão algumas capturas de tela dos aplicativos resultantes em
execução no Android e iOS:

Os projetos do Android e do iOS no exemplo são todos escritos em C#. A interface do usuário para cada
aplicativo é criada com tecnologias nativas, enquanto o TodoItem gerenciamento é fornecido pela biblioteca
Visual Basic .net Standard usando um arquivo XML (para fins de demonstração, não um banco de dados
completo).

Passo a passo de exemplo


Este guia discute como Visual Basic foi implementado no exemplo do Xamarin TaskyVB para IOS e Android.

NOTE
Examine as instruções em Visual Basic e .net Standard antes de continuar com este guia.
Consulte o Xamarin. Forms usando instruções de Visual Basic para ver como criar um aplicativo com código de Visual
Basic de interface de usuário compartilhada.

VisualBasicNetStandard
Visual Basic .NET Standard bibliotecas só podem ser criadas no Visual Studio no Windows. A biblioteca de
exemplo contém os conceitos básicos de nosso aplicativo nesses Visual Basic arquivos:
TodoItem. vb
TodoItemManager. vb
TodoItemRepositoryXML. vb
Xmlstorage. vb
TodoItem. vb
Essa classe contém o objeto comercial a ser usado em todo o aplicativo. Ele será definido em Visual Basic e
compartilhado com os projetos Android e iOS que são escritos em C#.
A definição de classe é mostrada aqui:

Public Class TodoItem


Property ID() As Integer
Property Name() As String
Property Notes() As String
Property Done() As Boolean
End Class

O exemplo usa serialização e desserialização de XML para carregar e salvar os objetos TodoItem.
TodoItemManager. vb
A classe Manager apresenta a ' API ' para o código portátil. Ele fornece operações CRUD básicas para a
TodoItem classe, mas nenhuma implementação dessas operações.

Public Class TodoItemManager


Private _repository As TodoItemRepositoryXML
Public Sub New(filename As String)
_repository = New TodoItemRepositoryXML(filename, storage)
End Sub
Public Function GetTask(id As Integer) As TodoItem
Return _repository.GetTask(id)
End Function
Public Function GetTasks() As List(Of TodoItem)
Return New List(Of TodoItem)(_repository.GetTasks())
End Function
Public Function SaveTask(item As TodoItem) As Integer
Return _repository.SaveTask(item)
End Function
Public Function DeleteTask(item As TodoItem) As Integer
Return _repository.DeleteTask(item.ID)
End Function
End Class

O construtor usa uma instância de IXmlStorage como um parâmetro. Isso permite que cada plataforma forneça
sua própria implementação de trabalho e, ao mesmo tempo, permita que o código portátil Descreva outras
funcionalidades que podem ser compartilhadas.
TodoItemRepository. vb
A classe Repository contém a lógica para gerenciar a lista de objetos TodoItem. O código completo é mostrado
abaixo – a lógica existe principalmente para gerenciar um valor de ID exclusivo em TodoItems à medida que eles
são adicionados e removidos da coleção.
Public Class TodoItemRepositoryXML
Private _filename As String
Private _storage As IXmlStorage
Private _tasks As List(Of TodoItem)

''' <summary>Constructor</summary>
Public Sub New(filename As String)
_filename = filename
_storage = New XmlStorage
_tasks = _storage.ReadXml(filename)
End Sub
''' <summary>Inefficient search for a Task by ID</summary>
Public Function GetTask(id As Integer) As TodoItem
For t As Integer = 0 To _tasks.Count - 1
If _tasks(t).ID = id Then
Return _tasks(t)
End If
Next
Return New TodoItem() With {.ID = id}
End Function
''' <summary>List all the Tasks</summary>
Public Function GetTasks() As IEnumerable(Of TodoItem)
Return _tasks
End Function
''' <summary>Save a Task to the Xml file
''' Calculates the ID as the max of existing IDs</summary>
Public Function SaveTask(item As TodoItem) As Integer
Dim max As Integer = 0
If _tasks.Count > 0 Then
max = _tasks.Max(Function(t As TodoItem) t.ID)
End If
If item.ID = 0 Then
item.ID = ++max
_tasks.Add(item)
Else
Dim j = _tasks.Where(Function(t) t.ID = item.ID).First()
j = item
End If
_storage.WriteXml(_tasks, _filename)
Return max
End Function
''' <summary>Removes the task from the XMl file</summary>
Public Function DeleteTask(id As Integer) As Integer
For t As Integer = 0 To _tasks.Count - 1
If _tasks(t).ID = id Then
_tasks.RemoveAt(t)
_storage.WriteXml(_tasks, _filename)
Return 1
End If
Next
Return -1
End Function
End Class

NOTE
Esse código é um exemplo de um mecanismo de armazenamento de dados muito básico. Ele é fornecido para demonstrar
como uma biblioteca de .NET Standard pode codificar em uma interface para acessar a funcionalidade específica da
plataforma (nesse caso, carregar e salvar um arquivo XML). Ele não pretende ser uma alternativa de banco de dados de
qualidade de produção.

Projetos de aplicativos Android e iOS


iOS
No aplicativo iOS, o TodoItemManager e o XmlStorageImplementation são criados no arquivo AppDelegate.cs ,
conforme mostrado neste trecho de código. As primeiras quatro linhas estão apenas criando o caminho para o
arquivo em que os dados serão armazenados; as duas linhas finais mostram as duas classes que estão sendo
instanciadas.

var xmlFilename = "TodoList.xml";


string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
var path = Path.Combine(libraryPath, xmlFilename);

TaskMgr = new TodoItemManager(path);

Android
No aplicativo Android, o TodoItemManager e o XmlStorageImplementation são criados no arquivo Application.cs
, conforme mostrado neste trecho de código. As três primeiras linhas estão apenas criando o caminho para o
arquivo em que os dados serão armazenados; as duas linhas finais mostram as duas classes que estão sendo
instanciadas.

var xmlFilename = "TodoList.xml";


string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(libraryPath, xmlFilename);

TaskMgr = new TodoItemManager(path);

O restante do código do aplicativo se preocupa principalmente com a interface do usuário e usando a TaskMgr
classe para carregar e salvar TodoItem classes.

Visual Studio 2019 para Mac


WARNING
Visual Studio para Mac não dá suporte à edição do idioma do Visual Basic – não há itens de menu para criar Visual Basic
projetos ou arquivos. Se você abrir um . vb , não haverá realce de sintaxe de linguagem, preenchimento automático ou
IntelliSense.

O Visual Studio 2019 para Mac pode compilar projetos de .net standard do Visual Studio criados no Windows,
para que aplicativos Ios possam fazer referência a esses projetos.
O Visual Studio 2017 não pode Compilar Visual Basic projetos.

Resumo
Este artigo demonstrou como consumir Visual Basic código em aplicativos Xamarin usando o Visual Studio e
bibliotecas de .NET Standard. Embora o Xamarin não ofereça suporte a Visual Basic diretamente, a compilação
de Visual Basic em uma biblioteca .NET Standard permite que o código escrito com Visual Basic seja incluído nos
aplicativos iOS e Android.

Links Relacionados
TaskyVB (exemplo de .NET Standard)
Novidades no .NET Standard
Xamarin. Forms usando o Visual Basic.NET
15/01/2021 • 5 minutes to read • Edit Online

O Xamarin não oferece suporte a Visual Basic diretamente – siga as instruções nesta página para criar uma
solução de Xamarin. Forms em C# e, em seguida, substitua o projeto .NET Standard C# por Visual Basic.

Baixar o exemplo

NOTE
Você deve usar o Visual Studio no Windows para programar com Visual Basic.

Xamarin. Forms com instruções Visual Basic


Siga estas etapas para criar um projeto do Xamarin. Forms simples que usa Visual Basic:
1. No Visual Studio 2019, escolha criar um novo projeto .
2. Na janela criar um novo projeto , digite Xamarin. Forms para filtrar a lista e selecione aplicativo
móvel (xamarin. Forms) e pressione Avançar .
3. Na próxima tela, digite um nome para o projeto e pressione criar .
4. Escolha o modelo em branco e pressione OK :

Isso cria uma solução Xamarin. Forms no Visual Studio, usando C#. As próximas etapas modificam a
solução para usar Visual Basic.
5. Clique com o botão direito do mouse na solução e escolha adicionar > novo projeto...
6. Digite Visual Basic biblioteca para filtrar as opções de projeto e escolha a opção biblioteca de
classes (.net Standard) com o ícone de Visual Basic:

7. Na próxima tela, digite um nome para o projeto e pressione criar .


8. Clique com o botão direito do mouse no projeto Visual Basic e escolha Propriedades e, em seguida,
altere o namespace padrão para corresponder aos projetos C# existentes:
9. Clique com o botão direito do mouse no novo projeto Visual Basic e escolha gerenciar pacotes NuGet
e, em seguida, instale o Xamarin. Forms e feche a janela do Gerenciador de pacotes.

10. Renomeie o arquivo Class1. vb padrão para app. vb :

11. Cole o código a seguir no arquivo app. vb , que se tornará o ponto inicial do aplicativo Xamarin. Forms:
Imports Xamarin.Forms

Public Class App


Inherits Application

Public Sub New()


Dim label = New Label With {.HorizontalTextAlignment = TextAlignment.Center,
.FontSize = Device.GetNamedSize(NamedSize.Medium,
GetType(Label)),
.Text = "Welcome to Xamarin.Forms with Visual Basic.NET"}

Dim stack = New StackLayout With {


.VerticalOptions = LayoutOptions.Center
}
stack.Children.Add(label)

Dim page = New ContentPage


page.Content = stack
MainPage = page

End Sub

End Class

12. Atualize os projetos do Android e iOS para que eles façam referência a novos projetos de Visual Basic (e
não ao projeto C# criado pelo modelo). Clique com o botão direito do mouse no nó referências nos
projetos do Android e Ios para abrir o Gerenciador de referências . Desmarcar a biblioteca do C# e
marcar a biblioteca de Visual Basic (não se esqueça disso, faça isso para os projetos do Android e do iOS).

13. Exclua o projeto C#. Adicione novos arquivos . vb para criar seu aplicativo Xamarin. Forms. Um modelo
para novos ContentPage s no Visual Basic é mostrado abaixo:
Imports Xamarin.Forms

Public Class Page2


Inherits ContentPage

Public Sub New()


Dim label = New Label With {.HorizontalTextAlignment = TextAlignment.Center,
.FontSize = Device.GetNamedSize(NamedSize.Medium,
GetType(Label)),
.Text = "Visual Basic ContentPage"}

Dim stack = New StackLayout With {


.VerticalOptions = LayoutOptions.Center
}
stack.Children.Add(label)

Content = stack
End Sub
End Class

Limitações de Visual Basic no Xamarin. Forms


Conforme indicado na página do Visual Basic.net portátil, o Xamarin não oferece suporte à linguagem Visual
Basic. Isso significa que há algumas limitações sobre onde você pode usar Visual Basic:
As páginas XAML não podem ser incluídas no projeto Visual Basic-o gerador code-behind só pode
compilar C#. É possível incluir o XAML em uma biblioteca de classes portátil do C#, referenciada e
separada, e usar DataBinding para popular os arquivos XAML por meio de modelos de Visual Basic (um
exemplo disso é incluído no exemplo).
Renderizadores personalizados não podem ser gravados em Visual Basic, eles devem ser escritos em C#
nos projetos da plataforma nativa.
As implementações do serviço de dependência não podem ser gravadas em Visual Basic, elas devem ser
escritas em C# nos projetos da plataforma nativa.

Links Relacionados
XamarinFormsVB (exemplo)
Desenvolvimento entre plataformas com o .NET Framework
Criando exibições HTML usando modelos do Razor
23/04/2020 • 32 minutes to read • Edit Online

No mundo de desenvolvimento móvel, o termo "aplicativo híbrido" normalmente se refere a um aplicativo que
apresenta algumas (ou todas) suas telas como páginas HTML dentro de um controle do Visualizador da Web
hospedado.
Há alguns ambientes de desenvolvimento que permitem que você crie seu aplicativo móvel inteiramente em
HTML e JavaScript, no entanto, esses aplicativos podem sofrer problemas de desempenho ao tentar realizar
processamento complexo ou efeitos de interface do usuário e também são limitados na plataforma recursos
que eles podem acessar.
O Xamarin oferece o melhor dos dois mundos, especialmente ao utilizar o mecanismo de modelagem HTML do
Razor. Com o Xamarin, você tem a flexibilidade de criar exibições HTML modeladas de plataforma cruzada que
usam JavaScript e CSS, mas também têm acesso completo às APIs de plataforma C#subjacentes e ao
processamento rápido usando o.
Este documento explica como usar o mecanismo de modelagem do Razor para criar modos de exibição HTML +
JavaScript + CSS que podem ser usados em plataformas móveis usando o Xamarin.

Usando exibições da Web programaticamente


Antes de aprendermos sobre o Razor, esta seção aborda como usar exibições da Web para exibir conteúdo
HTML diretamente – especificamente o conteúdo HTML que é gerado em um aplicativo.
O Xamarin fornece acesso completo às APIs de plataforma subjacentes no iOS e no Android, portanto, é fácil
criar e exibir HTML C#usando. A sintaxe básica para cada plataforma é mostrada abaixo.
iOS
A exibição de HTML em um controle UIWebView no Xamarin. iOS também leva apenas algumas linhas de
código:

var webView = new UIWebView (View.Bounds);


View.AddSubview(webView);
string contentDirectoryPath = Path.Combine (NSBundle.MainBundle.BundlePath, "Content/");
var html = "<html><h1>Hello</h1><p>World</p></html>";
webView.LoadHtmlString(html, NSBundle.MainBundle.BundleUrl);

Consulte as receitas do Ios UIWebView para obter mais detalhes sobre como usar o controle UIWebView.
Android
A exibição de HTML em um controle WebView usando o Xamarin. Android é realizada em apenas algumas
linhas de código:

// webView is declared in an AXML layout file


var webView = FindViewById<WebView> (Resource.Id.webView);

// enable JavaScript execution in your html view so you can provide "alerts" and other js
webView.SetWebChromeClient(new WebChromeClient());

var html = "<html><h1>Hello</h1><p>World</p></html>";


webView.LoadDataWithBaseURL("file:///android_asset/", html, "text/html", "UTF-8", null);
Consulte as receitas da WebView do Android para obter mais detalhes sobre como usar o controle WebView.
Especificando o diretório base
Em ambas as plataformas, há um parâmetro que especifica o diretório base para a página HTML. Esse é o local
no sistema de arquivos do dispositivo que é usado para resolver referências relativas a recursos como imagens
e arquivos CSS. Por exemplo, marcas como

<link rel="stylesheet" href="style.css" />


<img src="monkey.jpg" />
<script type="text/javascript" src="jscript.js">

consulte estes arquivos: Style. css , monkey.jpg e JScript. js . A configuração do diretório base informa à
exibição da Web onde esses arquivos estão localizados para que possam ser carregados na página.
iOS
A saída do modelo é renderizada em iOS com C# o seguinte código:

webView.LoadHtmlString (page, NSBundle.MainBundle.BundleUrl);

O diretório base é especificado como NSBundle.MainBundle.BundleUrl que se refere ao diretório no qual o


aplicativo está instalado. Todos os arquivos na pasta recursos são copiados para esse local, como o arquivo
Style. css mostrado aqui:

A ação de compilação para todos os arquivos de conteúdo estático deve ser BundleResource :

Android
O Android também exige que um diretório base seja passado como um parâmetro quando as cadeias de
caracteres HTML são exibidas em uma exibição da Web.

webView.LoadDataWithBaseURL("file:///android_asset/", page, "text/html", "UTF-8", null);

A cadeia de caracteres especial file:///android_asset/ refere-se à pasta de ativos do Android em seu


aplicativo, mostrada aqui contendo o arquivo Style. css .
A ação de Build para todos os arquivos de conteúdo estático deve ser AndroidAsset .

Chamando C# a partir de HTML e JavaScript


Quando uma página HTML é carregada em uma exibição da Web, ela trata os links e os formulários como faria
se a página fosse carregada a partir de um servidor. Isso significa que, se o usuário clicar em um link ou enviar
um formulário, a exibição da Web tentará navegar até o destino especificado.
Se o link for para um servidor externo (como google.com), a exibição da Web tentará carregar o site externo
(supondo que haja uma conexão com a Internet).

<a href="http://google.com/">Google</a>

Se o link for relativo, a exibição da Web tentará carregar esse conteúdo do diretório base. Obviamente,
nenhuma conexão de rede é necessária para que isso funcione, pois o conteúdo é armazenado no aplicativo no
dispositivo.

<a href="somepage.html">Local content</a>

As ações de formulário seguem a mesma regra.

<form method="get" action="http://google.com/"></form>


<form method="get" action="somepage.html"></form>

Você não vai hospedar um servidor Web no cliente; no entanto, você pode usar as mesmas técnicas de
comunicação de servidor empregadas nos padrões de design responsivos atuais para chamar serviços por
HTTP GET e manipular respostas de forma assíncrona emitindo JavaScript (ou chamando JavaScript já
hospedado na exibição da Web). Isso permite que você passe facilmente os dados do HTML de volta C# para o
código para processamento e, em seguida, exiba os resultados de volta na página HTML.
O iOS e o Android fornecem um mecanismo para o código do aplicativo interceptar esses eventos de navegação
para que o código do aplicativo possa responder (se necessário). Esse recurso é crucial para a criação de
aplicativos híbridos porque permite que o código nativo interaja com a exibição da Web.
iOS
O evento ShouldStartLoad na exibição da Web no iOS pode ser substituído para permitir que o código do
aplicativo manipule uma solicitação de navegação (como um clique de link). Os parâmetros do método
fornecem todas as informações
bool HandleShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
{
// return true if handled in code
// return false to let the web view follow the link
}

e, em seguida, atribua o manipulador de eventos:

webView.ShouldStartLoad += HandleShouldStartLoad;

Android
No Android, basta WebViewClient a subclasse e, em seguida, implementar o código para responder à solicitação
de navegação.

class HybridWebViewClient : WebViewClient {


public override bool ShouldOverrideUrlLoading (WebView webView, IWebResourceRequest request) {
// return true if handled in code
// return false to let the web view follow the link
}
}

em seguida, defina o cliente na exibição da Web:

webView.SetWebViewClient (new HybridWebViewClient ());

Chamando JavaScript a partir de C#


Além de informar uma exibição da Web para carregar uma nova página HTML, C# o código também pode
executar JavaScript na página atualmente exibida. Blocos de código JavaScript inteiros podem ser criados C#
usando cadeias de caracteres e executados, ou você pode criar chamadas de método para o JavaScript já
disponível na página por meio de marcas de script .
Android
Crie o código JavaScript a ser executado e, em seguida, Prefixe-o com "JavaScript:" e instrua a exibição da Web
para carregar essa cadeia de caracteres:

var js = "alert('test');";
webView.LoadUrl ("javascript:" + js);

iOS
exibições da Web do iOS fornecem um método especificamente para chamar JavaScript:

var js = "alert('test');";
webView.EvaluateJavascript (js);

Resumo
Esta seção introduziu os recursos dos controles de exibição da Web no Android e no iOS que nos permitem criar
aplicativos híbridos com o Xamarin, incluindo:
A capacidade de carregar HTML de cadeias de caracteres geradas no código,
A capacidade de fazer referência a arquivos locais (CSS, JavaScript, imagens ou outros arquivos HTML),
A capacidade de interceptar solicitações de C# navegação no código,
A capacidade de chamar JavaScript a C# partir do código.
A próxima seção apresenta o Razor, que torna mais fácil criar o HTML a ser usado em aplicativos híbridos.

O que é o Razor?
O Razor é um mecanismo de modelagem que foi introduzido com o ASP.NET MVC, originalmente para execução
no servidor e geração de HTML para ser servido em navegadores da Web.
O mecanismo de modelagem do Razor estende a sintaxe C# HTML padrão com para que você possa expressar o
layout e incorporar folhas de estilo CSS e JavaScript com facilidade. O modelo pode fazer referência a uma
classe de modelo, que pode ser qualquer tipo personalizado e cujas propriedades possam ser acessadas
diretamente do modelo. Uma de suas principais vantagens é a capacidade de misturar HTML e C# sintaxe com
facilidade.
Os modelos do Razor não estão limitados ao uso do lado do servidor, eles também podem ser incluídos em
aplicativos Xamarin. Usar modelos do Razor junto com a capacidade de trabalhar com exibições da Web
programaticamente permite que aplicativos híbridos entre plataformas sofisticados sejam criados com o
Xamarin.
Noções básicas do modelo Razor
Os arquivos de modelo do Razor têm uma extensão de arquivo . cshtml . Eles podem ser adicionados a um
projeto do Xamarin da seção modelagem de texto na caixa de diálogo novo arquivo :

Um modelo Razor simples ( RazorView. cshtml ) é mostrado abaixo.

@model string
<html>
<body>
<h1>@Model</h1>
</body>
</html>

Observe as seguintes diferenças de um arquivo HTML regular:


O símbolo de @ tem um significado especial em modelos do Razor – ele indica que a C# expressão a seguir
deve ser avaliada.
@model diretiva sempre aparece como a primeira linha de um arquivo de modelo do Razor.
A diretiva @model deve ser seguida por um tipo. Neste exemplo, uma cadeia de caracteres simples está
sendo passada para o modelo, mas pode ser qualquer classe personalizada.
Quando @Model é referenciado em todo o modelo, ele fornece uma referência ao objeto passado para o
modelo quando ele é gerado (neste exemplo, ele será uma cadeia de caracteres).
O IDE gerará automaticamente a classe Partial para modelos (arquivos com a extensão . cshtml ). Você pode
exibir esse código, mas ele não deve ser editado. a classe Partial é denominada RazorView
para corresponder ao nome do arquivo de modelo. cshtml. É esse nome que é usado para fazer referência ao
modelo no C# código.
@using instruções também podem ser incluídas na parte superior de um modelo do Razor para incluir
namespaces adicionais.
A saída HTML final pode então ser gerada com o código C# a seguir. Observe que especificamos que o modelo é
uma cadeia de caracteres "Olá, Mundo", que será incorporada à saída do modelo renderizado.

var template = new RazorView () { Model = "Hello World" };


var page = template.GenerateString ();

Aqui está a saída mostrada em uma exibição da Web no simulador de iOS e Android Emulator:

Mais sintaxe do Razor


Nesta seção, vamos introduzir algumas sintaxe Razor básicas para ajudá-lo a começar a usá-la. Os exemplos
nesta seção preenchem a seguinte classe com dados e as exibem usando o Razor:

public class Monkey {


public string Name { get; set; }
public DateTime Birthday { get; set; }
public List<string> FavoriteFoods { get; set; }
}

Todos os exemplos usam o seguinte código de inicialização de dados

var animal = new Monkey {


Name = "Rupert",
Birthday=new DateTime(2011, 04, 01),
FavoriteFoods = new List<string>
{"Bananas", "Banana Split", "Banana Smoothie"}
};

Exibindo Propriedades do modelo


Quando o modelo é uma classe com propriedades, eles são facilmente referenciados no modelo Razor,
conforme mostrado neste modelo de exemplo:

@model Monkey
<html>
<body>
<h1>@Model.Name</h1>
<p>Birthday: @(Model.Birthday.ToString("d MMMM yyyy"))</p>
</body>
</html>

Isso pode ser processado para uma cadeia de caracteres usando o seguinte código:

var template = new RazorView () { Model = animal };


var page = template.GenerateString ();

A saída final é mostrada aqui em uma exibição da Web no simulador de iOS e Android Emulator:
C#instruções
Mais complexo C# pode ser incluído no modelo, como as atualizações de propriedade de modelo e o cálculo de
idade neste exemplo:

@model Monkey
<html>
<body>
@{
Model.Name = "Rupert X. Monkey";
Model.Birthday = new DateTime(2011,3,1);
}
<h1>@Model.Name</h1>
<p>Birthday: @Model.Birthday.ToString("d MMMM yyyy")</p>
<p>Age: @(Math.Floor(DateTime.Now.Date.Subtract (Model.Birthday.Date).TotalDays/365)) years old</p>
</body>
</html>

Você pode gravar expressões de linha C# única complexas (como formatar a idade) ao redor do código com
@() .

Várias C# instruções podem ser escritas ao redor delas com @{} .


Instruções if-else
As ramificações de código podem ser expressas com @if conforme mostrado neste exemplo de modelo.

@model Monkey
<html>
<body>
<h1>@Model.Name</h1>
<p>Birthday: @(Model.Birthday.ToString("d MMMM yyyy"))</p>
<p>Age: @(Math.Floor(DateTime.Now.Date.Subtract (Model.Birthday.Date).TotalDays/365)) years old</p>
<p>Favorite Foods:</p>
@if (Model.FavoriteFoods.Count == 0) {
<p>No favorites</p>
} else {
<p>@Model.FavoriteFoods.Count favorites</p>
}
</body>
</html>

Loops
Construções de loop como foreach também podem ser adicionadas. O prefixo de @ pode ser usado na
variável de loop ( @food nesse caso) para renderizá-lo em HTML.
@model Monkey
<html>
<body>
<h1>@Model.Name</h1>
<p>Birthday: @Model.Birthday.ToString("d MMMM yyyy")</p>
<p>Age: @(Math.Floor(DateTime.Now.Date.Subtract (Model.Birthday.Date).TotalDays/365)) years old</p>
<p>Favorite Foods:</p>
@if (Model.FavoriteFoods.Count == 0) {
<p>No favorites</p>
} else {
<ul>
@foreach (var food in @Model.FavoriteFoods) {
<li>@food</li>
}
</ul>
}
</body>
</html>

A saída do modelo acima é mostrada em execução no simulador de iOS e Android Emulator:

Esta seção abordou os conceitos básicos do uso de modelos do Razor para renderizar exibições simples
somente leitura. A próxima seção explica como criar aplicativos mais completos usando o Razor que pode
aceitar a entrada do usuário e interoperar entre JavaScript na exibição HTML e C#.

Usando modelos do Razor com o Xamarin


Esta seção explica como usar o compilar seu próprio aplicativo híbrido usando os modelos de solução no Visual
Studio para Mac. Há três modelos disponíveis no arquivo > nova solução de >... janela:
Aplicativo de > Android > aplicativos Android WebView
Aplicativo iOS > > aplicação WebView
Projeto MVC do ASP.NET
A nova janela de solução tem esta aparência para projetos iPhone e Android-a descrição da solução na direita
realça o suporte para o mecanismo de modelagem do Razor.
Observe que você pode adicionar facilmente um modelo do Razor . cshtml a qualquer projeto Xamarin
existente, não é necessário usar esses modelos de solução. os projetos do iOS não exigem um Storyboard para
usar o Razor; Basta adicionar um controle UIWebView a qualquer modo de exibição programaticamente e você
poderá renderizar todos os modelos Razor no C# código.
O conteúdo da solução de modelo padrão para projetos do iPhone e do Android é mostrado abaixo:

Os modelos fornecem uma infraestrutura de aplicativo pronta para uso para carregar um modelo do Razor com
um objeto de modelo de dados, processar a entrada do usuário e se comunicar de volta com o usuário via
JavaScript.
As partes importantes da solução são:
Conteúdo estático, como o arquivo Style. css .
Arquivos de modelo Razor. cshtml como RazorView. cshtml .
Classes de modelo que são referenciadas nos modelos do Razor, como ExampleModel.cs .
A classe específica da plataforma que cria a exibição da Web e renderiza o modelo, como o MainActivity no
Android e o iPhoneHybridViewController no iOS.

A seção a seguir explica como os projetos funcionam.


Conteúdo Estático
O conteúdo estático inclui folhas de estilo CSS, imagens, arquivos JavaScript ou outro conteúdo que pode ser
vinculado ou referenciado por um arquivo HTML que está sendo exibido em uma exibição da Web.
Os projetos de modelo incluem uma folha de estilos mínima para demonstrar como incluir conteúdo estático
em seu aplicativo híbrido. A folha de estilos CSS é referenciada no modelo como este:

<link rel="stylesheet" href="style.css" />

Você pode adicionar qualquer folha de estilos e arquivos JavaScript necessários, incluindo estruturas como
JQuery.
Modelos Razor cshtml
O modelo inclui um arquivo Razor . cshtml que tem código pré-gravados para ajudar a comunicar dados entre
o HTML/JavaScript e C#o. Isso permitirá que você crie aplicativos híbridos sofisticados que não apenas exibem
dados somente leitura do modelo, mas também aceitam entrada de usuário no HTML e os retransmitem ao C#
código para processamento ou armazenamento.
Renderizando o modelo
Chamar o GenerateString em um modelo renderiza o HTML pronto para exibição em uma exibição da Web. Se
o modelo usar um modelo, ele deverá ser fornecido antes da renderização. Este diagrama ilustra como funciona
a renderização – não que os recursos estáticos são resolvidos pela exibição da Web em tempo de execução,
usando o diretório base fornecido para localizar os arquivos especificados.

Código C# de chamada do modelo


A comunicação de uma exibição da Web renderizada C# voltando para é feita definindo a URL para a exibição
da Web e, em seguida, interceptando a solicitação no C# para lidar com a solicitação nativa sem recarregar o
modo de exibição da Web.
Um exemplo pode ser visto no modo como o botão RazorView é manipulado. O botão tem o seguinte HTML:

<input type="button" name="UpdateLabel" value="Click" onclick="InvokeCSharpWithFormValues(this)" />

O InvokeCSharpWithFormValuesfunção JavaScript lê todos os valores do formulário HTML e define o


location.href para o modo de exibição da Web:

location.href = "hybrid:" + elm.name + "?" + qs;

Isso tenta navegar na exibição da Web para uma URL com um esquema personalizado (por exemplo, hybrid: )

hybrid:UpdateLabel?textbox=SomeValue&UpdateLabel=Click

Quando a exibição da Web nativa processa essa solicitação de navegação, temos a oportunidade de interceptá-
la. No iOS, isso é feito manipulando o evento HandleShouldStartLoad do UIWebView. No Android,
simplesmente criamos uma subclasse da WebViewClient usada no formulário e substituem
ShouldOverrideUrlLoading.
Os elementos internos desses dois interceptadores de navegação são essencialmente os mesmos.
Primeiro, verifique a URL que a exibição da Web está tentando carregar e, se ela não começar com o esquema
personalizado ( hybrid: ), permita que a navegação ocorra normalmente.
Para o esquema de URL personalizado, tudo na URL entre o esquema e o "?" é o nome do método a ser
manipulado (neste caso, "UpdateLabel"). Tudo na cadeia de caracteres de consulta será tratado como os
parâmetros para a chamada do método:

var resources = url.Substring(scheme.Length).Split('?');


var method = resources [0];
var parameters = System.Web.HttpUtility.ParseQueryString(resources[1]);

UpdateLabel neste exemplo faz uma quantidade mínima de manipulação de cadeia de caracteres no parâmetro
TextBox (prependenteC# "diz" para a cadeia de caracteres) e, em seguida, retorna à exibição da Web.
Depois de manipular a URL, o método anula a navegação para que a exibição da Web não tente terminar de
navegar para a URL personalizada.
Manipulando o modelo a partir de C#
A comunicação com uma exibição da Web HTML C# renderizada a partir do é feita chamando JavaScript na
exibição da Web. No iOS, isso é feito chamando EvaluateJavascript no UIWebView:

webView.EvaluateJavascript (js);

No Android, o JavaScript pode ser invocado no modo de exibição da Web carregando o JavaScript como uma
URL usando o esquema de URL "javascript:" :

webView.LoadUrl ("javascript:" + js);

Tornando um aplicativo realmente híbrido


Esses modelos não fazem uso de controles nativos em cada plataforma – a tela inteira é preenchida com uma
única exibição da Web.
O HTML pode ser ótimo para o protótipo e exibir os tipos de coisas que a Web é melhor, como Rich Text e layout
responsivo. No entanto, nem todas as tarefas são adequadas para HTML e JavaScript – rolar por longas listas de
dados, por exemplo, executa melhor usando controles nativos da interface do usuário (como UITableView no
iOS ou ListView no Android).
As exibições da Web no modelo podem ser facilmente aumentadas com controles específicos da plataforma –
basta editar o MainStor yboard. Stor yboard no designer do Ios ou os recursos/layout/Main. axml no
Android.
Exemplo de RazorTodo
O repositório RazorTodo contém duas soluções separadas para mostrar as diferenças entre um aplicativo
baseado em HTML completo e um aplicativo que combina HTML com controles nativos:
RazorTodo – aplicativo baseado em HTML completo usando modelos do Razor.
RazorNativeTodo -usa controles de exibição de lista nativa para IOS e Android, mas exibe a tela de edição
com HTML e Razor.
Esses aplicativos Xamarin são executados no iOS e no Android, utilizando PCLs (bibliotecas de classe portátil)
para compartilhar um código comum, como as classes de banco de dados e modelo. Os modelos Razor .
cshtml também podem ser incluídos no PCL para que eles sejam facilmente compartilhados entre plataformas.
Ambos os aplicativos de exemplo incorporam o compartilhamento do Twitter e as APIs de conversão de texto
em fala da plataforma nativa, demonstrando que aplicativos híbridos com o Xamarin ainda têm acesso a toda a
funcionalidade subjacente de exibições controladas por modelo do Razor em HTML.
O aplicativo RazorTodo usa modelos do Razor em HTML para a lista e edita modos de exibição. Isso significa
que podemos criar o aplicativo quase que completamente em uma biblioteca de classes portátil compartilhada
(incluindo os modelos de banco de dados e . cshtml Razor). As capturas de tela abaixo mostram os aplicativos
iOS e Android.

O aplicativo RazorNativeTodo usa um modelo HTML Razor para o modo de exibição de edição, mas
implementa uma lista de rolagem nativa em cada plataforma. Isso fornece vários benefícios, incluindo:
Desempenho-os controles de rolagem nativos usam a virtualização para garantir a rolagem rápida e suave,
mesmo com listas muito longas de dados.
Experiência nativa-os elementos da interface do usuário específicos da plataforma são facilmente habilitados,
como o suporte ao índice de rolagem rápida no iOS e no Android.
Um dos principais benefícios da criação de aplicativos híbridos com o Xamarin é que você pode começar com
uma interface de usuário totalmente controlada por HTML (como o primeiro exemplo) e adicionar
funcionalidade específica da plataforma quando necessário (como o segundo exemplo mostra). As telas de lista
nativa e as telas de edição do Razor do HTML no iOS e no Android são mostradas abaixo.
Resumo
Este artigo explicou os recursos dos controles de exibição da Web disponíveis no iOS e no Android que facilitam
a criação de aplicativos híbridos.
Em seguida, discutimos o mecanismo de modelagem do Razor e a sintaxe que pode ser usada para gerar HTML
facilmente em aplicativos Xamarin usando o. cshtml Arquivos de modelo Razor. Ele também descreveu os
modelos de solução Visual Studio para Mac que permitem que você comece rapidamente a criar aplicativos
híbridos com o Xamarin.
Por fim, ele introduziu os exemplos de RazorTodo que demonstram como combinar exibições da Web com
interfaces de usuário nativas e APIs.
Links relacionados
Exemplo de RazorTodo
MVC 3 – mecanismo de exibição do Razor (Microsoft)
Introdução à programação da Web do ASP.NET usando a sintaxe do Razor (Microsoft)
Desempenho e segurança
23/04/2020 • 2 minutes to read • Edit Online

Desempenho de plataforma cruzada


Há muitas técnicas para aumentar o desempenho dos aplicativos compilados com a plataforma Xamarin.
Coletivamente, essas técnicas podem reduzir de forma considerável a quantidade de trabalho que está sendo
executado por uma CPU e a quantidade de memória consumida por um aplicativo.
Desempenho do Android
Desempenho do iOS
Desempenho do Mac

Protocolo TLS
Verifique se os aplicativos estão usando as configurações de segurança recomendadas, como TLS 1.2.
Android
iOS e Mac
Desempenho de plataforma cruzada
02/11/2020 • 34 minutes to read • Edit Online

O baixo desempenho de aplicativo se apresenta de várias maneiras. Ele pode fazer com que o aplicativo pareça
não responder, deixar a rolagem lenta ou reduzir a vida útil da bateria. No entanto, a otimização do desempenho
engloba mais do que apenas a implementação de um código eficiente. A experiência do usuário quanto ao
desempenho do aplicativo também deve ser considerada. Por exemplo, garantir que as operações sejam
executadas sem impedir o usuário de realizar outras atividades pode ajudar a melhorar a experiência do
usuário.

Usar o Profiler
Ao desenvolver um aplicativo, é importante tentar otimizar código apenas após ele ter sido analisado. Criação
de perfil é uma técnica para determinar onde as otimizações de código terão o maior efeito na redução de
problemas de desempenho. O criador de perfil controla o uso de memória do aplicativo e registra o tempo de
execução dos métodos no aplicativo. Esses dados ajudam a navegar pelos caminhos de execução do aplicativo e
o custo da execução do código, para que as melhores oportunidades de otimização possam ser descobertas.
O Xamarin Profiler medirá, avaliará e ajudará a localizar problemas relacionados ao desempenho em um
aplicativo. Ele pode ser usado para analisar aplicativos Xamarin.iOS e Xamarin.Android do Visual Studio para
Mac ou Visual Studio. Para obter mais informações sobre o Xamarin Profiler, veja Introdução ao Xamarin
Profiler.
As melhores práticas a seguir são recomendadas ao analisar um aplicativo:
Evite a criação de perfil de um aplicativo em um simulador, pois o simulador pode distorcer o desempenho
do aplicativo.
Idealmente, a criação de perfil deve ser executada em uma variedade de dispositivos, pois tomar medidas de
desempenho em um único dispositivo nem sempre mostrará as características de desempenho de outros
dispositivos. No entanto, no mínimo, de criação de perfil deve ser executada em um dispositivo que tem a
menor especificação antecipada.
Feche todos os outros aplicativos para garantir que o impacto total do aplicativo que está sendo analisado
está sendo medido, em vez de o de outros aplicativos.

Liberar recursos IDisposable


A interface IDisposable fornece um mecanismo para liberar recursos. Ele fornece um método Dispose que
deve ser implementado para liberar recursos explicitamente. IDisposable não é um destruidor e só deve ser
implementado nas seguintes circunstâncias:
Quando a classe tem recursos não gerenciados. Recursos não gerenciados típicos que exigem liberação
incluem arquivos, fluxos e conexões de rede.
Quando a classe tem recursos IDisposable gerenciados.
Os consumidores de tipo podem chamar a implementação IDisposable.Dispose para liberar recursos quando a
instância não é mais necessária. Há duas abordagens para fazer isso:
Encapsulando o objeto IDisposable em uma instrução using .
Encapsulando a chamada IDisposable.Dispose em um bloco try / finally .
Encapsulando o objeto IDisposable em uma instrução using
O exemplo de código a seguir mostra como encapsular um objeto IDisposable em uma instrução using :

public void ReadText (string filename)


{
...
string text;
using (StreamReader reader = new StreamReader (filename)) {
text = reader.ReadToEnd ();
}
...
}

A classe StreamReader implementa IDisposable e a instrução using fornece uma sintaxe conveniente, que
chama o método StreamReader.Dispose no objeto StreamReader antes que ele saia do escopo. Dentro do bloco
using , o objeto StreamReader é somente leitura e não pode ser reatribuído. A instrução using garante que o
método Dispose seja chamado mesmo se ocorrer uma exceção, pois o compilador implementa a IL (linguagem
intermediária) em um bloco try / finally .
Encapsulamento da chamada para IDisposable.Dispose em um bloco Try/Finally
O exemplo de código a seguir mostra como encapsular a chamada para IDisposable.Dispose em um bloco
try / finally :

public void ReadText (string filename)


{
...
string text;
StreamReader reader = null;
try {
reader = new StreamReader (filename);
text = reader.ReadToEnd ();
} finally {
if (reader != null) {
reader.Dispose ();
}
}
...
}

A classe StreamReader implementa IDisposable e o bloco finally chama o método StreamReader.Dispose


para liberar o recurso.
Para obter mais informações, veja Interface IDisposable.

Cancelar assinatura de eventos


Para evitar vazamentos de memória, os eventos devem ser cancelados antes que o objeto do assinante seja
descartado. Até que a assinatura do evento seja cancelada, o delegado para o evento no objeto de publicação
tem uma referência para o delegado que encapsula o manipulador de eventos do assinante. Desde que o objeto
de publicação contenha essa referência, a coleta de lixo não recuperará a memória do objeto de assinante.
O exemplo de código a seguir mostra como cancelar a assinatura de um evento:
public class Publisher
{
public event EventHandler MyEvent;

public void OnMyEventFires ()


{
if (MyEvent != null) {
MyEvent (this, EventArgs.Empty);
}
}
}

public class Subscriber : IDisposable


{
readonly Publisher publisher;

public Subscriber (Publisher publish)


{
publisher = publish;
publisher.MyEvent += OnMyEventFires;
}

void OnMyEventFires (object sender, EventArgs e)


{
Debug.WriteLine ("The publisher notified the subscriber of an event");
}

public void Dispose ()


{
publisher.MyEvent -= OnMyEventFires;
}
}

A classe Subscriber cancela a assinatura do evento em seu método Dispose .


Ciclos de referência também podem ocorrer ao usar manipuladores de eventos e sintaxe lambda, já que
expressões lambda podem fazer referência a objetos e mantê-los ativos. Portanto, uma referência para o
método anônimo pode ser armazenada em um campo e usada para cancelar a inscrição do evento, conforme
mostrado no exemplo de código a seguir:

public class Subscriber : IDisposable


{
readonly Publisher publisher;
EventHandler handler;

public Subscriber (Publisher publish)


{
publisher = publish;
handler = (sender, e) => {
Debug.WriteLine ("The publisher notified the subscriber of an event");
};
publisher.MyEvent += handler;
}

public void Dispose ()


{
publisher.MyEvent -= handler;
}
}

O campo handler mantém a referência para o método anônimo e é usado para assinatura e cancelamento de
assinatura do evento.
Usar referências fracas para impedir a criação de objetos imortais
NOTE
Os desenvolvedores iOS do devem revisar a documentação ao evitar referências circulares no iOS para garantir que seus
aplicativos usem a memória com eficiência.

Atrasar o custo de criação de objetos


A inicialização lenta pode ser usada para adiar a criação de um objeto até que ele seja usado pela primeira vez.
Essa técnica é usada principalmente para melhorar o desempenho, evitar a computação e reduzir os requisitos
de memória.
Considere o uso da inicialização lenta para objetos com custo de criação elevado nesses dois cenários:
O aplicativo não pode usar o objeto.
Outras operações caras devem ser concluídas antes que o objeto seja criado.
A classe Lazy<T> é usada para definir um tipo inicializado lentamente, conforme demonstrado no exemplo de
código a seguir:

void ProcessData(bool dataRequired = false)


{
Lazy<double> data = new Lazy<double>(() =>
{
return ParallelEnumerable.Range(0, 1000)
.Select(d => Compute(d))
.Aggregate((x, y) => x + y);
});

if (dataRequired)
{
if (data.Value > 90)
{
...
}
}
}

double Compute(double x)
{
...
}

A inicialização lenta ocorre na primeira vez que a propriedade Lazy<T>.Value é acessada. O tipo encapsulado é
criado e retornado no primeiro acesso, então é armazenado para eventuais acessos futuros.
Para obter mais informações sobre a inicialização lenta, veja Inicialização lenta.

Implementar operações assíncronas


O .NET fornece versões assíncronas de muitas de suas APIs. Ao contrário das APIs síncronas, as APIs assíncronas
certificam-se de que o thread de execução ativo nunca bloqueie o thread de chamada por uma quantidade
significativa de tempo. Portanto, ao chamar uma API do thread de interface do usuário, use a API assíncrona se
ela estiver disponível. Isso manterá o thread de interface do usuário desbloqueado, o que ajudará a melhorar a
experiência do usuário com o aplicativo.
Além disso, as operações de execução longa devem ser executadas em um thread em segundo plano, para
evitar o bloqueio do thread de interface do usuário. O .NET fornece as palavras-chave async e await que
permitem a gravação de código assíncrono, que executa operações de execução longa em um thread em
segundo plano e acessa os resultados após a conclusão. No entanto, embora as operações de execução longa
possam ser executadas de forma assíncrona com a palavra-chave await , isso não garante que a operação será
executada em um thread em segundo plano. Em vez disso, é possível fazer com que ela seja executada desse
modo passando a operação de execução longa para Task.Run , conforme mostrado no exemplo de código a
seguir:

public class FaceDetection


{
...
async void RecognizeFaceButtonClick(object sender, EventArgs e)
{
await Task.Run(() => RecognizeFace ());
...
}

async Task RecognizeFace()


{
...
}
}

O método RecognizeFace é executado em um thread em segundo plano, com o método


RecognizeFaceButtonClick esperando até que o método RecognizeFace seja concluído antes de continuar.
Operações de execução longa também devem dar suporte a cancelamento. Por exemplo, continuar a executar
uma operação de execução longa poderá tornar-se desnecessário se o usuário navegar dentro do aplicativo. O
padrão para implementar o cancelamento é o seguinte:
Crie uma instância de CancellationTokenSource . Essa instância gerenciará e enviará notificações de
cancelamento.
Passe o valor da propriedade CancellationTokenSource.Token para cada tarefa que deve ser cancelável.
Forneça um mecanismo para cada tarefa responder ao cancelamento.
Chame o método CancellationTokenSource.Cancel para fornecer uma notificação de cancelamento.

IMPORTANT
A classe CancellationTokenSource implementa a interface IDisposable e então o método
CancellationTokenSource.Dispose deve ser invocado uma vez que o trabalho com a instância
CancellationTokenSource for concluído.

Para obter mais informações, veja Visão geral do suporte assíncrono.

Usar o coletor de lixo SGen


Linguagens gerenciadas como o C# usam a coleta de lixo para recuperar a memória alocada para objetos que
não estão mais em uso. Os dois coletores de lixo usados pela plataforma Xamarin são:
SGen – esse é um coletor de lixo geracional e é o coletor de lixo padrão na plataforma Xamarin.
Boehm – esse é um coletor de lixo conservador, não geracional. É o coletor de lixo padrão usado para
aplicativos Xamarin.iOS que usam a API clássica.
SGen utiliza um dos três heaps para alocar espaço para objetos:
O Berçário – é onde os novos objetos pequenos são alocados. Quando o berçário ficar sem espaço,
ocorrerá uma coleta de lixo secundária. Todos os objetos ativos serão movidos para o heap principal.
Heap Principal – é aqui que são mantidos os objetos de execução longa. Se não houver memória suficiente
no heap principal, uma coleta de lixo principal ocorrerá. Se uma coleta de lixo principal falhar liberar em
memória suficiente, o SGen solicitará mais memória ao sistema.
Espaço de objeto grande – aqui são mantidos os objetos que exigem mais de 8.000 bytes. Objetos
grandes não começarão no berçário, mas em vez disso serão alocados nesse heap.
Uma das vantagens de SGen é que o tempo necessário para executar uma coleta de lixo secundária é
proporcional ao número de novos objetos ativos que foram criados desde a última coleta de lixo secundária.
Isso reduzirá o impacto de coleta de lixo sobre o desempenho de um aplicativo, porque essas coletas de lixo
secundárias levarão menos tempo do que uma coleta de lixo principal. Coletas de lixo principais ainda ocorrem,
mas com menos frequência.
O coletor de lixo do SGen é o padrão no Xamarin. iOS 9.2.1 e superior e, portanto, será usado automaticamente.
Observe que a capacidade de alterar o coletor de lixo foi removida das versões mais recentes do Visual Studio.
Para obter mais informações, consulte novo sistema de contagem de referência.
Redução da pressão sobre o coletor de lixo
Quando SGen inicia uma coleta de lixo, ele interromperá os threads do aplicativo enquanto ele recupera a
memória. Enquanto a memória está sendo recuperada, o aplicativo pode ter uma pequena pausa ou apresentar
intermitências na interface do usuário. O quão perceptível essa pausa é depende de dois fatores:
1. Frequência – frequência ocorre a coleta de lixo. A frequência de coletas de lixo aumentará à medida que
mais memória for alocada entre coletas.
2. Duração – quanto tempo levará cada coleta de lixo individual. Isso é aproximadamente proporcional ao
número de objetos ativos que estão sendo coletados.
Coletivamente, isso significa que, se vários objetos forem alocados, mas não permanecerem ativos, haverá
muitas coletas de lixo curtas. Por outro lado, se novos objetos forem alocados lentamente e os objetos
permanecerem ativos, haverá menos coletas de lixo, mas elas serão mais demoradas.
Para reduzir a pressão sobre o coletor de lixo, siga estas diretrizes:
Evite a coleta de lixo em loops apertados usando pools de objeto. Isso é particularmente relevante para
jogos, que precisam criar a maioria de seus objetos com antecedência.
Libere explicitamente recursos como fluxos, conexões de rede, blocos grandes de memória e arquivos
quando eles não forem mais necessários. Para obter mais informações, veja Liberar recursos IDisposable.
Cancele o registro de manipuladores de eventos quando eles não forem mais necessários para tornar os
objetos colecionáveis. Para obter mais informações, consulte Unsubscribe from Events (Cancelar assinatura
de eventos).

Reduzir o tamanho do aplicativo


É importante compreender o processo de compilação em cada plataforma para entender de onde vem o
tamanho do executável de um aplicativo:
Aplicativos iOS passam por compilação AOT (Ahead Of Time) para linguagem assembly do ARM. O .NET
framework está incluído e as classes não utilizadas são eliminadas somente quando a opção de vinculador
apropriada está habilitada.
Aplicativos Android são compilados em IL (linguagem intermediária) e empacotados com o MonoVM e a
compilação JIT (Just-In-Time). Classes de estrutura não utilizadas são eliminadas somente quando a opção de
vinculador apropriada está habilitada.
Aplicativos do Windows Phone são compilados para IL e executados segundo o runtime interno.
Além disso, se um aplicativo fizer uso extensivo de genéricos, o tamanho final do executável aumentará ainda
mais, uma vez que ele conterá versões compiladas nativamente das possibilidades genéricas.
Para ajudar a reduzir o tamanho dos aplicativos, a plataforma Xamarin inclui um vinculador como parte das
ferramentas de build. Por padrão o vinculador está desabilitado e deve ser habilitado nas opções do projeto do
aplicativo. No momento do build, ele executará uma análise estática do aplicativo para determinar quais tipos e
membros são realmente usados pelo aplicativo. Ele então removerá quaisquer tipos e métodos não utilizados
do aplicativo.
A captura de tela a seguir mostra as opções do vinculador no Visual Studio para Mac para um projeto do
Xamarin.iOS:

A captura de tela a seguir mostra as opções do vinculador no Visual Studio para Mac para um projeto do
Xamarin.Android:
O vinculador fornece três diferentes configurações para controlar seu comportamento:
Não vincular – nenhum método nem tipo não utilizado será removido pelo vinculador. Por motivos de
desempenho, essa é a configuração padrão para builds de depuração.
Vincular somente Assemblies de SDKs/SDK da Estrutura – essa configuração reduzirá o tamanho
apenas dos assemblies que são enviados via Xamarin. O código do usuário não será afetado.
Vincular Todos os Assemblies – essa é uma otimização mais agressiva que tem como destino o código
do usuário e assemblies do SDK. Para associações, isso removerá os campos de suporte não utilizados e
tornará cada instância (ou objetos associados) mais leves, consumindo menos memória.
O Vincular Todos os Assemblies deve ser usado com cuidado, pois pode interromper o aplicativo de maneiras
inesperadas. A análise estática realizada pelo vinculador pode não identificar corretamente todo o código que é
necessário, resultando na remoção de uma quantidade excessiva de código do aplicativo compilado. Essa
situação se manifestará somente em runtime quando o aplicativo falhar. Por isso, é importante testar um
aplicativo depois de alterar o comportamento do vinculador.
Se o teste revelar que o vinculador removeu incorretamente uma classe ou método, será possível marcar tipos
ou métodos que não são referenciados estaticamente, mas são exigidos pelo aplicativo pelo uso de um dos
seguintes atributos:
Xamarin.iOS.Foundation.PreserveAttribute – esse atributo é para projetos Xamarin.iOS.
Android.Runtime.PreserveAttribute – esse atributo é para projetos Xamarin.Android.

Por exemplo, pode ser necessário preservar os construtores padrão de tipos que são instanciados
dinamicamente. Além disso, o uso da serialização XML pode exigir que as propriedades de tipos sejam
preservadas.
Para obter mais informações, veja Vinculador para iOS e Vinculador para Android.
Técnicas adicionais de redução de tamanho
Há uma grande variedade de arquiteturas de CPU que alimentam dispositivos móveis. Portanto, o Xamarin.iOS
e o Xamarin.Android produzem binários FAT, que contêm uma versão compilada do aplicativo para cada
arquitetura de CPU. Isso garante que um aplicativo móvel possa ser executado em um dispositivo,
independentemente da arquitetura da CPU.
As etapas a seguir podem ser usadas para reduzir ainda mais o tamanho do executável do aplicativo:
Certifique-se de que um build de versão é produzido.
Reduza o número de arquiteturas para as quais o aplicativo é compilado, para evitar que um binário FAT seja
produzido.
Certifique-se de que o compilador LLVM está sendo usado para gerar um executável mais otimizado.
Reduza o tamanho do código gerenciado do aplicativo. Isso pode ser feito habilitando o vinculador em cada
assembly (Vincular todos para projetos iOS e Vincular todos os assemblies para projetos Android).
Aplicativos Android também podem ser divididos em um APK separado para cada ABI ("arquitetura"). Saiba
mais nesta postagem de blog: How To Keep Your Android App Size Down (Como manter o tamanho de seu
aplicativo Android pequeno).

Otimizar os recursos de imagem


As imagens são alguns dos recursos mais caros que os aplicativos usam e, geralmente, são capturadas em alta
resolução. Enquanto isso cria imagens vibrantes cheias de detalhes, aplicativos que exibem tais imagens
normalmente exigem mais recursos da CPU para decodificar a imagem e mais memória para armazenar a
imagem decodificada. É dispendioso decodificar uma imagem de alta resolução na memória sendo que ele será
reduzido para um tamanho menor para exibição. Em vez disso, reduza o volume de memória e o uso de CPU
criando versões de imagens armazenadas com várias resoluções, próximas dos tamanhos de exibição previstos.
Por exemplo, uma imagem exibida em uma exibição de lista provavelmente deve ter uma resolução menor do
que uma imagem exibida em tela inteira. Além disso, versões reduzidas das imagens de alta resolução podem
ser carregadas para exibi-las de modo eficiente, com impacto mínimo sobre a memória. Para obter mais
informações, veja Loading Large Bitmaps Efficiently (Como carregar bitmaps de modo eficiente).
Independentemente da resolução da imagem, os recursos de imagem de exibição podem aumentar
significativamente o volume de memória do aplicativo. Portanto, eles só devem ser criados quando necessário e
devem ser liberados assim que o aplicativo não exigi-los mais.

Reduzir o período de ativação do aplicativo


Todos os aplicativos têm um período de ativação, que é o tempo entre quando o aplicativo é iniciado e quando o
aplicativo está pronto para uso. O período de ativação permite que os usuários tenham a primeira impressão do
aplicativo. Portanto, é importante reduzir o período de ativação e a percepção que os usuários têm dele, para
que o aplicativo cause uma primeira impressão favorável.
Antes de um aplicativo exibir sua interface do usuário inicial, ele deve fornecer uma tela inicial para indicar ao
usuário que o aplicativo está sendo iniciado. Se o aplicativo não puder exibir rapidamente sua interface do
usuário inicial, a tela inicial deverá usada para informar ao usuário o progresso durante o período de ativação, a
fim de oferecer uma garantia de que o aplicativo não parou. Essa garantia pode ser uma barra de progresso ou
um controle semelhante.
Durante o período de ativação os aplicativos executam a lógica de ativação, que geralmente inclui o
carregamento e o processamento de recursos. O período de ativação pode ser reduzido, garantindo que os
recursos necessários sejam empacotados no aplicativo, em vez de serem recuperados remotamente. Por
exemplo, em algumas circunstâncias, pode ser apropriado durante o período de ativação carregar dados de
espaço reservado armazenados localmente. Em seguida, depois que a interface do usuário inicial é exibida e o
usuário é capaz de interagir com o aplicativo, os dados de espaço reservado podem ser substituídos
progressivamente de uma fonte remota. Além disso, a lógica de ativação do aplicativo deve executar apenas o
trabalho necessário para permitir que o usuário comece a usar o aplicativo. Isso pode ajudar se atrasar o
carregamento de assemblies adicionais, já que assemblies são carregados na primeira vez em que eles são
usados.

Reduzir a comunicação de serviços Web


Conectar-se de um aplicativo a um serviço Web pode ter um impacto no desempenho do aplicativo. Por
exemplo, um aumento do uso da largura de banda de rede resultará em um aumento no uso da bateria do
dispositivo. Além disso, os usuários podem estar usando o aplicativo em um ambiente com largura de banda
limitada. Portanto, é sensato limitar a utilização de largura de banda entre um aplicativo e um serviço Web.
É uma abordagem para reduzir a utilização da largura de banda de um aplicativo é compactar os dados antes de
transferi-los por uma rede. No entanto, o uso adicional de CPU gerado pelo processo de compactação também
pode resultar em um uso maior da bateria. Portanto, essa compensação deve ser avaliada cuidadosamente
antes de decidir se é necessário mover os dados compactados por uma rede.
Outra questão a considerar é o formato dos dados que se movem entre um aplicativo e um serviço Web. Os
dois principais formatos são XML (Extensible Markup Language) e JSON (JavaScript Object Notation). XML é um
formato de troca de dados baseado em texto que gera conteúdos de dados relativamente grandes, porque ele
contém um grande número de caracteres de formatação. JSON é um formato de troca de dados baseado em
texto que gera conteúdos de dados compactos, o que resulta em redução de requisitos de largura de banda ao
enviar dados e receber dados. Portanto, JSON é geralmente o formato preferencial para aplicativos móveis.
Recomenda-se usar DTOs (objetos de transferência de dados) ao transferir dados entre um aplicativo e um
serviço Web. Um DTO contém um conjunto de dados para transferência pela rede. Utilizando DTOs, mais dados
podem ser transmitidos em uma única chamada remota, o que pode ajudar a reduzir o número de chamadas
remotas feitas pelo aplicativo. Em geral, a quantidade de tempo utilizada em uma chamada remota com um
conteúdo maior de dados é similar àquela utilizada em uma chamada que contém apenas um conteúdo de
dados pequeno.
Dados recuperados do serviço Web devem ser armazenados em cache localmente, com os dados armazenados
em cache sendo utilizados em vez de repetidamente recuperados do serviço Web. No entanto, ao adotar essa
abordagem, uma estratégia adequada de cache deve ser implementada para atualizar os dados no cache local
se eles forem alterados no serviço Web.

Resumo
Esse artigo descreve e discute técnicas para aumentar o desempenho dos aplicativos criados usando a
plataforma Xamarin. Coletivamente, essas técnicas podem reduzir de forma considerável a quantidade de
trabalho que está sendo executado por uma CPU e a quantidade de memória consumida por um aplicativo.

Links Relacionados
Desempenho do Xamarin. iOS
Desempenho do Xamarin.Android
Introdução ao Xamarin Profiler
Desempenho do Xamarin. Forms
Visão geral do suporte assíncrono
IDisposable
Melhorar o Xamarin.Forms desempenho do
aplicativo
02/11/2020 • 30 minutes to read • Edit Online

Evolua 2016: Otimizando o desempenho do aplicativo comXamarin.Forms


O baixo desempenho de aplicativo se apresenta de várias maneiras. Ele pode fazer com que o aplicativo pareça
não responder, deixar a rolagem lenta e reduzir a vida útil da bateria do dispositivo. No entanto, a otimização do
desempenho engloba mais do que apenas a implementação de um código eficiente. A experiência do usuário
quanto ao desempenho do aplicativo também deve ser considerada. Por exemplo, garantir que as operações
sejam executadas sem impedir o usuário de realizar outras atividades pode ajudar a melhorar a experiência do
usuário.
Há muitas técnicas para aumentar o desempenho e desempenho percebido dos Xamarin.Forms aplicativos.
Coletivamente, essas técnicas podem reduzir de forma considerável a quantidade de trabalho que está sendo
executado por uma CPU e a quantidade de memória consumida por um aplicativo.

NOTE
Antes de ler esse artigo, você deve primeiro ler Desempenho de plataforma cruzada, que discute técnicas específicas sem
plataforma para melhorar o uso de memória e o desempenho de aplicativos criados usando a plataforma Xamarin.

Habilitar o compilador de XAML


Opcionalmente, XAML pode ser compilado direto na IL (linguagem intermediária) com o compilador XAML
(XAMLC). XAMLC oferece vários benefícios:
Executa verificação de tempo de compilação de XAML, notificando o usuário de quaisquer erros.
Elimina parte da carga e do tempo de instanciação para elementos XAML.
Ajuda a reduzir o tamanho do arquivo do assembly final não incluindo mais arquivos .XAML.
O XAMLC é habilitado por padrão em novas Xamarin.Forms soluções. No entanto, talvez seja necessário
habilitá-lo em soluções mais antigas. Para saber mais, consulte Compilação de XAML.

Usar associações compiladas


Associações compiladas melhoram o desempenho de vinculação de dados em Xamarin.Forms aplicativos
resolvendo expressões de associação em tempo de compilação, em vez de em tempo de execução com reflexão.
A compilação de uma expressão de associação gera código compilado que normalmente resolve uma
associação 8 a 20 vezes mais rápido do que ao usar uma associação clássica. Para saber mais, confira
Associações compiladas.

Reduzir associações desnecessárias


Não use associações para conteúdo que pode ser facilmente definido estaticamente. Não há nenhuma
vantagem em associar dados que não precisam ser associados, pois associações não são econômicas. Por
exemplo, a configuração Button.Text = "Accept" tem menos sobrecarga do que Button.Text a associação a
uma propriedade ViewModel com o string valor "Accept".
Usar renderizadores rápidos
Renderizadores rápidos reduzem os custos de inflação e renderização de Xamarin.Forms controles no Android,
nivelando a hierarquia de controle nativo resultante. Isso aprimora o desempenho criando menos objetos, o que
resulta em uma árvore visual menos complexa e em menos uso de memória.
De Xamarin.Forms 4,0 em diante, todos os aplicativos destinados FormsAppCompatActivity a usar renderizadores
rápidos por padrão. Para obter mais informações, veja Renderizadores Rápidos.

Habilitar o rastreamento de inicialização no Android


A compilação AOT (Ahead of Time) no Android minimiza a sobrecarga e o uso de memória da inicialização de
aplicativo JIT (Just-in-Time), com o custo de criar um APK muito maior. Uma alternativa é usar o rastreamento de
inicialização, que proporciona uma compensação entre o tamanho do APK do Android e o tempo de
inicialização, quando comparado à compilação AOT convencional.
Em vez de compilar o máximo possível do aplicativo para código não-gerenciado, o rastreamento de
inicialização compila apenas o conjunto de métodos gerenciados que representam as partes mais caras da
inicialização do aplicativo em um Xamarin.Forms aplicativo em branco. Essa abordagem resulta na redução do
tamanho do APK, quando comparado à compilação AOT convencional, enquanto ainda fornece melhorias de
inicialização semelhantes.

Habilitar a compactação de layout


A compactação de layout remove os layouts especificados da árvore visual, em uma tentativa de melhorar o
desempenho de renderização da página. O benefício de desempenho que isso oferece varia dependendo da
complexidade de uma página, da versão do sistema operacional que está sendo usado e do dispositivo no qual
o aplicativo está sendo executado. No entanto, os maiores ganhos de desempenho serão observados em
versões mais antigas. Para obter mais informações, confira Layout de Compactação.

Escolher o layout correto


Um layout que é capaz de exibir vários filhos, mas que tem apenas um único filho, é um desperdício. Por
exemplo, o exemplo de código a seguir mostra um StackLayout com um único filho:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DisplayImage.HomePage">
<StackLayout>
<Image Source="waterfront.jpg" />
</StackLayout>
</ContentPage>

Isso é um desperdício e o StackLayout elemento deve ser removido, conforme mostrado no exemplo de código
a seguir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DisplayImage.HomePage">
<Image Source="waterfront.jpg" />
</ContentPage>

Além disso, não tente reproduzir a aparência de um layout específico usando combinações de outros layouts,
pois isso resulta na execução de cálculos de layout desnecessários. Por exemplo, não tente reproduzir um Grid
layout usando uma combinação de StackLayout instâncias. O código a seguir mostra um exemplo dessa má
prática:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Details.HomePage"
Padding="0,20,0,0">
<StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Name:" />
<Entry Placeholder="Enter your name" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Age:" />
<Entry Placeholder="Enter your age" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Occupation:" />
<Entry Placeholder="Enter your occupation" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Address:" />
<Entry Placeholder="Enter your address" />
</StackLayout>
</StackLayout>
</ContentPage>

Isso é um desperdício porque cálculos de layout desnecessário são executados. Em vez disso, o layout desejado
pode ser melhor obtido usando um Grid , conforme mostrado no exemplo de código a seguir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Details.HomePage"
Padding="0,20,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Text="Name:" />
<Entry Grid.Column="1" Placeholder="Enter your name" />
<Label Grid.Row="1" Text="Age:" />
<Entry Grid.Row="1" Grid.Column="1" Placeholder="Enter your age" />
<Label Grid.Row="2" Text="Occupation:" />
<Entry Grid.Row="2" Grid.Column="1" Placeholder="Enter your occupation" />
<Label Grid.Row="3" Text="Address:" />
<Entry Grid.Row="3" Grid.Column="1" Placeholder="Enter your address" />
</Grid>
</ContentPage>

Otimizar o desempenho do layout


Para obter o melhor desempenho possível do layout, siga estas diretrizes:
Reduza a profundidade das hierarquias de layout especificando Margin valores de propriedade, permitindo
a criação de layouts com menos exibições de quebra. Para saber mais, consulte Margens e preenchimento.
Ao usar um Grid , tente garantir que o menor número de linhas e colunas possível esteja definido como
Auto tamanho. Cada linha ou coluna dimensionada automaticamente fará o mecanismo de layout realizar
cálculos de layout adicionais. Em vez disso, use linhas e colunas de tamanho fixo, se possível. Como
alternativa, defina linhas e colunas para ocupar uma quantidade proporcional de espaço com o valor de
GridUnitType.Star enumeração, desde que a árvore pai Siga estas diretrizes de layout.
Não defina as VerticalOptions HorizontalOptions Propriedades e de um layout, a menos que necessário. Os
valores padrão de LayoutOptions.Fill e LayoutOptions.FillAndExpand permitem a melhor otimização de
layout. Alterar essas propriedades tem um custo e consome memória, mesmo ao configurá-las como os
valores padrão.
Evite usar um RelativeLayout sempre que possível. Isso resultará em a CPU precisar realizar
significativamente mais trabalho.
Ao usar um AbsoluteLayout , evite usar a AbsoluteLayout.AutoSize propriedade sempre que possível.
Ao usar um StackLayout , verifique se apenas um filho está definido como LayoutOptions.Expands . Essa
propriedade garante que o filho especificado ocupe o maior espaço que o StackLayout pode dar a ele e é
um desperdício executar esses cálculos mais de uma vez.
Evite chamar qualquer um dos métodos da Layout classe, pois eles resultam na execução de cálculos de
layout caros. Em vez disso, é provável que o comportamento de layout desejado possa ser obtido definindo
TranslationX as TranslationY Propriedades e. Como alternativa, subclasse a Layout<View> classe para
obter o comportamento de layout desejado.
Não atualize nenhuma Label instância com mais frequência do que o necessário, pois a alteração do
tamanho do rótulo pode resultar em todo o layout da tela sendo recalculado.
Não defina a Label.VerticalTextAlignment propriedade, a menos que seja necessário.
Defina o LineBreakMode de qualquer Label instância para NoWrap sempre que possível.

usar programação assíncrona


A capacidade de resposta geral do seu aplicativo pode ser aprimorada e os gargalos de desempenho
geralmente são evitados usando a programação assíncrona. No .NET, o padrão assíncrono baseado em tarefa
(toque) é o padrão de design recomendado para operações assíncronas. No entanto, o uso incorreto do TAP
pode resultar em aplicativos não executados. Portanto, as diretrizes a seguir devem ser seguidas ao usar o
toque.
Conceitos básicos
Entenda o ciclo de vida da tarefa, que é representado pela TaskStatus enumeração. Para obter mais
informações, consulte o significado de TaskStatus e status da tarefa.
Use o Task.WhenAll método para aguardar assincronamente que várias operações assíncronas sejam
concluídas, em vez de await uma série de operações assíncronas individualmente. Para obter mais
informações, consulte Task. WhenAll.
Use o Task.WhenAny método para aguardar de forma assíncrona que uma de várias operações
assíncronas seja concluída. Para obter mais informações, consulte Task. WhenAny.
Use o Task.Delay método para produzir um Task objeto que termina após o tempo especificado. Isso é
útil para cenários como sondagem de dados e atraso de manipulação de entrada do usuário para um
tempo predeterminado. Para obter mais informações, consulte Task. Delay.
Execute operações de CPU síncrona intensivas no pool de threads com o Task.Run método. Esse método
é um atalho para o TaskFactory.StartNew método, com os argumentos mais ideais definidos. Para obter
mais informações, consulte Task. Run.
Evite tentar criar construtores assíncronos. Em vez disso, use eventos de ciclo de vida ou lógica de
inicialização separada para await qualquer inicialização corretamente. Para obter mais informações,
consulte construtores assíncronos em blog.stephencleary.com.
Use o padrão de tarefa lenta para evitar esperar que operações assíncronas sejam concluídas durante a
inicialização do aplicativo. Para obter mais informações, consulte AsyncLazy.
Crie um wrapper de tarefa para operações assíncronas existentes, que não usam o TAP, criando
TaskCompletionSource<T> objetos. Esses objetos têm os benefícios da Task programação e permitem
controlar o tempo de vida e a conclusão do associado Task . Para obter mais informações, consulte a
natureza de TaskCompletionSource.
Retornar um Task objeto, em vez de retornar um Task objeto esperado, quando não for necessário
processar o resultado de uma operação assíncrona. Isso é mais eficaz devido à execução de menos
alternância de contexto.
Use a biblioteca de Dataflow da TPL (biblioteca paralela de tarefas) em cenários como processamento de
dados conforme ele se tornar disponível ou quando você tiver várias operações que devem se comunicar
entre si de forma assíncrona. Para obter mais informações, consulte fluxo de dados (biblioteca paralela de
tarefas).
UI
Chamar uma versão assíncrona de uma API, se ela estiver disponível. Isso manterá o thread de interface
do usuário desbloqueado, o que ajudará a melhorar a experiência do usuário com o aplicativo.
Atualize os elementos da interface do usuário com dados de operações assíncronas no thread da
interface do usuário, para evitar que exceções sejam geradas. No entanto, as atualizações para a
ListView.ItemsSource propriedade serão automaticamente empacotadas para o thread da interface do
usuário. Para obter informações sobre como determinar se o código está em execução no thread da
interface do usuário, consulte Xamarin.Essentials : MainThread.

IMPORTANT
Todas as propriedades de controle que são atualizadas por meio da ligação de dados serão automaticamente
empacotadas para o thread da interface do usuário.

Tratamento de erros
Saiba mais sobre a manipulação de exceção assíncrona. As exceções sem tratamento que são geradas pelo
código que está sendo executado de forma assíncrona são propagadas de volta para o thread de chamada,
exceto em determinados cenários. Para obter mais informações, consulte tratamento de exceção (biblioteca
paralela de tarefas).
Evite criar async void métodos e, em vez disso, criar async Task métodos. Isso permite o tratamento de
erros, a capacidade de composição e a possibilidade de teste mais fáceis. A exceção a essa diretriz são os
manipuladores de eventos assíncronos, que devem retornar void . Para obter mais informações, consulte
evitar Async void.
Não misture o bloqueio e o código assíncrono chamando Task.Wait os Task.Result métodos, ou
GetAwaiter().GetResult , pois eles podem resultar na ocorrência de deadlock. No entanto, se essa diretriz
precisar ser violada, a abordagem preferida será chamar o GetAwaiter().GetResult método porque preserva
as exceções da tarefa. Para obter mais informações, consulte Async All The e tratamento de exceção de tarefa
no .NET 4,5.
Use o ConfigureAwait método sempre que possível, para criar código sem contexto. O código sem contexto
tem um melhor desempenho para aplicativos móveis e é uma técnica útil para evitar o deadlock ao trabalhar
com uma base de código parcialmente assíncrona. Para obter mais informações, consulte Configurar
contexto.
Use tarefas de continuação para funcionalidades como a manipulação de exceções lançadas pela operação
assíncrona anterior e a cancelamento de uma continuação antes que ela seja iniciada ou enquanto estiver em
execução. Para obter mais informações, consulte encadeando tarefas usando tarefas contínuas.
Use uma implementação assíncrona ICommand quando operações assíncronas forem invocadas do ICommand
. Isso garante que qualquer exceção na lógica de comando assíncrono possa ser tratada. Para obter mais
informações, consulte programação assíncrona: padrões para aplicativos MVVM assíncronos: comandos.

Escolha o contêiner de injeção de dependência com cuidado


Contêineres de injeção de dependência introduzem restrições de desempenho adicionais em aplicativos móveis.
Efetuar o registro e a resolução de tipos usando um contêiner tem um custo de desempenho devido ao uso da
reflexão pelo contêiner para criar cada tipo, especialmente se as dependências estiverem sendo reconstruídas
para cada navegação de página no aplicativo. Se houver muitas dependências ou se elas forem profundas, o
custo da criação poderá aumentar significativamente. Além disso, o registro de tipo, que geralmente ocorre
durante a inicialização do aplicativo, pode ter um impacto perceptível sobre o tempo de inicialização
dependendo do contêiner que está sendo usado.
Como alternativa, a injeção de dependência pode se tornar mais eficaz por meio da implementação manual
usando fábricas.

Criar aplicativos de Shell


Xamarin.FormsOs aplicativos de shell fornecem uma experiência de navegação conceituada com base em
submenus e guias. Se a experiência do usuário do aplicativo puder ser implementada com Shell, será benéfico
fazê-lo. Aplicativos de Shell ajudam a evitar uma experiência de inicialização ruim, pois as páginas são criadas
sob demanda em resposta à navegação, e não na inicialização do aplicativo, o que ocorre com aplicativos que
usam uma `TabbedPage'. Para obter mais informações, consulte Xamarin.Forms shell.

Usar CollectionView em vez de ListView


CollectionView é uma exibição para apresentar listas de dados usando especificações de layout diferentes. Ele
fornece uma alternativa mais flexível e de alto desempenho para o ListView . Para obter mais informações,
consulte Xamarin.Forms CollectionView.

Otimizar o desempenho da ListView


Ao usar ListView o, há várias experiências de usuário que devem ser otimizadas:
Inicialização – o intervalo de tempo que começa quando o controle é criado e termina quando itens são
mostrados na tela.
Rolagem – a capacidade de rolar pela lista e garantir que a interface do usuário não fique atrasada com
relação a gestos de toque.
Interação para adicionar, excluir e selecionar itens.
O ListView controle requer um aplicativo para fornecer dados e modelos de célula. Como isso é feito terá um
grande impacto sobre o desempenho do controle. Para obter mais informações, consulte Desempenho da
ListView.

Otimizar os recursos de imagem


Exibir recursos de imagem pode aumentar significativamente o volume de memória de um aplicativo. Portanto,
eles só devem ser criados quando necessário e devem ser liberados assim que o aplicativo não exigi-los mais.
Por exemplo, se um aplicativo estiver exibindo uma imagem lendo seus dados de um fluxo, certifique-se de que
esse fluxo seja criado somente quando necessário e liberado quando não for mais necessário. Isso pode ser feito
criando o fluxo quando a página é criada, ou quando o Page.Appearing evento é acionado e, em seguida,
descartando o fluxo quando o Page.Disappearing evento é acionado.
Ao baixar uma imagem para exibição com o ImageSource.FromUri método, armazene em cache a imagem
baixada, assegurando que a UriImageSource.CachingEnabled Propriedade esteja definida como true . Para saber
mais, consulte Trabalhando com imagens.
Para saber mais, consulte Otimizar recursos de imagem.

Reduzir o tamanho da árvore visual


Reduzir o número de elementos em uma página tornará a renderização da página mais rápida. Há duas técnicas
principais para realizar essa tarefa. A primeira é ocultar elementos que não estão visíveis. A IsVisible
propriedade de cada elemento determina se o elemento deve ser parte da árvore visual ou não. Portanto, se um
elemento não estiver visível porque está oculto atrás de outros elementos, remova o elemento ou defina sua
propriedade IsVisible como false .
A segunda técnica é remover elementos desnecessários. Por exemplo, o exemplo de código a seguir mostra um
layout de página que contém vários Label objetos:

<StackLayout>
<StackLayout Padding="20,20,0,0">
<Label Text="Hello" />
</StackLayout>
<StackLayout Padding="20,20,0,0">
<Label Text="Welcome to the App!" />
</StackLayout>
<StackLayout Padding="20,20,0,0">
<Label Text="Downloading Data..." />
</StackLayout>
</StackLayout>

O mesmo layout da página poderá ser mantido com uma contagem de elementos reduzida, conforme mostrado
no exemplo de código a seguir:

<StackLayout Padding="20,35,20,20" Spacing="25">


<Label Text="Hello" />
<Label Text="Welcome to the App!" />
<Label Text="Downloading Data..." />
</StackLayout>

Reduzir o tamanho do dicionário de recursos do aplicativo


Todos os recursos usados em todo o aplicativo devem ser armazenados no dicionário de recursos do aplicativo
para evitar duplicação. Isso ajudará a reduzir a quantidade de XAML que precisa ser analisada em todo o
aplicativo. O seguinte exemplo de código mostra o recurso HeadingLabelStyle , que é usado em todo o
aplicativo e então é definido no dicionário de recursos do aplicativo:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Resources.App">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="HeadingLabelStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Red" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>

No entanto, o XAML específico de uma página não deve ser incluído no dicionário de recursos do aplicativo,
uma vez que os recursos então serão analisados na inicialização do aplicativo, em vez de quando exigido por
uma página. Se um recurso for usado por uma página que não seja a página de inicialização, ele deverá ser
colocado no dicionário de recursos para essa página, ajudando, assim, a reduzir o XAML analisado quando o
aplicativo é iniciado. O seguinte exemplo de código mostra o recurso HeadingLabelStyle , que está em apenas
uma única página e então é definido no dicionário de recursos da página:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Test.HomePage"
Padding="0,20,0,0">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="HeadingLabelStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Red" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>

Para saber mais sobre os recursos de aplicativo, consulte Estilos de XAML.

Usar o padrão de renderizador personalizado


A maioria das Xamarin.Forms classes de renderizador expõe o OnElementChanged método, que é chamado
quando um Xamarin.Forms controle personalizado é criado para renderizar o controle nativo correspondente.
Então, classes de renderizador personalizadas em cada projeto da plataforma substituem esse método para
instanciar e personalizar o controle nativo. O método SetNativeControl é usado para instanciar o controle
nativo e esse método também atribuirá a referência de controle à propriedade Control .
No entanto, em algumas circunstâncias, o método OnElementChanged pode ser chamado várias vezes. Portanto,
para evitar perdas de memória, que podem ter um impacto no desempenho, é necessário ter cuidado ao
instanciar um novo controle nativo. A abordagem a ser usada ao instanciar um novo controle nativo em um
renderizador personalizado é mostrada no exemplo de código a seguir:
protected override void OnElementChanged (ElementChangedEventArgs<NativeListView> e)
{
base.OnElementChanged (e);

if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
}

if (e.NewElement != null)
{
if (Control == null)
{
// Instantiate the native control with the SetNativeControl method
}
// Configure the control and subscribe to event handlers
}
}

Um novo controle nativo deve ser instanciado apenas uma vez, quando a propriedade Control é null . Além
disso, o controle só deve ser criado, configurado e manipuladores de eventos assinados quando o renderizador
personalizado é anexado a um novo Xamarin.Forms elemento. Da mesma forma, a inscrição de quaisquer
manipuladores de evento inscritos só deve ser cancelada quando o elemento ao qual o renderizador está
anexado for alterado. Adotar essa abordagem ajudará a criar um renderizador personalizado de desempenho
eficiente que não sofra perdas de memória.

IMPORTANT
O método SetNativeControl só deverá ser invocado se a propriedade e.NewElement não for null e a propriedade
Control for null .

Para obter mais informações sobre renderizadores personalizados, consulte Como personalizar controles em
cada plataforma.

Links relacionados
Desempenho de plataforma cruzada
Compilando XAML
Associações compiladas
Renderizadores Rápidos
Compactação de Layout
Xamarin.FormsShell
Xamarin.FormsCollectionView
Desempenho de ListView
Otimizar recursos de imagem
Estilos de XAML
Personalizando controles em cada plataforma
Desempenho do Xamarin.Android
02/11/2020 • 16 minutes to read • Edit Online

Há muitas técnicas para aumentar o desempenho dos aplicativos criados com o Xamarin. Android.
Coletivamente, essas técnicas podem reduzir muito a quantidade de trabalho que está sendo executado por
uma CPU e a quantidade de memória consumida por um aplicativo. Este artigo descreve e discute essas
técnicas.

Visão geral do desempenho


O baixo desempenho de aplicativo se apresenta de várias maneiras. Ele pode fazer com que o aplicativo pareça
não responder, deixar a rolagem lenta ou reduzir a vida útil da bateria. No entanto, a otimização do desempenho
engloba mais do que apenas a implementação de um código eficiente. A experiência do usuário quanto ao
desempenho do aplicativo também deve ser considerada. Por exemplo, garantir que as operações sejam
executadas sem impedir o usuário de realizar outras atividades pode ajudar a melhorar a experiência do
usuário.
Há várias técnicas para aumentar o desempenho, bem como o desempenho observado, dos aplicativos criados
com o Xamarin.Android. Entre elas estão:
Otimizar hierarquias de layout
Otimizar os modos de exibição de lista
Remover manipuladores de eventos nas atividades
Limitar o tempo de vida dos serviços
Liberar recursos ao receber notificação
Liberar recursos quando a interface do usuário estiver oculta
Otimizar recursos de imagem
Descartar os Recursos de Imagem não Utilizados
Evitar aritmético de ponto flutuante
Ignorar caixas de diálogo

NOTE
Antes de ler esse artigo, você deve primeiro ler Desempenho de plataforma cruzada, que discute técnicas específicas sem
plataforma para melhorar o uso de memória e o desempenho de aplicativos criados usando a plataforma Xamarin.

Otimizar hierarquias de layout


Cada layout adicionado a um aplicativo exige inicialização, layout e desenho. A passagem de layout pode ser
cara ao aninhar LinearLayout instâncias que usam o weight parâmetro, pois cada filho será medido duas
vezes. O uso de instâncias aninhadas do LinearLayout pode levar a uma hierarquia de exibição profunda, o que
pode resultar em baixo desempenho para layouts que são informados várias vezes, como em um ListView .
Portanto, é importante que esses layouts sejam otimizados, uma vez que os benefícios de desempenho serão
multiplicados.
Por exemplo, considere o LinearLayout para uma linha de exibição de lista que tem um ícone, um título e uma
descrição. O LinearLayout conterá um ImageView e um vertical LinearLayout que contém duas TextView
instâncias:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="5dip">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="5dip"
android:src="@drawable/icon" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="Mei tempor iuvaret ad." />
<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"
android:text="Lorem ipsum dolor sit amet." />
</LinearLayout>
</LinearLayout>

Esse layout tem 3 níveis de profundidade e é um desperdício quando é desinflado para cada ListView linha. No
entanto, ele pode ser melhorado ao nivelar o layout, conforme mostrado no exemplo de código a seguir:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="5dip">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="5dip"
android:src="@drawable/icon" />
<TextView
android:id="@+id/secondLine"
android:layout_width="fill_parent"
android:layout_height="25dip"
android:layout_toRightOf="@id/icon"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:singleLine="true"
android:ellipsize="marquee"
android:text="Lorem ipsum dolor sit amet." />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/icon"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@id/secondLine"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="Mei tempor iuvaret ad." />
</RelativeLayout>

A hierarquia anterior de três níveis foi reduzida para uma hierarquia de dois níveis e uma única RelativeLayout
substituiu duas LinearLayout instâncias. Um aumento de desempenho significativo será obtido ao recriar o
layout de cada ListView linha.

Otimizar os modos de exibição de lista


Os usuários esperam uma rolagem suave e tempos de carregamento rápidos para ListView instâncias. No
entanto, o desempenho de rolagem pode ser prejudicado quando cada linha do modo de exibição de lista tiver
hierarquias de exibição profundamente aninhadas ou quando as linhas do modo de exibição da lista tiverem
layouts complexos. Contudo, existem técnicas que podem ser usadas para evitar o baixo desempenho de
ListView :

Para obter mais informações sobre como reutilizar os modos de exibição de linha, confira Reutilizar modos
de exibição de linha.
Nivele os layouts, sempre que possível.
Armazene em cache o conteúdo da linha que for recuperado de um serviço Web.
Evite colocar a imagem em escala.
Coletivamente, essas técnicas podem ajudar a manter as ListView instâncias rolando suavemente.
Reutilizar modos de exibição de linha
Ao exibir centenas de linhas em um ListView , seria um desperdício de memória para criar centenas de View
objetos quando apenas um pequeno número deles é exibido na tela ao mesmo tempo. Em vez disso, apenas os
objetos View visíveis nas linhas da tela podem ser carregados na memória, com o conteúdo sendo carregado
nesses objetos reutilizados. Isso impede a instanciação de centenas de objetos adicionais, economizando tempo
e memória.
Portanto, quando uma linha desaparecer da tela, seu modo de exibição poderá ser colocado em uma fila para
reutilização, conforme mostrado no exemplo de código a seguir:

public override View GetView(int position, View convertView, ViewGroup parent)


{
View view = convertView; // re-use an existing view, if one is supplied
if (view == null) // otherwise create a new one
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
// set view properties to reflect data for the given row
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
// return the view, populated with data, for display
return view;
}

À medida que o usuário rola, o ListView chama a GetView substituição para solicitar que novas exibições
sejam exibidas – se disponível, ela passa uma exibição não usada no convertView parâmetro. Se esse valor for
null , o código criará uma nova View instância, caso contrário, as convertView Propriedades poderão ser
redefinidas e reutilizadas.
Para obter mais informações, confira Reutilização do modo de exibição da linha em Preenchendo um ListView
usando dados.

Remover manipuladores de eventos nas atividades


Quando uma atividade é destruída no runtime do Android, ela ainda poderá estar ativa no runtime Mono.
Portanto, remova os manipuladores de eventos de objetos externos no Activity.OnPause para impedir que o
runtime mantenha uma referência a uma atividade que foi destruída.
Em uma atividade, declare os manipuladores de eventos no nível de classe:

EventHandler<UpdatingEventArgs> service1UpdateHandler;

Em seguida, implemente os manipuladores de atividade, como em OnResume :

service1UpdateHandler = (object s, UpdatingEventArgs args) => {


this.RunOnUiThread (() => {
this.updateStatusText1.Text = args.Message;
});
};
App.Current.Service1.Updated += service1UpdateHandler;

Quando a atividade encerra o estado de execução, o OnPause é chamado. Na implementação OnPause , remova
os manipuladores da seguinte maneira:

App.Current.Service1.Updated -= service1UpdateHandler;

Limitar o tempo de vida dos serviços


Quando um serviço é iniciado, o Android mantém o processo do serviço em execução. Isso torna o processo
caro, uma vez que sua memória não pode ser paginada ou usada em outro lugar. Portanto, deixar um serviço
em execução quando não é necessário aumenta o risco de um aplicativo apresentar um desempenho baixo
devido às restrições de memória. A troca de aplicativos também pode se tornar menos eficiente, pois o número
de processos que o Android pode armazenar em cache é reduzido.
O tempo de vida de um serviço pode ser limitado ao usar um IntentService , que se encerra uma vez que é
controlado pela tentativa que o iniciou.

Liberar recursos ao receber notificação


Durante o ciclo de vida do aplicativo, o OnTrimMemory retorno de chamada fornece uma notificação quando a
memória do dispositivo está baixa. Esse retorno de chamada deve ser implementado para detectar as seguintes
notificações de nível de memória:
TrimMemoryRunningModerate – o aplicativo pode desejar liberar alguns recursos desnecessários.
TrimMemoryRunningLow – o aplicativo deve liberar recursos desnecessários.
TrimMemoryRunningCritical – o aplicativo deve liberar o máximo possível de processos não críticos.

Além disso, quando o processo do aplicativo é armazenado em cache, as seguintes notificações de nível de
memória podem ser recebidas pelo OnTrimMemory retorno de chamada:
TrimMemoryBackground – recursos de liberação que podem ser recriados de forma rápida e eficiente se o
usuário retornar ao aplicativo.
TrimMemoryModerate – a liberação de recursos pode ajudar o sistema a manter os outros processos em cache
para melhorar o desempenho geral.
TrimMemoryComplete – o processo do aplicativo será encerrado em breve se mais memória não for
recuperada em breve.
As notificações devem ser respondidas liberando recursos com base no nível recebido.

Liberar recursos quando a interface do usuário estiver oculta


Libere quaisquer recursos usados pela interface do usuário do aplicativo quando o usuário navegar para outro
aplicativo, visto que eles podem aumentar significativamente a capacidade do Android para processos em
cache, o que pode causar um impacto sobre a qualidade da experiência do usuário.
Para receber uma notificação quando o usuário sai da interface de usuário, implemente o OnTrimMemory retorno
de chamada em Activity classes e escute o TrimMemoryUiHidden nível, o que indica que a interface do usuário
está oculta da exibição. Essa notificação será recebida apenas quando todos os componentes da interface do
usuário do aplicativo ficarem ocultos para o usuário. A liberação de recursos da interface do usuário quando
esta notificação é recebida garante que, se o usuário navegar de volta de outra atividade no aplicativo, os
recursos da interface do usuário ainda estarão disponíveis para retomar a atividade rapidamente.

Otimizar os recursos de imagem


As imagens são alguns dos recursos mais caros que os aplicativos usam e, geralmente, são capturadas em alta
resolução. Portanto, ao exibir uma imagem, mostre-a com a resolução necessária para a tela do dispositivo. Se a
imagem tiver uma resolução mais alta que a tela, ela deverá ser reduzida.
Para obter mais informações, confira Otimizar os recursos de imagem na guia Desempenho de plataforma
cruzada.

Descartar os Recursos de Imagem não Utilizados


Para salvar no uso de memória, é uma boa ideia descartar recursos de imagem grandes, que não são mais
utilizados. No entanto, é importante garantir que as imagens sejam descartadas corretamente. Em vez de usar
uma invocação .Dispose() explícita, é possível aproveitar as instruções using para garantir o uso correto dos
objetos IDisposable .
Por exemplo, a classe Bitmap implementa IDisposable . O encapsulamento da instanciação de um objeto
BitMap em um bloco using garante que ele será descartado corretamente na saída do bloco:

using (Bitmap smallPic = BitmapFactory.DecodeByteArray(smallImageByte, 0, smallImageByte.Length))


{
// Use the smallPic bit map here
}

Para saber mais sobre a liberação de recursos descartáveis, consulte Liberar Recursos IDisposable.

Evitar aritmético de ponto flutuante


Em dispositivos Android, a aritmética de ponto flutuante é aproximadamente duas vezes mais lenta do que a
aritmética de inteiros. Portanto, substitua a aritmética de ponto flutuante pela aritmética de inteiros, se possível.
No entanto, não há nenhuma diferença de tempo de execução entre a aritmética float e a double em
hardwares recentes.

NOTE
Mesmo para a aritmética de inteiros, algumas CPUs não têm recursos de divisão de hardware. Portanto, as divisões de
inteiro e as operações de módulo geralmente são executadas no software.

Descartar as caixas de diálogo


Ao usar a ProgressDialog classe (ou qualquer caixa de diálogo ou alerta), em vez de chamar o Hide método
quando a finalidade da caixa de diálogo for concluída, chame o Dismiss método. Caso contrário, a caixa de
diálogo ainda estará ativa e vazará a atividade ao manter uma referência a ela.

Resumo
Esse artigo descreve e discute técnicas para aumentar o desempenho dos aplicativos criados com o
Xamarin.Android. Coletivamente, essas técnicas podem reduzir de forma considerável a quantidade de trabalho
que está sendo executado por uma CPU e a quantidade de memória consumida por um aplicativo.

Links Relacionados
Desempenho de plataforma cruzada
Desempenho do Xamarin.iOS
02/11/2020 • 17 minutes to read • Edit Online

O baixo desempenho de aplicativo se apresenta de várias maneiras. Ele pode fazer com que o aplicativo pareça
não responder, deixar a rolagem lenta ou reduzir a vida útil da bateria. No entanto, a otimização do desempenho
engloba mais do que apenas a implementação de um código eficiente. A experiência do usuário quanto ao
desempenho do aplicativo também deve ser considerada. Por exemplo, garantir que as operações sejam
executadas sem impedir o usuário de realizar outras atividades pode ajudar a melhorar a experiência do
usuário.
Este documento descreve técnicas que podem ser usadas para melhorar o desempenho e o uso de memória em
aplicativos Xamarin.iOS.

NOTE
Antes de ler esse artigo, você deve primeiro ler Desempenho de plataforma cruzada, que discute técnicas específicas sem
plataforma para melhorar o uso de memória e o desempenho de aplicativos criados usando a plataforma Xamarin.

Evitar referências circulares fortes


Em algumas situações, é possível criar ciclos de referência fortes que podem impedir que os objetos tenham sua
memória recuperada pelo coletor de lixo. Por exemplo, considere o caso em que uma NSObject subclasse
derivada, como uma classe herdada de UIView , é adicionada a um NSObject contêiner derivado e é altamente
referenciada de Objective-C, conforme mostrado no exemplo de código a seguir:

class Container : UIView


{
public void Poke ()
{
// Call this method to poke this object
}
}

class MyView : UIView


{
Container parent;
public MyView (Container parent)
{
this.parent = parent;
}

void PokeParent ()
{
parent.Poke ();
}
}

var container = new Container ();


container.AddSubview (new MyView (container));

Quando esse código cria a instância Container , o objeto C# terá uma referência forte a um objeto Objective-C.
Da mesma forma, a instância MyView também terá uma referência forte a um objeto Objective-C.
Além disso, a chamada para container.AddSubview aumentará a contagem de referência na instância MyView
não gerenciada. Quando isso acontece, o runtime do Xamarin.iOS cria uma instância GCHandle para manter o
objeto MyView ativo no código gerenciado, uma vez que não há nenhuma garantia de que qualquer objeto
gerenciado manterá uma referência a ele. De uma perspectiva de código gerenciado, o MyView objeto seria
recuperado depois AddSubview que a chamada era não para o GCHandle .
O objeto MyView não gerenciado terá um GCHandle apontando para o objeto gerenciado, conhecido como um
link forte. O objeto gerenciado terá uma referência para a instância Container . Por sua vez, a instância
Container terá uma referência gerenciada ao objeto MyView .

Em casos nos quais um objeto contido mantém um link para seu contêiner, há várias opções disponíveis para
lidar com a referência circular:
Interrompa manualmente o ciclo ao definir o link para o contêiner para null .
Remova manualmente o objeto contido do contêiner.
Chame Dispose nos objetos.
Evite que a referência circular mantenha uma referência fraca ao contêiner. Para obter mais informações
sobre referências fracas.
Usando WeakReferences
Uma maneira de evitar um ciclo é usar uma referência fraca do filho para o pai. Por exemplo, o código acima
poderia ser escrito da seguinte forma:

class Container : UIView


{
public void Poke ()
{
// Call this method to poke this object
}
}

class MyView : UIView


{
WeakReference<Container> weakParent;
public MyView (Container parent)
{
this.weakParent = new WeakReference<Container> (parent);
}

void PokeParent ()
{
if (weakParent.TryGetTarget (out var parent))
parent.Poke ();
}
}

var container = new Container ();


container.AddSubview (new MyView (container));

Aqui, o objeto contido não manterá o pai ativo. No entanto, o pai mantém o filho ativo por meio da chamada
feita para container.AddSubView .
Isso também ocorre em APIs do iOS que usam o padrão delegado ou fonte de dados, em que uma classe par
contém a implementação; por exemplo, ao definir o Delegate ou a propriedade DataSource na UITableView
classe.
No caso de classes que são criadas puramente para a implementação de um protocolo, por exemplo
IUITableViewDataSource , o, o que você pode fazer é, em vez de criar uma subclasse, você pode apenas
implementar a interface na classe e substituir o método e atribuir a DataSource Propriedade a this .
Atributo fraco
O Xamarin.iOS 11.10 introduziu o atributo [Weak] . Como WeakReference <T> , [Weak] pode ser usado para
interromper referências circulares fortes, mas com ainda menos código.
Considere o seguinte código, que usa WeakReference <T> :

public class MyFooDelegate : FooDelegate {


WeakReference<MyViewController> controller;
public MyFooDelegate (MyViewController ctrl) => controller = new WeakReference<MyViewController> (ctrl);
public void CallDoSomething ()
{
MyViewController ctrl;
if (controller.TryGetTarget (out ctrl)) {
ctrl.DoSomething ();
}
}
}

O código equivalente usando [Weak] é muito mais conciso:

public class MyFooDelegate : FooDelegate {


[Weak] MyViewController controller;
public MyFooDelegate (MyViewController ctrl) => controller = ctrl;
public void CallDoSomething () => controller.DoSomething ();
}

Veja abaixo outro exemplo do uso de [Weak] no contexto do padrão de delegação:

public class MyViewController : UIViewController


{
WKWebView webView;

protected MyViewController (IntPtr handle) : base (handle) { }

public override void ViewDidLoad ()


{
base.ViewDidLoad ();
webView = new WKWebView (View.Bounds, new WKWebViewConfiguration ());
webView.UIDelegate = new UIDelegate (this);
View.AddSubview (webView);
}
}

public class UIDelegate : WKUIDelegate


{
[Weak] MyViewController controller;

public UIDelegate (MyViewController ctrl) => controller = ctrl;

public override void RunJavaScriptAlertPanel (WKWebView webView, string message, WKFrameInfo frame,
Action completionHandler)
{
var msg = $"Hello from: {controller.Title}";
var alertController = UIAlertController.Create (null, msg, UIAlertControllerStyle.Alert);
alertController.AddAction (UIAlertAction.Create ("Ok", UIAlertActionStyle.Default, null));
controller.PresentViewController (alertController, true, null);
completionHandler ();
}
}

Descartando objetos com referências fortes


Se houver uma referência forte e for difícil remover a dependência, faça um método Dispose limpar o ponteiro
pai.
Para os contêineres, substitua o método Dispose para remover os objetos contidos, conforme mostrado no
exemplo de código a seguir:

class MyContainer : UIView


{
public override void Dispose ()
{
// Brute force, remove everything
foreach (var view in Subviews)
{
view.RemoveFromSuperview ();
}
base.Dispose ();
}
}

Para um objeto filho que mantém uma referência forte ao seu pai, limpe a referência ao pai na implementação
Dispose :

class MyChild : UIView


{
MyContainer container;
public MyChild (MyContainer container)
{
this.container = container;
}
public override void Dispose ()
{
container = null;
}
}

Para obter mais informações sobre a liberação de referências fortes, confira Liberar recursos IDisposable. Há
também uma boa discussão nesta postagem de blog: Xamarin.iOS, the garbage collector and me (Xamarin.iOS,
o coletor de lixo e eu).
Mais informações
Para obter mais informações, confira Rules to Avoid Retain Cycles (Regras para evitar a retenção de ciclos) em
Cocoa With Love, Is this a bug in MonoTouch GC (Isso é um bug no MonoTouch GC?) em StackOverflow e Why
can't MonoTouch GC kill managed objects with refcount > 1? (Por que o MonoTouch GC não pode eliminar
objetos gerenciados com contagem de referência > 1?) no StackOverflow.

Otimizar modos de exibição de tabela


Os usuários esperam uma rolagem suave e tempos de carregamento rápidos para UITableView instâncias. No
entanto, o desempenho de rolagem pode ser prejudicado quando as células tiverem hierarquias do modo de
exibição profundamente aninhadas ou quando as células tiverem layouts complexos. Contudo, existem técnicas
que podem ser usadas para evitar o baixo desempenho de UITableView :
Células de reutilização. Para saber mais, confira Células de Reutilização.
Reduzir o número de subexibições.
Armazene em cache o conteúdo da célula que for recuperado de um serviço Web.
Armazene a altura das linhas em cache, se elas não forem idênticas.
Torne a célula e quaisquer exibições, opacas.
Evite gradientes e a colocação da imagem em escala.
Coletivamente, essas técnicas podem ajudar a manter as UITableView instâncias rolando suavemente.
Reutilizar células
Ao exibir centenas de linhas em um UITableView , seria um desperdício de memória para criar centenas de
UITableViewCell objetos quando apenas um pequeno número deles é exibido na tela ao mesmo tempo. Em vez
disso, apenas as células visíveis na tela podem ser carregadas na memória, com o conteúdo sendo carregado
nessas células reutilizadas. Isso impede a instanciação de centenas de objetos adicionais, economizando tempo
e memória.
Portanto, quando uma célula desaparece da tela, seu modo de exibição poderá ser colocado em uma fila para
reutilização, conforme mostrado no exemplo de código a seguir:

class MyTableSource : UITableViewSource


{
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
// iOS will create a cell automatically if one isn't available in the reuse pool
var cell = (MyCell) tableView.DequeueReusableCell (MyCellId, indexPath);

// Perform required cell actions


return cell;
}
}

À medida que o usuário rola, o UITableView chama a GetCell substituição para solicitar que novas exibições
sejam exibidas. Essa substituição então chama o DequeueReusableCell método e, se uma célula estiver
disponível para reutilização, ela será retornada.
Para obter mais informações, confira Reutilização de Célula em Populating a Table with Data (Preenchendo uma
Tabela usando dados).

Usar exibições opacas


Certifique-se de que todas as exibições sem transparência definida tenham suas Opaque Propriedades
definidas. Isso garantirá que os modos de exibição sejam processados de forma ideal pelo sistema de desenho.
Isso é particularmente importante quando uma exibição é inserida em um UIScrollView ou faz parte de uma
animação complexa. Caso contrário, o sistema de desenho alinhará as exibições com outros tipos de conteúdo, o
que pode afetar visivelmente no desempenho.

Evitar XIBs pesados


Embora os XIBs tenham sido amplamente substituídos pelos storyboards, há algumas circunstâncias nas quais
os XIBs ainda podem ser usados. Quando um XIB é carregado na memória, todo seu conteúdo é carregado na
memória, incluindo todas as imagens. Se o XIB tiver um modo de exibição que não estiver sendo usado
imediatamente, então a memória estará sendo desperdiçada. Portanto, ao usar XIBs, verifique se há apenas um
XIB por controlador de exibição e, se possível, coloque a hierarquia do modo de exibição do controlador de
exibição em XIBs separados.

Otimizar os recursos de imagem


As imagens são alguns dos recursos mais caros que os aplicativos usam e, geralmente, são capturadas em alta
resolução. Portanto, ao exibir uma imagem do pacote do aplicativo em um UIImageView , certifique-se de que a
imagem e UIImageView seja de tamanho idêntico. Dimensionar imagens em tempo de execução pode ser uma
operação cara, especialmente se o UIImageView estiver inserido em um UIScrollView .
Para obter mais informações, confira Otimizar os recursos de imagem na guia Desempenho de plataforma
cruzada.

Testar nos dispositivos


Comece a implantar e a testar um aplicativo em um dispositivo físico o quanto antes. Os simuladores não
correspondem perfeitamente com os comportamentos e as limitações dos dispositivos. Desse modo, é
importante fazer um teste em um cenário de dispositivo real o mais rápido possível.
Em particular, o simulador não simula de forma alguma a memória ou as restrições de CPU de um dispositivo
físico.

Sincronizar animações com a atualização da exibição


Os jogos tendem a ter loops comprimidos para executar a lógica do jogo e atualizar a tela. As taxas de quadro
típicas variam de trinta a sessenta quadros por segundo. Alguns desenvolvedores acreditam que devem
atualizar a tela quantas vezes forem possíveis por segundo, combinando a simulação de jogo com as
atualizações na tela e podem se sentir motivados a ir além dos sessenta quadros por segundo.
No entanto, o servidor de exibição executa atualizações de tela em um limite de sessenta vezes por segundo.
Portanto, a tentativa de atualizar a tela de modo mais rápido do que esse limite pode causar subdivisão e
intermitências da tela. É melhor estruturar o código para que as atualizações de tela sejam sincronizadas com a
atualização da exibição. Isso pode ser feito usando a CoreAnimation.CADisplayLink classe, que é um
temporizador adequado para visualização e jogos executados em 60 quadros por segundo.

Evitar transparência de animação de núcleo


Evitar a transparência de animação de núcleo melhora o desempenho da composição de bitmap. Em geral, evite
camadas transparentes e bordas borradas, se possível.

Evitar a geração de código


A geração de código de modo dinâmico com o System.Reflection.Emit ou com o Dynamic Language Runtime
deve ser evitada, uma vez que o kernel iOS impede a execução do código dinâmico.

Resumo
Esse artigo descreve e discute técnicas para aumentar o desempenho dos aplicativos criados com o
Xamarin.iOS. Coletivamente, essas técnicas podem reduzir de forma considerável a quantidade de trabalho que
está sendo executado por uma CPU e a quantidade de memória consumida por um aplicativo.

Links relacionados
Desempenho de plataforma cruzada
Desempenho do Xamarin.Mac
02/11/2020 • 4 minutes to read • Edit Online

Visão geral
Aplicativos Xamarin.Mac são semelhantes a Xamarin.iOS e muitas das mesmas sugestões de desempenho são
aplicáveis:
Desempenho do Xamarin.iOS
Desempenho de plataforma cruzada
Mas há inúmeras sugestões específicas para macOS que podem ser úteis.

Preferir a estrutura de destino moderna


Há várias Estruturas de Destino disponíveis para o aplicativo Xamarin.Mac com diferentes características de
desempenho e recursos.
Quando for possível, prefira a Moderna e trabalhe com bibliotecas dependentes para adicionar suporte.
Somente a Estrutura de Destino Moderna permite a vinculação, que pode reduzir drasticamente os tamanhos de
assembly. Isso será importante principalmente no momento em que habilitar a AOT, uma vez que a compilação
da AOT dos assemblies completos pode produzir pacotes finais grandes.

Habilitar o vinculador
O tempo de inicialização, tanto no carregamento quanto no JIT (Just In Time), é escalonado um pouco
linearmente com o tamanho de seus binários finais. A maneira mais fácil de melhorar isso é removendo o
código morto com o vinculador.
Enquanto essa sugestão se aplica principalmente aos usuários da Estrutura de Destino Moderna, o uso da
Vinculação de Plataforma também pode fornecer um aumento de desempenho limitado.

Habilitar AOT quando apropriado


Outra faceta do desempenho de inicialização é a compilação JIT dos assemblies em código de computador. A
compilação AOT (Ahead of Time) pode reduzir significativamente o tempo de inicialização, mas acompanha
diversas compensações abordadas na documentação de AOT.

Assegurar delegados com bom desempenho


Muitos aplicativos Xamarin.Mac são centralizados em torno de exibições do Cocoa como NSCollectionView ,
NSOutlineView ou NSTableView . Geralmente, essas exibições são alimentadas por classes Delegate e
DataSource que você fornece ao Cocoa, respondendo perguntas sobre o que exibir.

Muitos desses pontos de entrada são invocados com frequência e, ocasionalmente, várias vezes por segundo
durante a rolagem.
Verifique se que essas funções retornam valores que são calculados facilmente ou use as informações já
armazenadas em cache, para impedir o bloqueio da interface do usuário.

Usar APIs fornecidas pelo Cocoa para reutilização de exibições


Várias exibições do Cocoa que contêm muitas células ou exibições filhas (como NSCollectionView ,
NSOutlineView e NSTableView ) fornecem APIs para criar e reutilizar as exibições. Essas APIs criam pools de itens
compartilhados e evitam problemas de desempenho ao rolar pelas exibições rapidamente.

Usar async e não bloquear a interface do usuário


Aplicativos da área de trabalho geralmente processam grandes quantidades de dados e é muito fácil bloquear o
thread de interface do usuário esperando por uma operação síncrona.
Sempre que possível, use async e threads para evitar o bloqueio da interface do usuário.
Para operações de execução longa, considere o uso de NSProgressIndicator ou outras opções observadas no
HIG da Apple para notificar os usuários.

Links Relacionados
Desempenho de plataforma cruzada
Desempenho do Xamarin.iOS
Protocolo TLS 1.2
02/11/2020 • 7 minutes to read • Edit Online

Usar a versão mais recente do protocolo TLS é importante para garantir que as comunicações de rede do
aplicativo sejam seguras.

WARNING
Abril de 2018 – devido a requisitos de segurança maiores, incluindo a conformidade com PCI, os principais provedores
de nuvem e servidores Web devem parar de dar suporte a versões de TLS anteriores a 1,2. Os projetos do Xamarin
criados em versões anteriores do Visual Studio usam o padrão para usar versões mais antigas do TLS.
Para garantir que seus aplicativos continuem a trabalhar com esses servidores e serviços, você deve atualizar seus
projetos do Xamarin para usar as configurações abaixo e, em seguida, recompilar e implantar novamente
seus aplicativos para os usuários.

Os projetos devem referenciar o assembly System .net. http e ser configurado como mostrado abaixo.

Atualizar Xamarin. Android para TLS 1,2


Atualize a implementação de HttpClient e as opções de implementação de SSL/TLS para habilitar a
segurança TLS 1,2.

NOTE
Requer Android 5,0 ou mais recente.

Visual Studio
Visual Studio para Mac
Essas configurações podem ser encontradas nas Propriedades do projeto > opções do Android e, em
seguida, clicando no botão avançado :

Atualizar Xamarin. iOS para TLS 1,2


Atualize a opção de implementação HttpClient para habilitar a segurança de TSL 1,2.
Visual Studio
Visual Studio para Mac
Essa configuração pode ser encontrada nas Propriedades do projeto > Build do IOS :
Atualizar o Xamarin. Mac para TLS 1,2
No Visual Studio para Mac, para habilitar o TLS 1,2 em um aplicativo Xamarin. Mac, atualize a opção de
implementação HttpClient em opções de projeto > compilar > Build do Mac :

WARNING
A próxima versão do Xamarin.Mac 4.8 dará suporte somente a macOS 10.9 ou posterior. As versões anteriores do
Xamarin.Mac eram compatíveis com macOS 10.7 ou superior, mas essas versões mais antigas do macOS não têm
infraestrutura TLS suficiente para dar suporte ao TLS 1.2. Para macOS 10.7 ou macOS 10.8, use o Xamarin.Mac 4.6 ou
anterior.

Opções de configuração alternativas


Esta seção discute alternativas para as configurações com suporte do TLS 1,2 mostradas acima. Os
desenvolvedores de aplicativos só devem considerar essas alternativas se entenderem os riscos de usar
diferentes níveis de suporte a TLS.
Implementação de HttpClient
Os desenvolvedores do Xamarin sempre conseguiram usar as classes de rede nativas em seu código, no
entanto, há também uma opção que determina qual pilha de rede é usada pelas HttpClient classes. Isso
fornece uma API .NET familiar que tem as vantagens de velocidade e segurança da plataforma nativa.
As opções são:
Pilha gerenciada – a funcionalidade de rede fornecida por mono ou
Pilha nativa – várias APIs de rede fornecidas pelas plataformas subjacentes (Android, Ios ou MacOS).
A pilha gerenciada fornece o nível mais alto de compatibilidade com o código .NET existente, no entanto, pode
ser mais lento e resultar em um tamanho de executável maior.
As opções nativas podem ser mais rápidas e ter mais segurança (incluindo o TLS 1,2), mas podem não fornecer
toda a funcionalidade e as opções da HttpClient classe.
Implementação de SSL/TLS (Android)
As opções de projeto do Android também permitem que você escolha a implementação de SSL/TLS com
suporte:
Mono/gerenciado – TLS 1,1 no Android
Nativo – TLS 1,2 no Android.
Os novos projetos do Xamarin são padronizados para a implementação nativa que dá suporte a TLS 1,2 (que é
recomendado para todos os projetos), no entanto, você pode alternar de volta para o código gerenciado, se
necessário por motivos de compatibilidade.
IMPORTANT
A opção mono/Managed foi removida das opções de projeto do IOS e do Mac .
A opção nativa é sempre usada em plataformas iOS e Mac.

Detalhes específicos da plataforma


O resumo acima explica as configurações de nível de projeto para a implementação de HttpClient e SSL/TLS em
projetos do Xamarin. A implementação de HttpClient também pode ser definida dinamicamente no código.
Consulte estes guias específicos da plataforma para obter mais informações:
Android
iOS e Mac

Resumo
Os aplicativos devem usar o protocolo TLS 1,2 sempre que possível. Você deve atualizar as configurações em
aplicativos existentes de acordo com as instruções neste artigo e, em seguida, recompilar e reimplantar para
seus clientes.

Links relacionados
Segurança do transporte de aplicativo
Ambiente do Xamarin.Android
Xamarin ciclo 9 (fevereiro de 2017)
TLS (Wikipédia)
Notas de versão do mono 4,8 – suporte a TLS 1,2
BoringSSL
HttpClient, HttpClientHandler e WebRequestHandler explicados
System .net. HttpClient
System .net. HttpClientHandler
System .net. HttpMessageHandler
System .net. HttpWebRequest
System.Net.WebClient
System .net. WebRequest
Java. net. URLConnection
Foundation. CFNetwork
Foundation. NSUrlConnection
System .net. WebRequest
Cliente HTTP (exemplo)
Seletor de implementação de HttpClient Stack e
SSL/TLS para Android
23/04/2020 • 9 minutes to read • Edit Online

Os seletores de implementação de pilha HttpClient e SSL/TLS determinam a implementação de HttpClient e


SSL/TLS que será usada por seus aplicativos Xamarin. Android.
Os projetos devem referenciar o assembly do System .net. http .

WARNING
Abril de 2018 – devido a requisitos de segurança maiores, incluindo a conformidade com PCI, os principais provedores
de nuvem e servidores Web devem parar de dar suporte a versões de TLS anteriores a 1,2. Os projetos do Xamarin
criados em versões anteriores do Visual Studio usam o padrão para usar versões mais antigas do TLS.
Para garantir que seus aplicativos continuem a trabalhar com esses servidores e serviços, você deve atualizar seus
projetos do Xamarin com as configurações Android HttpClient e Native TLS 1.2 mostradas abaixo e, em
seguida, recompilar e reimplantar seus aplicativos para os usuários.

Visual Studio
Visual Studio para Mac
A configuração HttpClient do Xamarin. Android está em Opções do projeto > opções do Android e, em
seguida, clique no botão Opções avançadas .
Estas são as configurações recomendadas para o suporte a TLS 1,2:

Opções do

Opções de configuração alternativas


AndroidClientHandler
AndroidClientHandler é o novo manipulador que delega para código Java/OS nativo em vez de implementar
tudo no código gerenciado. Essa é a opção recomendada.
Prós
Use a API nativa para melhorar o desempenho e o tamanho do executável menor.
Suporte para os padrões mais recentes, por exemplo, TLS 1,2.
Contras
Requer o Android 4,1 ou posterior.
Alguns recursos/opções do HttpClient não estão disponíveis.
Gerenciado (HttpClientHandler)
O manipulador gerenciado é o manipulador HttpClient totalmente gerenciado que foi enviado com versões
anteriores do Xamarin. Android.
Prós
Ele é o mais compatível (recursos) com o MS .NET e versões anteriores do Xamarin.
Contras
Ele não está totalmente integrado ao sistema operacional (por exemplo, limitado a TLS 1,0).
Normalmente, é muito mais lento (por exemplo, criptografia) do que a API nativa.
Ele requer mais código gerenciado, criando aplicativos maiores.
Escolhendo um manipulador
A escolha entre AndroidClientHandler e HttpClientHandler depende das necessidades do seu aplicativo. o
AndroidClientHandler é recomendado para o suporte de segurança mais atualizado, por exemplo,

Você precisa de suporte a TLS 1.2 +.


Seu aplicativo está direcionando para o Android 4,1 (API 16) ou posterior.
Você precisa de suporte a TLS 1.2 + para HttpClient .
Você não precisa de suporte a TLS 1.2 + para WebClient .
HttpClientHandler é uma boa opção se você precisar de suporte a TLS 1.2 +, mas deve oferecer suporte a
versões do Android anteriores ao Android 4,1. Também é uma boa opção se você precisar de suporte a TLS 1.2
+ para WebClient .
A partir do Xamarin. Android 8,3, o HttpClientHandler assume como padrão o SSL enfadonho ( btls ) como o
provedor TLS subjacente. O provedor de TLS SSL enfadonho oferece as seguintes vantagens:
Ele dá suporte a TLS 1.2 +.
Ele dá suporte a todas as versões do Android.
Ele fornece suporte a TLS 1.2 + para HttpClient e WebClient .

A desvantagem de usar o SSL sem graça como o sob o provedor TLS é que ele pode aumentar o tamanho do
APK resultante (ele adiciona cerca de 1MB de tamanho adicional de APK por ABI com suporte).
A partir do Xamarin. Android 8,3, o provedor TLS padrão é um SSL enfadonho ( btls ). Se você não quiser usar
o SSL sem graça, poderá reverter para a implementação de SSL gerenciada por histórico definindo a
propriedade $(AndroidTlsProvider) como legacy (para obter mais informações sobre como definir
propriedades de compilação, consulte processo de compilação).
Programaticamente usando AndroidClientHandler

O Xamarin.Android.Net.AndroidClientHandler é uma implementação de HttpMessageHandler especificamente


para o Xamarin. Android. As instâncias dessa classe usarão a implementação de java.net.URLConnection nativa
para todas as conexões HTTP. Teoricamente, isso proporcionará um aumento no desempenho de HTTP e em
tamanhos de APK menores.
Este trecho de código é um exemplo de como explicitamente para uma única instância da classe HttpClient :

// Android 4.1 or higher, Xamarin.Android 6.1 or higher


HttpClient client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler ());

NOTE
O dispositivo Android subjacente deve dar suporte a TLS 1,2 (IE. Android 4,1 e posterior). Observe que o suporte oficial
para TLS 1,2 está no Android 5.0 +. No entanto, alguns dispositivos dão suporte a TLS 1,2 no Android 4.1 +.

Opção de Build de implementação de SSL/TLS


Essa opção de projeto controla qual biblioteca TLS subjacente será usada por todas as solicitações da Web,
HttpClient e WebRequest . Por padrão, o TLS 1,2 é selecionado:

Visual Studio
Visual Studio para Mac
caixa de combinação de implementação de TLS/SSL do

Por exemplo:

var client = new HttpClient();

Se a implementação de HttpClient foi definida como gerenciada e a implementação de TLS tiver sido definida
para o TLS 1.2 + nativo , o objeto de client usará automaticamente o HttpClientHandler gerenciado e o TLS
1,2 (fornecido pela biblioteca BORINGSSL) para seu http pedido.
No entanto, se a implementação de HttpClient for definida como AndroidHttpClient , todos os objetos de
HttpClient usarão a classe Java subjacente java.net.URLConnection e não serão afetados pelo valor de
implementação de TLS/SSL . WebRequest objetos usaria a biblioteca BoringSSL.

Outras maneiras de controlar a configuração de SSL/TLS


Há três maneiras que um aplicativo Xamarin. Android pode controlar as configurações de TLS:
1. Selecione a implementação de HttpClient e a biblioteca TLS padrão nas opções do projeto.
2. Programaticamente usando Xamarin.Android.Net.AndroidClientHandler .
3. Declare variáveis de ambiente (opcional).
Das três opções, a abordagem recomendada é usar as opções de projeto do Xamarin. Android para declarar o
HttpMessageHandler e o TLS padrão para todo o aplicativo. Em seguida, se necessário, crie programaticamente
Xamarin.Android.Net.AndroidClientHandler objetos. Essas opções são descritas acima.

A terceira opção – usar variáveis de ambiente – é explicada abaixo.


Declarar variáveis de ambiente
Há duas variáveis de ambiente relacionadas ao uso de TLS no Xamarin. Android:
XA_HTTP_CLIENT_HANDLER_TYPE – essa variável de ambiente declara o HttpMessageHandler padrão que o
aplicativo usará. Por exemplo:

XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler

XA_TLS_PROVIDER – essa variável de ambiente irá declarar qual biblioteca TLS será usada, btls , legacy
ou default (que é o mesmo que omitir essa variável):

XA_TLS_PROVIDER=btls

Essa variável de ambiente é definida adicionando um arquivo de ambiente ao projeto. Um arquivo de ambiente
é um arquivo de texto simples formatado para UNIX com uma ação de compilação de AndroidEnvironment :
Visual Studio
Visual Studio para Mac

Consulte o guia do ambiente Xamarin. Android para obter mais detalhes sobre as variáveis de ambiente e
Xamarin. Android.

Links relacionados
TLS (Transport Layer Security)
Seletor de implementação de HttpClient e SSL/TLS
para iOS/macOS
23/04/2020 • 9 minutes to read • Edit Online

O seletor de implementação HttpClient para os controles Xamarin. Ios, Xamarin. TvOS e Xamarin. Mac, que
HttpClient implementação a ser usada. Você pode alternar para uma implementação que usa Transportações
nativas iOS, tvOS ou macOS ( NSUrlSession ou CFNetwork , dependendo do sistema operacional). A vantagem é
o TLS 1,2-suporte, binários menores e downloads mais rápidos; a desvantagem é que requer que o loop de
eventos esteja em execução para que as operações assíncronas sejam executadas.
Os projetos devem referenciar o assembly do System .net. http .

WARNING
Abril de 2018 – devido a requisitos de segurança maiores, incluindo a conformidade com PCI, os principais provedores
de nuvem e servidores Web devem parar de dar suporte a versões de TLS anteriores a 1,2. Os projetos do Xamarin
criados em versões anteriores do Visual Studio usam o padrão para usar versões mais antigas do TLS.
Para garantir que seus aplicativos continuem a trabalhar com esses servidores e serviços, você deve atualizar seus
projetos do Xamarin com a configuração NSUrlSession mostrada abaixo e, em seguida, recompilar e
reimplantar seus aplicativos para os usuários.

Selecionando uma pilha HttpClient


Para ajustar o HttpClient que está sendo usado pelo seu aplicativo:
1. Clique duas vezes no nome do projeto no Gerenciador de soluções para abrir as opções do projeto.
2. Alterne para as configurações de compilação do seu projeto (por exemplo, Build do IOS para um
aplicativo Xamarin. Ios).
3. Na lista suspensa implementação de HttpClient , selecione o tipo de HttpClient como um dos seguintes:
NSUrlSession (recomendado), CFNetwork ou gerenciado .

TIP
Para o TLS 1,2, é recomendável a opção NSUrlSession .

NSUrlSession
O manipulador baseado em NSURLSession é baseado na estrutura nativa do NSURLSession disponível no iOS 7 e
mais recente. Essa é a configuração recomendada.
Prós
Ele usa APIs nativas para melhorar o desempenho e o tamanho do executável menor.
Suporte para os padrões mais recentes, como o TLS 1,2.
Contras
Requer o iOS 7 ou posterior.
Alguns HttpClient recursos/opções não estão disponíveis.
CFNetwork
O manipulador baseado em CFNetwork é baseado na estrutura nativa do CFNetwork disponível no iOS 6 e mais
recente.
Prós
Ele usa APIs nativas para melhorar o desempenho e o tamanho do executável menor.
Suporte para padrões mais recentes, como o TLS 1,2.
Contras
Requer o iOS 6 ou posterior.
Não disponível em watchOS.
Alguns recursos/opções do HttpClient não estão disponíveis.
Gerenciado
O manipulador gerenciado é o manipulador HttpClient totalmente gerenciado que foi enviado com a versão
anterior do Xamarin.
Prós
Ele tem o conjunto de recursos mais compatível com Microsoft .NET e versões anteriores do Xamarin.
Contras
Ele não está totalmente integrado com os SOS da Apple e está limitado ao TLS 1,0. Talvez não seja possível se
conectar a servidores Web ou serviços de nuvem seguros no futuro.
Normalmente, isso é muito mais lento em coisas como criptografia do que as APIs nativas.
Ele requer mais código gerenciado, criando assim um distribuído de aplicativo maior.
Definindo programaticamente o HttpMessageHandler
Além da configuração de todo o projeto mostrada acima, você também pode criar uma instância de um
HttpClient e injetar os HttpMessageHandler desejados por meio do Construtor, conforme demonstrado nestes
trechos de código:

// This will use the default message handler for the application; as
// set in the Project Options for the project.
HttpClient client = new HttpClient();

// This will create an HttpClient that explicitly uses the CFNetworkHandler


HttpClient client = new HttpClient(new CFNetworkHandler());

// This will create an HttpClient that explicitly uses NSUrlSessionHandler


HttpClient client = new HttpClient(new NSUrlSessionHandler());

Isso torna possível usar um HttpMessageHandler diferente do que é declarado na caixa de diálogo Opções do
projeto .

Implementação de SSL/TLS
SSL (camada de soquete seguro) e seu sucessor, TLS (segurança de camada de transporte), fornecer suporte
para HTTP e outras conexões de rede por meio de System.Net.Security.SslStream . A implementação de
System.Net.Security.SslStream do xamarin. iOS, Xamarin. tvOS ou Xamarin. Mac irá chamar a implementação
de SSL/TLS nativa da Apple em vez de usar a implementação gerenciada fornecida pelo mono. A
implementação nativa da Apple dá suporte a TLS 1,2.
WARNING
A próxima versão do Xamarin.Mac 4.8 dará suporte somente a macOS 10.9 ou posterior. As versões anteriores do
Xamarin.Mac eram compatíveis com macOS 10.7 ou superior, mas essas versões mais antigas do macOS não têm
infraestrutura TLS suficiente para dar suporte ao TLS 1.2. Para macOS 10.7 ou macOS 10.8, use o Xamarin.Mac 4.6 ou
anterior.

Segurança do transporte de aplicativo


A ATS ( segurança de transporte de aplicativo ) da Apple impõe conexões seguras entre os recursos da Internet
(como o servidor back-end do aplicativo) e seu aplicativo. O ATS garante que todas as comunicações com a
Internet estejam em conformidade com as práticas recomendadas de conexão, impedindo a divulgação
acidental de informações confidenciais diretamente por meio de seu aplicativo ou de uma biblioteca que esteja
consumindo.
Como o ATS está habilitado por padrão em aplicativos criados para iOS 9, tvOS 9 e OS X 10,11 (El Capitan) e
mais recentes, todas as conexões que usam NSUrlConnection , CFUrl ou NSUrlSession estarão sujeitos a
requisitos de segurança de ATS. Se suas conexões não atenderem a esses requisitos, elas falharão com uma
exceção.
Com base em suas seleções de implementação do HttpClient Stack e SSL/TLS, talvez seja necessário fazer
modificações em seu aplicativo para funcionar corretamente com o ATS.
Para saber mais sobre o ATS, consulte nosso Guia de segurança do transporte de aplicativo.

Problemas conhecidos
Esta seção abordará problemas conhecidos com o suporte a TLS no Xamarin. iOS.
Falha ao carregar o projeto com o erro "o valor solicitado AppleTLS não foi encontrado"
O Xamarin. iOS 9,8 introduziu algumas novas configurações que continham o arquivo . csproj para um
aplicativo Xamarin. Ios. Essas alterações podem causar problemas quando o projeto é aberto com versões mais
antigas do Xamarin. iOS. A captura de tela a seguir é um exemplo da mensagem de erro que pode ser exibida
neste cenário:

Esse erro é causado pela introdução da configuração de MtouchTlsProvider ao arquivo de projeto no Xamarin.
iOS 9,8. Se não for possível atualizar para o Xamarin. iOS 9,8 (ou superior), a solução alternativa é editar
manualmente o aplicativo de arquivo . csproj , remover o elemento MtouchTlsprovider e, em seguida, salvar o
arquivo de projeto alterado.
O trecho a seguir é um exemplo de como a configuração de MtouchTlsProvider pode parecer dentro de um
arquivo . csproj :

<MtouchTlsProvider>Default</MtouchTlsProvider>
Links relacionados
TLS (Transport Layer Security)
Segurança de transporte de aplicativo
Depuração e implantação
23/04/2020 • 2 minutes to read • Edit Online

Conecte-se aos serviços web locais


Os aplicativos em execução no simulador do iOS ou no emulador do Android podem consumir serviços Web
locais que são expostos via HTTP ou HTTPS.

Configuração de linker personalizado


Se o conjunto padrão de opções não for o suficiente, faça o processo de vinculação com um arquivo XML que
descreve o que você deseja do vinculador.

Depuração de vários processos


Este guia discute como depurar vários processos.
Conectar-se a serviços da Web locais de
simuladores do iOS e de emuladores do Android
15/01/2021 • 12 minutes to read • Edit Online

Baixar o exemplo
Muitos aplicativos móveis consomem serviços Web. Durante a fase de desenvolvimento, é comum implantar
um serviço Web localmente e consumi-lo de um aplicativo móvel em execução no simulador do iOS ou no
emulador do Android. Isso evita a necessidade de implantar o serviço Web em um ponto de extremidade
hospedado e possibilita uma experiência de depuração simples, pois o aplicativo móvel e o serviço Web estão
sendo executados localmente.
Os aplicativos móveis em execução no simulador do iOS ou no emulador do Android podem consumir serviços
Web do ASP.NET Core que estão sendo executados localmente e serem expostos via HTTP, conforme a seguir:
Os aplicativos em execução no simulador do iOS podem se conectar aos serviços web HTTP locais por meio
do endereço IP do computador ou do nome do host localhost . Por exemplo, considerando um serviço Web
HTTP local que expõe uma operação GET por meio do Uniform Resource Identifier (URI) relativo
/api/todoitems/ , o aplicativo em execução no simulador do iOS pode consumir a operação enviando uma
solicitação GET ao http://localhost:<port>/api/todoitems/ .
Os aplicativos em execução no emulador do Android podem se conectar aos serviços Web HTTP locais por
meio do endereço 10.0.2.2 , que é um alias para a sua interface de loopback do host ( 127.0.0.1 no
computador de desenvolvimento). Por exemplo, considerando um serviço Web HTTP local que expõe uma
operação GET por meio do URI relativo /api/todoitems/ , o aplicativo em execução no emulador do Android
pode consumir a operação enviando uma solicitação GET ao http://10.0.2.2:<port>/api/todoitems/ .
No entanto, é necessário um trabalho adicional para que o aplicativo em execução no simulador do iOS ou no
emulador do Android possam consumir um serviço Web local que esteja exposto via HTTPS. Para este cenário, o
processo é da seguinte maneira:
1. Crie um certificado autoassinado de desenvolvimento em seu computador. Para saber mais, confira as
informações sobre como criar um certificado de desenvolvimento.
2. Configure seu projeto para usar a HttpClient pilha de rede apropriada para sua compilação de depuração.
Para saber mais, confira as informações sobre como configurar o projeto.
3. Especifique o endereço do computador local. Para saber mais, confira as informações sobre como especificar
o endereço do computador local.
4. Ignore a verificação de segurança do certificado de desenvolvimento local. Para saber mais, veja Ignorar a
verificação de segurança do certificado.
Cada item será apresentado separadamente.

Criar um certificado de desenvolvimento


Instalar o SDK do .NET Core instala o certificado de desenvolvimento HTTPS do ASP.NET Core no repositório de
certificados do usuário local. No entanto, embora o certificado tenha sido instalado, ele não é confiável. Para
confiar no certificado, realize a única etapa a seguir para executar a ferramenta do dotnet dev-certs :

dotnet dev-certs https --trust


O comando a seguir fornece ajuda para a ferramenta dev-certs :

dotnet dev-certs https --help

Como alternativa, quando você executa um projeto do ASP.NET Core 2.1 (ou superior), que usa HTTPS, o Visual
Studio detectará se o certificado de desenvolvimento está ausente e oferecerá a possibilidade de instalá-lo e de
confiar nele.

NOTE
O certificado de desenvolvimento HTTPS do ASP.NET Core é autoassinado.

Para saber mais sobre como habilitar o HTTPS local em seu computador, confira o artigo Habilitar o HTTPS local.

Configurar seu projeto


Os aplicativos do Xamarin em execução no iOS e no Android podem especificar qual pilha de rede é usada pela
classe HttpClient ; sendo as opções uma pilha de rede gerenciada ou pilhas de rede nativa. A pilha gerenciada
fornece um alto nível de compatibilidade com o código existente do .NET, mas é limitada a TLS 1.0 e pode ser
mais lenta e resultar em um executável de tamanho maior. As pilhas nativas podem ser mais rápidas e oferecem
uma segurança melhor, mas podem não fornecer toda a funcionalidade da classe HttpClient .
iOS
Os aplicativos do Xamarin em execução no iOS podem usar a pilha de rede gerenciada ou as pilhas de rede
nativa CFNetwork ou NSUrlSession . Por padrão, a nova plataforma de projetos do iOS usa a pilha de rede
NSUrlSession , para dar suporte ao TLS 1.2, e usa as APIs nativas para um desempenho melhor e um executável
de tamanho menor. Para saber mais, confira Seletor de implementação de HttpClient e SSL/TLS para
iOS/macOS.
Android
Os aplicativos do Xamarin em execução no Android podem usar a pilha de rede gerenciada HttpClient ou a
pilha de rede nativa AndroidClientHandler . Por padrão, a nova plataforma de projetos do Android usa a pilha de
rede AndroidClientHandler , para dar suporte ao TLS 1.2, e usa as APIs nativas para um desempenho melhor e
um executável de tamanho menor. Para obter mais informações sobre pilhas de rede do Android, consulte
seletor de implementação do HttpClient Stack e SSL/TLS para Android.

Especificar o endereço do computador local


O simulador do iOS e o emulador do Android fornecem acesso para proteger os serviços Web em execução no
computador local. No entanto, o endereço do computador local é diferente para cada um deles.
iOS
O simulador do iOS usa a rede do computador host. Portanto, os aplicativos em execução no simulador podem
se conectar aos serviços Web em execução no computador local por meio do endereço IP dos computadores ou
por meio do nome do host localhost . Por exemplo, considerando um serviço Web local seguro que expõe uma
operação GET por meio do URI relativo /api/todoitems/ , o aplicativo em execução no simulador do iOS pode
consumir a operação enviando uma solicitação GET ao https://localhost:<port>/api/todoitems/ .
NOTE
Ao executar um aplicativo móvel no simulador do iOS a partir do Windows, o aplicativo é exibido no simulador do iOS
remoto para Windows. No entanto, o aplicativo está sendo executado no Mac emparelhado. Portanto, não há nenhum
acesso de localhost a um serviço Web em execução no Windows para um aplicativo iOS em execução no Mac.

Android
Cada instância do emulador do Android é isolada das interfaces de rede de seu computador de
desenvolvimento e é executado atrás de um roteador virtual. Portanto, um dispositivo emulado não pode ver
seu computador de desenvolvimento ou outras instâncias do emulador na rede.
No entanto, o roteador virtual para cada emulador gerencia um espaço de rede especial que inclui os endereços
alocados previamente, sendo que o endereço 10.0.2.2 é um alias para a sua interface host de loopback
(127.0.0.1 em seu computador de desenvolvimento). Portanto, considerando um serviço Web local seguro que
expõe uma operação GET por meio do URI relativo /api/todoitems/ , o aplicativo em execução no emulador do
Android pode consumir a operação enviando uma solicitação GET ao https://10.0.2.2:<port>/api/todoitems/ .
Exemplo do Xamarin.Forms
Em um aplicativo Xamarin. Forms, a Device classe pode ser usada para detectar a plataforma em que o
aplicativo está sendo executado. O nome do host apropriado, que permite o acesso a serviços Web locais
seguros, pode ser definido da seguinte maneira:

public static string BaseAddress =


Device.RuntimePlatform == Device.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

Ignorar a verificação de segurança do certificado


A tentativa de invocar um serviço Web local seguro de um aplicativo em execução no simulador do iOS ou no
emulador Android resultará em uma HttpRequestException sendo acionada, mesmo ao usar a pilha de rede
gerenciada em cada plataforma. Isso ocorre porque o certificado de desenvolvimento HTTPS local é
autoassinado, e certificados autoassinados não são confiados pelo iOS nem pelo Android. Portanto, é necessário
ignorar os erros de SSL quando um aplicativo consome um serviço Web local seguro. Isso pode ser feito ao
usar as pilhas de rede gerenciadas e nativas no iOS e no Android, definindo a
ServerCertificateCustomValidationCallback propriedade em um HttpClientHandler objeto como um retorno de
chamada que ignora o resultado da verificação de segurança de certificado para o certificado de
desenvolvimento de HTTPS local:

// This method must be in a class in a platform project, even if


// the HttpClient object is constructed in a shared project.
public HttpClientHandler GetInsecureHandler()
{
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
return handler;
}

Nesse exemplo de código, o resultado de validação de certificado do servidor é retornado quando o certificado
que passar por validação não for o certificado localhost . Para esse certificado, o resultado da validação é
ignorado e true é retornado, indicando que o certificado é válido. O HttpClientHandler objeto resultante deve
ser passado como um argumento para o HttpClient construtor para compilações de depuração:

#if DEBUG
HttpClientHandler insecureHandler = GetInsecureHandler();
HttpClient client = new HttpClient(insecureHandler);
#else
HttpClient client = new HttpClient();
#endif

Links relacionados
TodoREST (amostra)
Habilitar o HTTPS local
Seletor de implementação de HttpClient e SSL/TLS para iOS/macOS
Seletor de implementação de SSL/TLS e da pilha HttpClient para Android
Configuração personalizada do Linker
23/04/2020 • 3 minutes to read • Edit Online

Se o conjunto padrão de opções não for o suficiente, faça o processo de vinculação com um arquivo XML que
descreve o que você deseja do vinculador.
Você pode fornecer definições extras para o vinculador para garantir que o tipo, os métodos e/ou os campos
não sejam eliminados do seu aplicativo. Em seu próprio código, o modo preferido é usar o atributo
personalizado [Preserve] , conforme discutido nos guias Vinculação no iOS e Vinculação no Android. No
entanto, se você precisar de algumas definições dos assemblies do SDK ou do produto, a melhor solução para
você poderá ser usar um arquivo XML (em vez de adicionar código que garantirá que o vinculador não
eliminará itens de que você precise).
Para fazer isso, você define um arquivo XML com o elemento de nível superior <linker> , que contém nós de
assembly que, por sua vez, contêm nós de tipo que, por sua vez, contêm nós de método e de campo.
Quando você tiver esse arquivo de descrição de vinculador, adicione-o ao seu projeto e:
Para o Android : defina a Ação de Build para LinkDescription
Para o iOS : defina a Ação de Build para LinkDescription
O exemplo a seguir mostra a aparência do arquivo XML:

<linker>
<assembly fullname="mscorlib">
<type fullname="System.Environment">
<field name="mono_corlib_version" />
<method name="get_StackTrace" />
</type>
</assembly>
<assembly fullname="My.Own.Assembly">
<type fullname="Foo" preserve="fields">
<method name=".ctor" />
</type>
<type fullname="Bar">
<method signature="System.Void .ctor(System.String)" />
<field signature="System.String _blah" />
</type>
<namespace fullname="My.Own.Namespace" />
<type fullname="My.Other*" />
</assembly>
</linker>

No exemplo acima, o vinculador lerá e aplicará as instruções aos assemblies mscorlib.dll (fornecido com o
Mono para Android) e My.Own.Assembly (código do usuário).
A primeira seção, para mscorlib.dll , garantirá que o tipo System.Environment preservará seu campo
denominado mono_corlib_version e seu método get_StackTrace . Observe que os nomes de método getter
e/ou setter devem ser usados, pois o vinculador funciona em IL e não entende propriedades do C#.
A segunda seção, para My.Own.Assembly.dll , garantirá que o tipo Foo preservará todos os seus campos (ou
seja, o atributo preserve="fields" ) e todos os seus construtores (ou seja, todos os métodos chamados .ctor
em IL). O tipo Bar preservará assinaturas específicas (não nomes) para um construtor (que aceita um único
parâmetro de cadeia de caracteres) e para um campo de cadeia de caracteres específica _blah . O namespace
My.Own.Namespace preservará todos os tipos que ele contém. Por fim, qualquer tipo cujo nome completo
(incluindo o namespace) corresponda ao padrão de curinga "My.Other*" preservará todos os seus campos e
métodos. O caractere curinga * pode ser incluído várias vezes dentro de um padrão "tipo nomecompleto".

Links relacionados
Vinculação no iOS
Vinculação no Android
Linker GitHub repo com exemplos
Depuração de vários processos
02/11/2020 • 14 minutes to read • Edit Online

É muito comum que as soluções modernas desenvolvidas no Visual Studio para Mac tenham vários projetos
com diferentes plataformas de destino. Por exemplo, uma solução pode ter um projeto de aplicativo móvel que
se baseia nos dados fornecidos por um projeto de serviço Web. Ao desenvolver essa solução, o desenvolvedor
pode precisar que os dois projetos sejam executados simultaneamente para solucionar erros. A partir da versão
Cycle 9 do Xamarin, o Visual Studio para Mac consegue depurar vários processos que estejam sendo executados
ao mesmo tempo. Isso possibilita definir pontos de interrupção, inspecionar variáveis e exibir threads em mais
de um projeto em execução. Isso é conhecido como depuração de vários processos.
Este guia discutirá algumas das alterações feitas no Visual Studio para Mac para dar suporte à depuração de
vários processos, como configurar soluções para depurar vários processos e como anexar a processos
existentes com o Visual Studio para Mac.

Requisitos
Depurar vários processos de exige o Visual Studio para Mac.

Alterações no IDE
Para ajudar os desenvolvedores com a depuração de vários processos, o Visual Studio para Mac passou por
algumas alterações em sua interface do usuário. O Visual Studio para Mac tem uma Barra de ferramentas de
depuração atualizada e uma nova seção Configuração de Soluções na pasta Opções da Solução . Além
disso, o Painel Threads agora exibirá os processos em execução e os threads de cada processo. O Visual Studio
para Mac também exibirá vários painéis de depuração, um para cada processo, para certas ações, como Saída
do Aplicativo .
Configurações da solução
Por padrão, o Visual Studio para Mac exibirá um projeto individual na área Configuração da Solução da barra
de ferramentas de depuração. Quando uma sessão de depuração é iniciada, esse é o projeto que o Visual Studio
para Mac iniciará e ao qual anexará o depurador.
Para iniciar e depurar vários processos no Visual Studio para Mac, é necessário criar uma configuração da
solução. Uma configuração da solução descreve quais projetos em uma solução devem ser incluídos quando
uma sessão de depuração é iniciada com um clique do botão Iniciar ou quando ⌘↩ (Cmd-Enter ) é
pressionado. A captura de tela a seguir é um exemplo de uma solução do Visual Studio para Mac que tem várias
configurações da solução:
Partes da barra de ferramentas de depuração
A barra de ferramentas de depuração foi alterada para permitir que uma configuração da solução seja
selecionada por meio de um menu pop-up. Esta captura de tela mostra as partes da barra de ferramentas de
depuração:

1. Configuração da Solução – É possível definir a configuração da solução clicando na configuração da


solução na barra de ferramentas de depuração e selecionando a configuração no menu pop-up:

2. Destino de Build – Identifica o destino de build para os projetos. Isso permanece inalterado em relação
às versões anteriores do Visual Studio para Mac.
3. Destinos de Dispositivo – Seleciona os dispositivos nos quais a solução será executada. É possível
identificar um dispositivo ou emulador separado para cada projeto:
Vários painéis de depuração
Quando a configuração de várias soluções for iniciada, alguns dos painéis do Visual Studio para Mac serão
exibidos várias vezes, uma para cada processo. Por exemplo, a captura de tela a seguir mostra dois painéis
Saída do Aplicativo para uma solução que está executando dois projetos:

Vários processos e o Thread Ativo


Quando um ponto de interrupção for encontrado em um processo, esse processo pausará a execução, enquanto
os outros processos continuarão em execução. Em um cenário de um único processo, o Visual Studio para Mac
pode facilmente exibir informações como threads, variáveis locais, saída do aplicativo em um único conjunto de
painéis. No entanto, quando há vários processos com diversos pontos de interrupção e, possivelmente, vários
threads, pode ser muito complicado para o desenvolvedor lidar com as informações de uma sessão de
depuração que esteja tentando exibir todas as informações de todos os threads (e processos) ao mesmo tempo.
Para resolver esse problema, o Visual Studio para Mac somente exibirá as informações de um thread por vez,
isso é conhecido como o thread ativo. O primeiro thread que faz uma pausa em um ponto de interrupção é
considerado o thread ativo. O thread ativo é aquele que é o foco de atenção do desenvolvedor. Os comandos de
depuração como Step Over ⇧⌘O (Shift-Cmd-O), serão emitidos para o thread ativo.
O Painel de Threads exibirá informações de todos os processos e threads que estão sob inspeção na
configuração da solução e fornecerá dicas visuais sobre o que é o thread ativo:
Os threads são agrupados pelo processo que os está hospedando. O nome do projeto e a ID do thread ativo
serão exibidos em negrito e uma seta apontando para a direita será exibida na medianiz ao lado do thread ativo.
Na captura de tela anterior, o thread n° 1 na ID do processo 48703 (FirstProject ) é o thread ativo.
Ao depurar vários processos, é possível mudar o thread ativo para ver informações de depuração desse
processo (ou thread) usando o Painel de Threads . Para mudar o thread ativo, selecione o thread desejado no
Painel de Threads e, em seguida, clique duas vezes nele.
Percorrendo o código quando vários projetos são interrompidos
Quando dois (ou mais) projetos tiverem pontos de interrupção, o Visual Studio para Mac pausará todos os
processos. Só é possível Step Over código no thread ativo. O outro processo estará em pausa até que uma
alteração de escopo possibilite que o depurador mude o foco do thread ativo. Por exemplo, considere a seguinte
captura de tela do Visual Studio para Mac depurando dois projetos:

Nessa tela, cada solução tem seu próprio ponto de interrupção. Quando a depuração começa, o primeiro ponto
de interrupção a ser encontrado está na linha 10 de MainClass no SecondProject . Como ambos os projetos
têm pontos de interrupção, os dois processos são interrompidos. Depois que o ponto de interrupção é
encontrado, cada invocação do Step Over fará com que o Visual Studio para Mac execute step over no código
do thread ativo.
A ação de percorrer o código está limitada ao thread ativo, portanto, o Visual Studio para Mac percorrerá uma
linha de código por vez, enquanto o outro processo ainda estiver em pausa.
Usando a captura de tela anterior como um exemplo, quando o loop de for for concluído, o Visual Studio para
Mac permitirá que o FirstProject seja executado até que o ponto de interrupção na linha 11 em MainClass
seja encontrado. Para cada comando Step Over , o depurador avança linha por linha no FirstProject , até que
os algoritmos de heurística internos do Visual Studio para Mac retornem o thread ativo para o SecondProject .
Se apenas um dos projetos tiver um ponto de interrupção definido, somente esse processo estará em pausa. O
outro projeto continuará em execução até que esteja em pausa pelo desenvolvedor ou que um ponto de
interrupção seja adicionado.
Pausando e retomando um processo
É possível pausar ou retomar um processo clicando com o botão direito do mouse no processo e selecionando
Pausar ou Retomar no menu de contexto:

A aparência da barra de ferramentas de depuração será alterada dependendo do estado dos projetos que estão
sendo depurados. Quando vários projetos estiverem em execução, a barra de ferramentas de depuração exibirá
os botões Pausar e Retomar quando houver pelo menos um projeto em execução e um projeto em pausa:

Clicar no botão Pausar na Barra de ferramentas de depuração pausará todos os processos que estão sendo
depurados, enquanto clicar nos botões Retomar retomará todos os processos em pausa.
Depurando um segundo projeto
Também é possível depurar um segundo projeto depois que o primeiro projeto for iniciado pelo Visual Studio
para Mac. Depois que o primeiro projeto for iniciado, *Clique com o botão direito do mouse no projeto no
Painel da Solução e selecione Iniciar Depuração de Item :
Criando uma configuração da solução
A configuração da solução informa ao Visual Studio para Mac qual projeto deve ser executado quando uma
sessão de depuração é iniciada com o botão Iniciar . Pode haver mais de uma configuração de solução por
solução. Isso torna possível especificar quais projetos são executados ao depurar o projeto.
Para criar uma nova configuração da solução no Xamaring Studio:
1. Abra a caixa de diálogo Opções da Solução no Visual Studio para Mac e selecione Executar >
Configurações :
2. Clique no botão Novo , insira o nome da nova configuração da solução e clique em Criar . A nova
configuração da solução será exibida na janela Configurações :

3. Selecione a nova configuração de execução na lista de configurações. A caixa de diálogo Opções da


Solução exibirá cada projeto na solução. Marque cada projeto que deverá ser iniciado quando uma
sessão de depuração for iniciada:
Agora, a configuração da solução MultipleProjects será exibida na Barra de ferramentas de depuração ,
permitindo que o desenvolvedor depure os dois projetos simultaneamente.

Resumo
Este guia discutiu a depuração de vários processos no Visual Studio para Mac. Ele abordou algumas das
alterações no IDE para dar suporte à depuração de vários processos e descreveu alguns dos comportamentos
associados.

Links Relacionados
Notas de versão do Xamarin Cycle 9
Plataforma cruzada para desenvolvedores de
desktop
23/04/2020 • 2 minutes to read • Edit Online

Esta seção contém informações para ajudar os desenvolvedores do WPF e Windows Forms a aprender o
desenvolvimento de aplicativos móveis com o Xamarin, fazendo referência cruzada a seus conhecimentos e
experiências existentes com os idiomas móveis e fornecendo exemplos de portar aplicativos da área de trabalho
para dispositivos móveis.

Comparação do ciclo de vida do aplicativo


Entender as diferenças entre os Estados de inicialização e de plano de fundo do aplicativo do WPF e Xamarin.
Forms.

Comparação de controles da interface do usuário


Referência rápida para localizar controles equivalentes em Windows Forms, WPF e Xamarin. Forms, incluindo
diretrizes adicionais sobre as diferenças entre o WPF e o Xamarin. Forms.

Diretrizes de portabilidade
Usando o analisador de portabilidade para ajudar a migrar o código do aplicativo de área de trabalho (excluindo
a interface do usuário) para Xamarin. Forms.

Amostras
Exemplos de referência que demonstram a arquitetura de aplicativos empresariais e o código de portabilidade
do WPF para Xamarin. Forms.

Saiba mais
Ciclo de vida do aplicativo WPF versus Xamarin.
Forms
15/01/2021 • 15 minutes to read • Edit Online

O Xamarin. Forms leva muitas diretrizes de design das estruturas baseadas em XAML que vieram antes dela,
especialmente o WPF. No entanto, de outras maneiras, ela se desvia significativamente, o que pode ser um
ponto adesivo para as pessoas que tentam migrar. Este documento tenta identificar alguns desses problemas e
fornece orientação quando possível para a ponte de conhecimento do WPF para Xamarin. Forms.

Ciclo de vida do aplicativo


O ciclo de vida do aplicativo entre o WPF e o Xamarin. Forms é semelhante. Ambos iniciam em código externo
(plataforma) e iniciam a interface do usuário por meio de uma chamada de método. A diferença é que o
Xamarin. Forms sempre inicia em um assembly específico da plataforma que inicializa e cria a interface do
usuário para o aplicativo.
WPF
Main method > App > MainWindow

NOTE
O Main método é, por padrão, gerado automaticamente e não visível no código.

Xamarin.Forms
iOS – Main method > AppDelegate > App > ContentPage
Android – MainActivity > App > ContentPage
UWP – Main method > App(UWP) > MainPage(UWP) > App > ContentPage

Classe de aplicativo
O WPF e o Xamarin. Forms têm uma Application classe que é criada como um singleton. Na maioria dos casos,
os aplicativos serão derivados dessa classe para fornecer um aplicativo personalizado, embora isso não seja
estritamente necessário no WPF. Ambos expõem uma Application.Current propriedade para localizar o
singleton criado.
Propriedades globais + persistência
O WPF e o Xamarin. Forms têm um Application.Properties dicionário disponível onde você pode armazenar
objetos globais no nível do aplicativo que são acessíveis em qualquer lugar no aplicativo. A principal diferença é
que o Xamarin. Forms manterá todos os tipos primitivos armazenados na coleção quando o aplicativo for
suspenso e os recarregará quando for reiniciado. O WPF não dá suporte automaticamente a esse
comportamento – em vez disso, a maioria dos desenvolvedores conta com armazenamento isolado ou utilizou
o Settings suporte interno.

Definindo páginas e a árvore visual


O WPF usa o Window como o elemento raiz para qualquer elemento visual de nível superior. Isso define um
HWND no mundo do Windows para exibir informações. Você pode criar e exibir tantas janelas simultaneamente
quanto desejar no WPF.
No Xamarin. Forms, o Visual de nível superior é sempre definido pela plataforma, por exemplo, no iOS, é um
UIWindow . O Xamarin. Forms renderiza o conteúdo para essas representações de plataforma nativas usando
uma Page classe. Cada um Page no Xamarin. Forms representa uma "página" exclusiva no aplicativo, em que
apenas uma é visível por vez.
WPFs Window e Xamarin. Forms Page incluem uma Title propriedade para influenciar o título exibido, e
ambos têm uma Icon propriedade para exibir um ícone específico para a página ( Obser ve que o título e o
ícone nem sempre são visíveis no Xamarin. Forms). Além disso, você pode alterar as propriedades visuais
comuns, como a cor ou a imagem do plano de fundo.
É tecnicamente possível renderizar para duas exibições de plataforma separadas (por exemplo, definir dois
UIWindow objetos e fazer com que o segundo seja renderizado para uma exibição externa ou Airplay), ele requer
o código específico da plataforma para fazer isso e não é um recurso diretamente suportado do Xamarin. Forms
em si.
Exibições
A hierarquia visual para ambas as estruturas é semelhante. O WPF é um pouco mais profundo devido ao seu
suporte a documentos WYSIWYG.
WPF

DependencyObject - base class for all bindable things


Visual - rendering mechanics
UIElement - common events + interactions
FrameworkElement - adds layout
Shape - 2D graphics
Control - interactive controls

Xamarin.Forms

BindableObject - base class for all bindable things


Element - basic parent/child support + resources + effects
VisualElement - adds visual rendering properties (color, fonts, transforms, etc.)
View - layout + gesture support

Ciclo de vida de exibição


O Xamarin. Forms é orientado principalmente em cenários móveis. Assim, os aplicativos são ativados ,
suspensos e reativados à medida que o usuário interage com eles. Isso é semelhante a clicar fora do Window em
um aplicativo do WPF e há um conjunto de métodos e eventos correspondentes que você pode substituir ou
conectar para monitorar esse comportamento.

F IN A L IDA DE M ÉTO DO W P F M ÉTO DO XA M A RIN . F O RM S

Ativação inicial Construtor + janela. pré-carregado ctor + Page. OnStart

Hubs Janela. IsVisibleChanged Página. aparecendo

Hidden Janela. IsVisibleChanged Página. desaparecendo

Suspender/perder foco Janela. OnActivated Page. onsleep

Ativado/obtido com foco Janela. OnActivated Page. retomar

Fechadas Janela. onfechando + janela. oncloseed N/D


Ambos dão suporte à ocultação/exibição de controles filho também, no WPF, é uma propriedade de três Estados
IsVisible (visível, oculta e recolhida). No Xamarin. Forms, ele está apenas visível ou oculto pela IsVisible
propriedade.
Layout
O layout de página ocorre na mesma 2 passagens (medida/organização) que ocorre no WPF. Você pode
conectar-se ao layout da página substituindo os seguintes métodos na classe Xamarin. Forms Page :

M ÉTO DO F IN A L IDA DE

OnChildMeasureInvalidated O tamanho preferencial de um filho foi alterado.

OnSizeAllocated A página recebeu uma largura/altura.

Evento layoutchanged Layout/tamanho da página alterado.

Não há evento de layout global chamado hoje, nem há um CompositionTarget.Rendering evento global como
encontrado no WPF.
Propriedades de layout comuns
O WPF e o Xamarin. Forms têm suporte Margin para controlar o espaçamento em um elemento e Padding
para controlar o espaçamento dentro de um elemento. Além disso, a maioria dos modos de exibição de layout
do Xamarin. Forms tem propriedades para controlar o espaçamento (por exemplo, linha ou coluna).
Além disso, a maioria dos elementos tem propriedades para influenciar como eles são posicionados no
contêiner pai:

WPF XA M A RIN . F O RM S F IN A L IDA DE

HorizontalAlignment Horizontaloptions Opções


esquerda/central/direita/alongar

VerticalAlignment Verticaloptions Opções


superior/central/inferior/ampliação

NOTE
A interpretação real dessas propriedades depende do contêiner pai.

Exibições de layout
O WPF e o Xamarin. Forms usam controles de layout para posicionar elementos filho. Na maioria dos casos, eles
são muito próximos um do outro em termos de funcionalidade.

WPF XA M A RIN . F O RM S EST ILO DO L AY O UT

StackPanel StackLayout Empilhamento infinito da esquerda


para a direita ou de cima para baixo

Grid Grid Formato de tabela (linhas e colunas)

DockPanel N/D Encaixar nas bordas da janela

Tela AbsoluteLayout Posicionamento de pixel/coordenado


WPF XA M A RIN . F O RM S EST ILO DO L AY O UT

WrapPanel N/D Pilha de encapsulamento

N/D RelativeLayout Posicionamento relativo baseado em


regra

NOTE
O Xamarin. Forms não dá suporte a um GridSplitter .

Ambas as plataformas usam Propriedades anexadas para ajustar os filhos.


Renderização
A mecânica de renderização para WPF e Xamarin. Forms é radicalmente diferente. No WPF, os controles criados
diretamente processam conteúdo para pixels na tela. O WPF mantém dois grafos de objeto ( árvores ) para
representar isso – a árvore lógica representa os controles conforme definidos no código ou XAML, e a árvore
visual representa a renderização real que ocorre na tela, que é executada diretamente pelo elemento visual (por
meio de um método de desenho virtual) ou por meio de um XAML definido ControlTemplate que pode ser
substituído ou personalizado. Normalmente, a árvore visual é mais complexa, pois inclui itens como bordas em
torno de controles, rótulos para conteúdo implícito, etc. O WPF inclui um conjunto de APIs ( LogicalTreeHelper
e VisualTreeHelper ) para examinar esses dois gráficos de objeto.
No Xamarin. Forms, os controles que você define em um Page são, na verdade, apenas objetos de dados
simples. Eles são semelhantes à representação de árvore lógica, mas nunca processam o conteúdo por conta
própria. Em vez disso, eles são o modelo de dados que influencia a renderização de elementos. A renderização
real é feita por um conjunto separado de renderizadores visuais que são mapeados para cada tipo de controle.
Esses renderizadores são registrados em cada um dos projetos específicos da plataforma por assemblies
Xamarin. Forms específicos da plataforma. Você pode ver uma lista aqui. Além de substituir ou estender o
renderizador, o Xamarin. Forms também tem suporte para efeitos que podem ser usados para influenciar a
renderização nativa em uma base por plataforma.
A árvore lógica/Visual
Não há API exposta para percorrer a árvore lógica no Xamarin. Forms-mas você pode usar a reflexão para obter
as mesmas informações. Por exemplo, aqui está um método que pode enumerar filhos lógicos com reflexão.

Gráficos
O Xamarin. Forms inclui um sistema gráfico para primitivos de desenho, que são chamados de formas. Para
obter mais informações sobre formas, consulte formas Xamarin. Forms. Além disso, você pode incluir
bibliotecas de terceiros, como SkiaSharp , para obter desenho 2D de plataforma cruzada.

Recursos
O WPF e o Xamarin. Forms têm o conceito de recursos e dicionários de recursos. Você pode inserir qualquer
tipo de objeto em um ResourceDictionary com uma chave e, em seguida, procurar {StaticResource} por coisas
que não serão alteradas ou {DynamicResource} para coisas que podem ser alteradas no dicionário em tempo de
execução. O uso e a mecânica são os mesmos com uma diferença: o Xamarin. Forms requer que você defina o
ResourceDictionary para atribuir à Resources propriedade, enquanto o WPF cria um e o atribui para você.

Por exemplo, consulte a definição abaixo:


WPF
<Window.Resources>
<Color x:Key="redColor">#ff0000</Color>
...
</Window.Resources>

Xamarin.Forms

<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="redColor">#ff0000</Color>
...
</ResourceDictionary>
</ContentPage.Resources>

Se você não definir o ResourceDictionary , um erro de tempo de execução será gerado.

Estilos
Os estilos também têm suporte total no Xamarin. Forms e podem ser usados para aplicar temas aos elementos
Xamarin. Forms que compõem a interface do usuário. Eles dão suporte a gatilhos (Propriedade, evento e dados),
herança por meio BasedOn do e pesquisas de recursos para valores. Os estilos são aplicados aos elementos
explicitamente por meio da Style propriedade ou implicitamente não fornecendo uma chave de recurso, assim
como o WPF.
Estilos de dispositivo
O WPF tem um conjunto de propriedades predefinidas (armazenadas como valores estáticos em um conjunto
de classes estáticas, como SystemColors ) que ditam cores do sistema, fontes e métricas na forma de valores e
chaves de recurso. O Xamarin. Forms é semelhante, mas define um conjunto de estilos de dispositivo para
representar as mesmas coisas. Esses estilos são fornecidos pela estrutura e definidos para valores com base no
ambiente de tempo de execução (por exemplo, acessibilidade).
WPF

<Label Text="Title" Foreground="{DynamicResource {x:Static SystemColors.DesktopBrushKey}}" />

Xamarin.Forms

<Label Text="Title" Style="{DynamicResource TitleStyle}" />


Comparação de controles da interface do usuário
02/11/2020 • 3 minutes to read • Edit Online

Veja abaixo uma comparação dos controles Xamarin. Forms com o Windows Forms e o WPF, com base nesta
tabela.
Leia mais sobre as semelhanças e diferenças entre o WPF e o Xamarin. Forms para ajudar a atualizar seu
conhecimento de área de trabalho para o desenvolvimento de aplicativos móveis.

W IN DO W S F O RM S WPF XA M A RIN . F O RM S

BindingNavigator - -

BindingSource CollectionViewSource Propriedade Binding, por exemplo,


BindingContext

Botão Botão Botão

CheckBox CheckBox Comutador

CheckedListBox ListBox com composição. ListView com composição.

ColorDialog - -

ComboBox ComboBox (não dá suporte para Seletor


preenchimento automático)

ContextMenuStrip ContextMenu -

DataGridView DataGrid -

DateTimePicker DatePicker DatePicker de & de seleção

DomainUpDown Caixa de texto e dois controles Passador


RepeatButton .

ErrorProvider - -

FlowLayoutPanel WrapPanel ou StackPanel StackLayout ou FlexLayout

FolderBrowserDialog - -

FontDialog - -

Formulário Window Página

GroupBox GroupBox -

HelpProvider Nenhum controle equivalente (use -


ToolTips).
W IN DO W S F O RM S WPF XA M A RIN . F O RM S

HScrollBar ScrollBar (a rolagem é incorporada aos usar ScrollView


controles de contêiner)

ImageList - -

Chamada Chamada Rótulo

LinkLabel Nenhum controle equivalente (você -


pode usar a classe Hyperlink para
hospedar hiperlinks dentro do
conteúdo do fluxo).

ListBox ListBox Usar ListView

ListView ListView ListView

MaskedTextBox - -

MenuStrip Menu Considere MasterDetailPage ou


TabbedPage

MonthCalendar Calendário -

NotifyIcon - -

NumericUpDown Caixa de texto e dois controles Passador


RepeatButton .

OpenFileDialog OpenFileDialog -

PageSetupDialog - -

Painel Tela Exibir ou AbsoluteLayout

PictureBox Imagem Imagem

PrintDialog PrintDialog -

PrintDocument - -

PrintPreviewControl DocumentViewer -

PrintPreviewDialog - -

ProgressBar ProgressBar ProgressBar

PropertyGrid - -

RadioButton RadioButton -
W IN DO W S F O RM S WPF XA M A RIN . F O RM S

RichTextBox RichTextBox O editor não dá suporte a texto rico


(formatado), entrada para texto de
linha única

SaveFileDialog SaveFileDialog -

ScrollableControl ScrollViewer ScrollView

SoundPlayer MediaPlayer -

SplitContainer GridSplitter Considerar MasterDetailPage

StatusStrip StatusBar -

TabControl TabControl TabbedPage

TableLayoutPanel Grid Grid

TextBox TextBox O editor não dá suporte a texto rico


(formatado)

Timer DispatcherTimer Dispositivo. StartTime ()

ToolStrip Barra Page. ToolbarItems e ToolbarItem

ToolStripContainer, Barra de ferramentas com composição. Page. ToolbarItems e ToolbarItem com


ToolStripDropDown, composição
ToolStripDropDownMenu,
ToolStripPanel

ToolTip ToolTip Usar recursos de acessibilidade

TrackBar Controle deslizante Controle deslizante

TreeView TreeView Considerar ListView hierárquico em um


NavigationPage

UserControl UserControl Exibir e também renderizadores


personalizados

VScrollBar ScrollBar usar ScrollView

WebBrowser WebBrowser WebView


WPF versus Xamarin. Forms: semelhanças &
diferenças
23/04/2020 • 14 minutes to read • Edit Online

Modelos de controle
O WPF dá suporte ao conceito de modelos de controle que fornecem as instruções de visualização para um
controle ( Button , ListBox , etc.). Conforme mencionado acima, o Xamarin. Forms usa classes de renderização
concretas para isso, que interagem com a plataforma nativa (Ios, Android etc.) para visualizar o controle.
No entanto, o Xamarin. Forms tem um tipo de ControlTemplate -ele é usado para Page objetos do. Ele fornece
uma definição para um Page que fornece conteúdo consistente, mas permite que o usuário da página altere
cores, fontes etc. e até mesmo adicione elementos para torná-lo exclusivo ao aplicativo.
Usos comuns para isso são coisas como caixas de diálogo de autenticação, prompts e fornecer uma aparência
de página padronizada, mas que pode ser orientada, que podem ser personalizadas no aplicativo. Como parte
desse suporte, muitos controles nomeados com WPF conhecidos são usados:
1. ContentPage
2. ContentView
3. ContentPresenter
4. TemplateBinding

Mas é importante saber que eles não atendem à mesma finalidade no Xamarin. Forms. Para obter mais
informações sobre esse recurso, confira a página de documentação.

XAML
O XAML é usado como a linguagem de marcação declarativa para WPF e Xamarin. Forms. Na maior parte, a
sintaxe é idêntica – a principal diferença são os objetos definidos/criados pelos grafos XAML.
O Xamarin. Forms dá suporte à especificação XAML 2009; Isso facilita a definição de dados, como
string s, int s, etc., bem como a definição de tipos genéricos e a passagem de argumentos para
construtores.
Atualmente, não há como carregar dinamicamente XAML, como o WPF, pode com XamlReader . No
entanto, você pode obter a mesma funcionalidade básica com um pacote NuGet .
Extensões de marcação
O Xamarin. Forms dá suporte à extensão de XAML por meio de extensões de marcação, assim como o WPF. Ele
tem os mesmos blocos de construção básicos:
1. {x:Array}
2. {Binding}
3. {DynamicResource}
4. {x:Null}
5. {x:Static}
6. {StaticResource}
7. {x:Type}
Além disso, ele inclui {x:Reference} da especificação XAML 2009 e uma {TemplateBinding} extensão de
marcação que é usada para a versão especializada do ControlTemplate com suporte do Xamarin. Forms.

WARNING
O suporte a ControlTemplate não é o mesmo, embora tenha o mesmo nome.

O Xamarin. Forms também dá suporte a extensões de marcação personalizadas, mas a implementação é um


pouco diferente. No WPF, você deve derivar de MarkupExtension -uma classe base abstrata. No Xamarin. Forms,
isso é substituído por uma interface IMarkupExtension ou IMarkupExtension<T> que é mais flexível.
Assim como o WPF, o único método necessário é um método ProvideValue para retornar o valor da extensão
de marcação.

Infraestrutura de associação
Um dos principais conceitos transferidos é uma infra-estrutura de ligação de dados para conectar propriedades
visuais a propriedades de dados do .NET. Isso permite padrões de arquitetura como MVVM. O design básico é
idêntico-você tem uma classe base vinculável vinculobject, no WPF, essa é a classe DependencyObject . Essa
classe base é usada como o ancestral raiz para todos os objetos que participarão como destinos na associação
de dados. As classes derivadas expõem os objetos vinculproperty que atuam como o armazenamento de
backup para valores de propriedade (eles são definidos como objetos DependencyProperty no WPF).
Definindo propriedades vinculáveis
A definição de uma propriedade vinculável no Xamarin. Forms é a mesma do WPF:
1. O objeto deve derivar de BindableObject .
2. Deve haver um campo estático público do tipo BindableProperty declarado para definir a chave de
armazenamento de backup para a propriedade.
3. Deve haver um wrapper de propriedade de instância pública que usa GetValue e SetValue para recuperar e
alterar o valor das propriedades.
Para obter um exemplo completo, consulte propriedades vinculáveis no Xamarin. Forms.
Propriedades anexadas
As propriedades anexadas são um subconjunto da propriedade vinculável e funcionam da mesma maneira que
no WPF. A principal diferença é que o wrapper de propriedade é omitido nesse caso e substituído por um
conjunto de métodos get/set estáticos na classe proprietária. Consulte Propriedades anexadas no Xamarin.
Forms para obter mais informações.
Usando o mecanismo de associação
O processo para usar o mecanismo de associação é o mesmo que no WPF. Ele pode ser utilizado no code-
behind criando um objeto Binding vinculado a um objeto de origem (qualquer tipo .NET) e um valor de
propriedade opcional (se omitido, ele trata o objeto de origem como a própria propriedade, assim como o WPF).
Em seguida, você pode usar SetBinding em qualquer BindableObject para associar a associação a uma
BindableProperty .

Como alternativa, você pode definir a relação de associação em XAML usando o BindingExtension . Ele tem os
mesmos valores básicos que a extensão no WPF.
O suporte e o mecanismo de ligação são mais semelhantes à implementação do Silverlight do que o WPF. Há
vários recursos ausentes que não foram implementados no Xamarin. Forms:
Não há suporte para os seguintes recursos em associações:
BindingGroupName
BindsDirectlyToSource
IsAsync
MultiBinding
NotifyOnSourceUpdated
NotifyOnTargetUpdated
NotifyOnValidationError
UpdateSourceTrigger
UpdateSourceExceptionFilter
ValidatesOnDataErrors
ValidatesOnExceptions
Coleção de ValidationRules
XPath
XmlNamespaceManager
RelativeSource
Não há suporte para associações de RelativeSource . No WPF, eles permitem que você se vincule a outros
elementos visuais definidos em XAML. No Xamarin. Forms, esse mesmo recurso pode ser obtido usando a
extensão de marcação {x:Reference} . Por exemplo, supondo que tenhamos um controle com o nome
"otherControl" que tem uma propriedade Text, podemos associar a ele da seguinte maneira:
WPF

Text={Binding RelativeSource={RelativeSource otherControl}, Path=Text}

Xamarin.Forms

Text={Binding Source={x:Reference otherControl}, Path=Text}

O mesmo recurso pode ser usado para o recurso de {RelativeSource Self} . No entanto, não há suporte para
localizar ancestrais por tipo ( {RelativeSource FindAncestor} ).
Contexto de associação
No WPF, você pode definir um valor de propriedade DataContext que reprents a fonte de associação padrão. Se
a origem de uma associação não for definida, esse valor de propriedade será usado. O valor é herdado para
baixo na árvore visual, permitindo que ele seja definido em um nível mais alto e, em seguida, usado por filhos.
No Xamarin. Forms, esse mesmo recurso é disponíveis, mas o nome da propriedade é BindingContext .
Conversores de valor
Os conversores de valor têm suporte total no Xamarin. Forms, assim como o WPF. A mesma forma de interface
é usada, mas o Xamarin. Forms tem a interface definida no namespace Xamarin.Forms .
Model-View-ViewModel
O MVVM é totalmente suportado pelo WPF e Xamarin. Forms.
O WPF inclui um RoutedCommand interno que às vezes é usado; O Xamarin. Forms não tem suporte de comando
interno além da definição de interface ICommand . Você pode incluir uma variedade de estruturas MVVM para
adicionar as classes base necessárias para implementar o MVVM.
INotifyPropertyChanged e INotifyCollectionChanged
Ambas as interfaces têm suporte total em associações do Xamarin. Forms. Ao contrário de muitas estruturas
baseadas em XAML, as notificações de alteração de propriedade podem ser geradas em threads em segundo
plano no Xamarin. Forms (assim como o WPF) e o mecanismo de associação fará a transição apropriada para o
thread da interface do usuário.
Além disso, os dois ambientes dão suporte a SynchronziationContext e async / await fazer Marshalling de
thread adequado. O WPF inclui a classe Dispatcher em todos os elementos visuais, o Xamarin. Forms tem um
método estático Device.BeginInvokeOnMainThread que também pode ser usado (embora SynchronizationContext
seja preferencial para codificação de plataforma cruzada).
O Xamarin. Forms inclui um ObservableCollection<T> que oferece suporte a notificações de alteração de
coleção.
Você pode usar BindingBase.EnableCollectionSynchronization para habilitar atualizações entre threads para
uma coleção. A API é ligeiramente diferente da variação do WPF, Verifique os detalhes de uso dos
documentos.

Modelos de dados
Modelos de dados têm suporte no Xamarin. Forms para personalizar a renderização de uma ListView linha
(célula). Ao contrário do WPF, que pode utilizar DataTemplate s para qualquer controle orientado a conteúdo, o
Xamarin. Forms atualmente os usa apenas para ListView . A definição do modelo pode ser definida como
embutida (atribuída à propriedade ItemTemplate ) ou como um recurso em um ResourceDictionary .
Além disso, eles não são tão flexíveis quanto seus equivalentes do WPF.
1. O elemento raiz da DataTemplate deve sempre ser um objeto ViewCell .
2. Os gatilhos de dados têm suporte total em um modelo de dados, mas devem incluir uma propriedade
DataType indicando o tipo da propriedade à qual o gatilho está associado.
3. também há suporte para DataTemplateSelector , mas deriva de DataTemplate e, portanto, atribuído
diretamente à propriedade ItemTemplate (vs. ItemTemplateSelector no WPF).

ItemsControl
Não há nenhum equivalente interno a um ItemsControl no Xamarin. Forms; Mas há um personalizado para o
Xamarin. Forms disponível aqui.

Controles de usuário
No WPF, UserControl s são usadas para fornecer uma seção da interface do usuário que tem comportamento
associado. No Xamarin. Forms, usamos o ContentView para a mesma finalidade. Ambos dão suporte à
associação e à inclusão em XAML.

Navegação
O WPF inclui um NavigationService raramente usado que pode ser usado para fornecer um recurso de
navegação "como navegador". A maioria dos aplicativos não se preocupa com isso no entanto e, em vez disso,
usava diferentes elementos de Window ou seções diferentes da janela para exibir dados.
Em dispositivos de telefone, telas diferentes geralmente são a solução e, portanto, o Xamarin. Forms inclui
suporte para várias formas de navegação:

EST ILO DE N AVEGA Ç Ã O T IP O DE PÁ GIN A

Baseado em pilha (Push/pop) NavigationPage

Mestre/Detalhes MasterDetailPage
EST ILO DE N AVEGA Ç Ã O T IP O DE PÁ GIN A

Tabulações TabbedPage

Passar o dedo para a esquerda/direita CarouselView

O NavigationPage é a abordagem mais comum, e cada página tem uma propriedade Navigation que pode ser
usada para enviar e desativar páginas na pilha de navegação. Esse é o equivalente mais próximo ao
NavigationService encontrado no WPF.

Navegação de URL
O WPF é uma tecnologia orientada a desktops e pode aceitar parâmetros de linha de comando para direcionar o
comportamento de inicialização. O Xamarin. Forms pode usar a vinculação de URL profunda para saltar para
uma página na inicialização.
Diretrizes de portabilidade de aplicativos para
desktop
02/11/2020 • 5 minutes to read • Edit Online

A maioria dos códigos de aplicativo pode ser categorizada em uma das seguintes áreas:
Código da interface do usuário (por exemplo, janelas e botões)
controles de terceiros (por exemplo, spersão
Lógica de negócios (por exemplo, regras de validação)
Armazenamento e acesso a dados locais
Serviços Web e acesso a dados remotos
Para aplicativos Windows Forms e WPF escritos com C# (ou Visual Basic.NET), uma quantidade surpreendente
de lógica de negócios, acesso a dados locais e código de serviços Web pode ser compartilhada entre
plataformas.

.NET Portability Analyzer


O Visual Studio 2017 e versões posteriores dão suporte ao .net Portability Analyzer (download para Windows),
que pode examinar seus aplicativos existentes e informar a quantidade de código que pode ser transportada
"no estado em que se encontra" para outras plataformas. Você pode aprender mais sobre isso neste vídeo do
Channel 9.
Também há uma ferramenta de linha de comando que pode ser baixada do analisador de portabilidade no
GitHub e usada para fornecer os mesmos relatórios.

"x% do meu código é portátil. O que vem a seguir? "


Felizmente, o analisador mostra que uma grande parte do seu código é portátil, mas certamente haverá
algumas partes de cada aplicativo que não podem ser movidas para outras plataformas.
Partes diferentes de código provavelmente se enquadram em um desses buckets, explicados em mais detalhes
abaixo:
Código portátil reutilizado
Código que requer alterações
Código que não é portátil e requer uma nova gravação
Código portátil reutilizado
O código .NET que é gravado em relação às APIs disponíveis em todas as plataformas pode ser feito de
plataforma cruzada. Idealmente, você poderá mover todo esse código para uma biblioteca de classes portátil,
uma biblioteca compartilhada ou uma biblioteca de .NET Standard e, em seguida, testá-lo em seu aplicativo
existente.
Essa biblioteca compartilhada pode então ser adicionada a projetos de aplicativos para outras plataformas
(como Android, iOS, macOS).
Código que requer alterações
Algumas APIs do .NET podem não estar disponíveis em todas as plataformas. Se essas APIs existirem no seu
código, você precisará reescrever essas seções para usar APIs de plataforma cruzada.
Exemplos disso incluem o uso de APIs de reflexão que estão disponíveis no .NET 4,6, mas não estão disponíveis
em todas as plataformas.
Depois de reescrever o código usando APIs portáteis, você deve ser capaz de empacotar esse código em uma
biblioteca compartilhada e testá-lo em seu aplicativo existente.
Código que não é portátil e requer uma nova gravação
Exemplos de código que não é provável que sejam entre plataformas, incluem:
Interface do usuário – as telas Windows Forms ou WPF não podem ser usadas em projetos no
Android ou Ios, por exemplo. Sua interface de usuário precisará ser reescrita, usando essa comparação de
controles como uma referência.
Código de Armazenamento específico da plataforma que se baseia em uma tecnologia específica da
plataforma (como um banco de dados SQL Server Express local). Você precisará escrever novamente isso
usando uma alternativa de plataforma cruzada (como o SQLite para o mecanismo de banco de dados).
Algumas operações do sistema de arquivos também podem precisar ser ajustadas, já que a UWP tem
APIs um pouco diferentes para Android e iOS (por exemplo, alguns sistemas de filediferenciam
maiúsculas de minúsculas e outros não.
componentes de terceiros – Verifique se os componentes de terceiros em seus aplicativos estão
disponíveis em outras plataformas. Alguns, como pacotes NuGet não visuais, podem estar disponíveis,
mas outros (especialmente controles visuais como gráficos ou media players)

Dicas para tornar o código portátil


Injeção de dependência – fornecer implementações diferentes para cada plataforma e
Abordagem em camadas – seja MVVM, MVC, MVP ou algum outro padrão que ajude a separar o
código portátil do código específico da plataforma.
Mensagens – você pode usar a passagem de mensagens em seu código para desassociar interações
entre diferentes partes do aplicativo.
Exemplos de área de trabalho entre plataformas
02/11/2020 • 2 minutes to read • Edit Online

WPF para plataforma cruzada com Xamarin. Forms


Aplicativo de despesas
Origem do WPFToMobile no GitHub
Aplicativo original
WPF + WCF
Aplicativos de plataforma cruzada
Usando o Xamarin. Forms, o aplicativo original foi capaz de portar para um back-end do Azure que é executado
em dispositivos móveis, tablets e desktops:
Android
iOS
Plataforma Universal do Windows

Diretrizes para arquitetura


Aplicativo eShop (no contêineres)
origem do eShopOnContainers no GitHub
Aplicativo de exemplo referenciado pelo seguinte:
Livro eletrônico de microservices do .NET
Livro eletrônico de ciclo de vida de aplicativo Docker em contêiner
Padrões de aplicativos empresariais usando o Xamarin. Forms ebook

Exemplos de aplicativos móveis


Outros exemplos do Xamarin
Solução de problemas do Xamarin
23/04/2020 • 2 minutes to read • Edit Online

Problemas gerais
Perguntas frequentes
Perguntas frequentes sobre a plataforma Xamarin e respostas específicas ao Visual Studio.
Atualizar referências de componentes para NuGet
Como atualizar as soluções Xamarin existentes para alterar Referências de componentes para pacotes NuGet.

Perguntas específicas do produto


Android
iOS
Xamarin.Forms
Perguntas frequentes gerais
23/04/2020 • 5 minutes to read • Edit Online

Bibliotecas de Classes Portáteis


Como posso exibir as bibliotecas com suporte em um PCL?
Este guia lista recursos e métodos para determinar se a biblioteca existente tem suporte nas várias plataformas
de destino PCL ou pode ser convertida em um perfil PCL.
API de reflexão de PCL
A Microsoft desenvolveu uma nova API de reflexão para uso em bibliotecas de classes portáteis. Se você tiver
algum código de reflexão existente que deseja mover para um PCL, ele poderá não funcionar.
Estudo de caso de PCL: como posso resolver problemas relacionados a System.Diagnostics.Tracing para o
pacote NuGet de Fluxo de Dados de TPL da Microsoft?
O xamarin. iOS e o Xamarin. Android não implementam 100% de cada perfil PCL que eles permitem como
referências. Para conveniência prática no Visual Studio para Mac, no Visual Studio e no Gerenciador de pacotes
NuGet, os projetos do Xamarin permitem o uso de vários perfis que têm apenas implementações incompletas.
Por exemplo, nem Xamarin. iOS nem Xamarin. Android atualmente incluem uma implementação completa dos
tipos no namespace de System.Diagnostics.Tracing PCL. Você pode contornar isso alternando o projeto de
aplicativo para fazer referência à versão portátil-Net45 + win8 + WP8 + wpa81 da biblioteca de Dataflow TPL.

Pacotes NuGet & componentes do Xamarin


Como posso atualizar o NuGet?
As atualizações, extensões e suplementos do NuGet podem ser encontrados na guia atualizações no
Gerenciador de pacotes NuGet . Navegação detalhada para localizar as atualizações no Visual Studio para
Mac & o Visual Studio está neste guia.
Como fazer downgrade de um pacote NuGet?
Visual Studio para Mac & o Visual Studio tem recursos para selecionar versões mais antigas de pacotes e
instalá-los automaticamente; semelhante a como a atualização de pacotes funciona.
Erro de pacotes ausentes após a atualização dos pacotes NuGet
Esse problema foi relatado principalmente em soluções de aplicativo de exemplo do Xamarin. Forms, mas o
potencial para esse problema pode ocorrer em qualquer projeto que usa pacotes NuGet.
Unificar os componentes do Google Play Services e o NuGet
Há vários componentes Google Play Services e pacotes NuGet, mas para facilitar as coisas para os
desenvolvedores, agora nós unificamos nossos componentes e pacotes NuGet em duas. Em quase todos os
casos, Google Play Services deve ser usado. O único motivo para usar o pacote (Froyo) é se você estiver
pretendendo ativamente a Froyo.
Onde meus componentes são armazenados no meu computador?
Sempre que você instala um componente do Xamarin em um projeto de aplicativo, ele é colocado nos dois
locais listados neste guia.

Solução de problemas
Onde posso encontrar informações e logs da minha versão?
Este guia fornece detalhes sobre onde encontrar a maioria das informações de diagnóstico que podem ser
usadas para solucionar problemas com o Xamarin.
Quando e como eu devo criar um relatório de bugs?
Este guia fornece dicas para o arquivamento de relatórios de bugs de alta qualidade, para que nossos
engenheiros possam determinar a causa (e quaisquer possíveis correções) para um problema com mais
eficiência.
Por que não há suporte para Jenkins no Xamarin?
Jenkins é um pacote de CI de código-fonte aberto; por causa dessa quantidade de problemas que são
provocados diretamente pelo Jenkins em si , precisarão ser arquivados como problemas em relação ao local em
que você obteve o código; como o repositório Jenkins principalou o repositório para Jenkins. app.
Quais configurações do projeto são necessárias para o depurador?
Para que o depurador funcione conforme o esperado (pontos de interrupção de acesso, exibir logs de depuração
etc.), a instrumentação do desenvolvedor e a exibição de informações de depuração devem ser habilitadas. Este
guia fornece detalhes sobre como localizar e ativar essas configurações.
Como posso exibir as bibliotecas com suporte em
um PCL?
02/11/2020 • 2 minutes to read • Edit Online

Você pode encontrar uma visão geral dos vários recursos com suporte nas várias plataformas de destino
PCL na parte recursos com suporte desta página: https://docs.microsoft.com/dotnet/standard/cross-
platform/cross-platform-development-with-the-portable-class-library
Outra opção é usar o analisador de portabilidade do .net para avaliar se sua biblioteca existente pode ser
convertida em um perfil PCL.
Uma terceira possibilidade é procurar o conteúdo do perfil real que você possa usar. Usando o perfil 78,
por exemplo, você pode ir aqui:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile78\ e
exibir todos os assemblies dentro dele.
Seja qual for o método escolhido, observe que algumas funcionalidades têm que ser baixadas por meio do
NuGet e da biblioteca Microsoft BCL.
API de Reflexão de PCL
23/04/2020 • 2 minutes to read • Edit Online

A Microsoft desenvolveu uma nova API de reflexão para uso em bibliotecas de classes portáteis. Se você tiver
algum código de reflexão existente que deseja mover para um PCL, ele poderá não funcionar. Para saber mais:
Desenvolvendo a API de reflexão
StackOverflow: biblioteca de classes portátil e reflexão
Estudo de caso de PCL: como posso resolver
problemas relacionados a
System.Diagnostics.Tracing para o pacote NuGet de
Fluxo de Dados de TPL da Microsoft?
23/04/2020 • 11 minutes to read • Edit Online

IMPORTANT
Esse exemplo específico de System.Diagnostic.Tracing não produz mais erros por padrão nas versões mais recentes
do Xamarin. Embora a solução alternativa sugerida ainda funcione, observe que alguns dos bugs mencionados na seção
"camadas de erros" foram corrigidos. Além disso, você deve observar que .NET Standard agora é a maneira preferida de
implementar APIs .NET entre plataformas.

Resumo
O xamarin. iOS e o Xamarin. Android não implementam 100% de cada perfil PCL que eles permitem como
referências. Para conveniência prática no Visual Studio para Mac, no Visual Studio e no Gerenciador de pacotes
NuGet, os projetos do Xamarin permitem o uso de vários perfis que têm apenas implementações incompletas .
Por exemplo, nem Xamarin. iOS nem Xamarin. Android atualmente incluem uma implementação completa dos
tipos no namespace PCL "System. Diagnostics. Tracing". Essa limitação leva a três camadas de erros ao tentar
usar a versão de portable-net45+win8+wpa81 padrão do pacote NuGet do Microsoft TPL Dataflow.

Solução alternativa: mude o projeto de aplicativo para fazer referência


à versão portable-net45+win8+wp8+wpa81 da biblioteca de fluxo de
aplicativos TPL
(Isso evita todas as três camadas de erros e funciona para todas as versões recentes do Xamarin.)
1. Abra o arquivo Project . csproj do aplicativo em um editor de texto.
2. Localize a linha que é semelhante a esta:

<HintPath>..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-
net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>

3. Alterar portable-net45+win8+wpa81 para portable-net45+win8+wp8+wpa81 ( +wp8 é adicionado):

<HintPath>..\packages\System.Threading.Tasks.Dataflow.4.5.25\lib\portable-
net45+win8+wp8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>

Explicação
A versão portable-net45+win8+wp8+wpa81 da biblioteca não faz referência a System. Diagnostics. Tracing. dll
_, por_isso evita completamente todas as três camadas de problemas.
Limitações
A versão portable-net45+win8+wp8+wpa81 da biblioteca pode não incluir 100% da funcionalidade da
versão portable-net45+win8+wpa81 .
O Gerenciador de pacotes NuGet instala a versão portable-net45+win8+wpa81 do pacote do NuGet PCL
por padrão, portanto, você deve ajustar a referência manualmente.

Detalhes sobre as três camadas de erros


1. O assembly de fachada System. Diagnostics. Tracing. dll está ausente atualmente de todas as versões
Mac do Xamarin. Android (bug não público 34888) e está ausente de todas as versões do Xamarin. Ios
inferiores a 9,0 (ou inferior a XamarinVS 3.11.1443 no Windows) (corrigido em Bug 32388). Esse
problema causará um dos seguintes erros dependendo do destino da implantação e das configurações
do vinculador:
Xamarin. Android. Common. targets: erro: exceção ao carregar assemblies: System. IO.
FileNotFoundException: não foi possível carregar o assembly ' System. Diagnostics. Tracing, versão
= 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a '. Talvez ele não exista no perfil
mono para Android?
Não foi possível carregar o arquivo ou o assembly ' System. Diagnostics. Tracing ' ou uma de suas
dependências. O sistema não pode encontrar o arquivo especificado. (System. IO.
FileNotFoundException)
MTOUCH: Error MT3001: não foi possível AOT o assembly
'/Users/macuser/Projects/TPLDataflow/UnifiedSingleViewIphone1/obj/iPhone/Debug/mtouch-
cache/64/Build/System.Threading.Tasks.Dataflow.dll '
MTOUCH: Error MT2002: falha ao resolver o assembly: ' System. Diagnostics. Tracing, Version =
4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a '
2. A implementação mono atual dos tipos em "System. Diagnostics. Tracing" não tem algumas sobrecargas
de método (bug 27337). Esse problema causará um dos seguintes erros de vinculador ao criar um
aplicativo Xamarin:
/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Comm
on.targets: erro: erro ao executar a tarefa LinkAssemblies: erro XA2006: referência ao item de
metadados ' System. void System. Diagnostics. Tracing. EventSource:: WriteEvent (System. Int32,
System. Object []) ' (definido em ' System. Threading. Tasks. Dataflow, Version = 4.5.24.0, Culture =
neutral, PublicKeyToken = b03f5f7f11d50a3a ') de ' System. Threading. Tasks. Dataflow, Version =
4.5.24.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a ' não pôde ser resolvido.
MTOUCH: Error MT2002: falha ao resolver "System. void System. Diagnostics. Tracing.
EventSource:: WriteEvent (System. Int32, System. Object [])" referência de "System. Diagnostics.
Tracing, versão = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a"
3. A implementação mono atual dos tipos em "System. Diagnostics. Tracing" também é uma implementação
"fictícia" vazia (bug 34890). Qualquer tentativa de usar esses métodos em tempo de execução pode,
portanto, gerar resultados inesperados. Para o caso específico da biblioteca de Dataflow do Microsoft tpl,
parece que as chamadas para WriteEvent(System.Int32,System.Object[]) não são essenciais para a maior
parte do comportamento da biblioteca, portanto, a correção para "camada 2" (bug 27337, adicionando
implementações vazias) provavelmente será suficiente para maioria dos casos de uso do Microsoft TPL
Dataflow.

Perguntas & respostas


Eu consegui deixar a vinculação habilitada com a versão portable-net45+win8+wpa81 da biblioteca em versões
mais antigas do Xamarin. iOS ou no Xamarin. Android. Como isso funcionou?
Atenda
É possível fazer com que a compilação seja concluída "com êxito" (com vinculação habilitada) em versões mais
antigas do Xamarin. Ios ou no Xamarin. Android no Mac se você incluir uma referência ao assembly de
referência System.Diagnostics.Tracing.dll [1] em vez de o assembly de fachada [2], mas infelizmente essa não
é uma solução alternativa "correta". Os assemblies de referência só devem ser usados durante a criação de
bibliotecas portáteis, não o código específico da plataforma, como aplicativos. A tentativa de executar o código
contido em assemblies de referência (em vez de apenas criar a partir dele) provavelmente produzirá resultados
inesperados. A correção correta será para que a equipe mono adicione a sobrecarga de
WriteEvent(System.Int32,System.Object[]) ausente ao tipo de EventSource (bug 27337). Por enquanto, a melhor
opção é alternar para a versão portable-net45+win8+wp8+wpa81 da biblioteca de Dataflow do Microsoft TPL,
conforme discutido na seção solução alternativa acima.
(Para qualquer pessoa que possa estar lendo este artigo depois de ver uma resposta mais antiga e mais curta
do StackOverflow (https://stackoverflow.com/a/23591322/2561894), observe que a distinção entre assemblies
de referência e o assembly de fachada não foi mencionada lá.)
[1] locais de "assembly de referência"
Windows:
C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\.NETPortable\v4.5\System.Diagnostics.Tracing.dll

Mac (mono):
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-
frameworks/.NETPortable/v4.5/System.Diagnostics.Tracing.dll

[2] locais de "assembly fachada"


Windows:
C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll

Mac (mono):
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/System.Diagnostics.Tracing.dll

Ajudará se eu adicionar manualmente uma referência ao assembly de fachada "System. Diagnostics. Tracing"?
Em particular, é possível resolver o problema usando essas duas etapas?
1. Copie o System.Diagnostics.Tracing.dll assembly de fachada na pasta do projeto de aplicativo de um
dos seguintes locais:
Windows:
C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll

Mac (mono):
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/System.Diagnostics.Tracing.dll

2. Adicione uma referência ao assembly de fachada no projeto de aplicativo Xamarin. iOS ou Xamarin.
Android.
Atenda
Não, isso não ajudará.
Para o Xamarin. iOS 9,0 ou qualquer versão recente do Xamarin. Android no Windows, essa solução
alternativa é estritamente redundante e pode causar erros de compilação semelhantes a "um assembly '
System. Diagnostics. Tracing ' com a mesma identidade já foi importado.".
Para o Xamarin. iOS 8,10 ou inferior ou para o Xamarin. Android no Mac, essa solução alternativa ajudará
apenas para o problema de assembly "camada 1" ausente. Ele não resolverá os erros de vinculador de
"camada 2", portanto, não é uma solução completa.
Posso usar o pacote NuGet System. Diagnostics. Tracing para resolver o problema?
Atenda
Não, o pacote NuGet 3,0 "System. Diagnostics. Tracing" inclui apenas implementações específicas de plataforma
para "DNXCore50" e "netcore50". Ele omite explicitamente as implementações para Xamarin. Android
("monoandroid") e Xamarin. Ios ("MonoTouch" e "xamarinios"). Isso significa que a instalação do pacote não terá
nenhum efeito para os projetos Xamarin. Android e Xamarin. Ios. O pacote NuGet pressupõe que essas duas
plataformas fornecem sua própria implementação dos tipos. Essa suposição é "correta" no sentido de que o
mono tem uma implementação do namespace, mas, como discutido nos pontos #2 e #3 de "detalhes sobre as
três camadas de erros" acima, a implementação está incompleta no momento. Portanto, a correção correta será
para que a equipe mono resolva o bug 27337 e o bug 34890.

Próximas etapas
Para obter mais assistência, entrar em contato conosco ou, se esse problema permanecer mesmo depois de
utilizar as informações acima, consulte quais opções de suporte estão disponíveis para o Xamarin? para obter
informações sobre opções de contato, sugestões, bem como como arquivar um novo bug, se necessário .
Como posso atualizar o NuGet?
23/04/2020 • 2 minutes to read • Edit Online

As atualizações, extensões e suplementos do NuGet podem ser encontrados na guia atualizações no


Gerenciador de pacotes NuGet . Navegação detalhada para localizar as atualizações no Visual Studio para
Mac & o Visual Studio está abaixo.
Observe que as atualizações só serão mostradas nesses menus se você não tiver a versão mais recente com
suporte do NUGET pelo IDE instalada:

Visual Studio
1. Abrir ferramentas > extensões e atualizações > atualizações > Galeria do Visual Studio
2. Selecione Gerenciador de pacotes NuGet para Visual Studio [ano]

Visual Studio para Mac


1. Abrir as extensões do Visual Studio para Mac > > atualizações > extensões IDE
2. Selecionar Gerenciamento de pacotes NuGet
Como fazer downgrade de um pacote NuGet?
23/04/2020 • 2 minutes to read • Edit Online

Visual Studio para Mac & o Visual Studio tem recursos para selecionar versões mais antigas de pacotes e
instalá-los automaticamente; semelhante a como a atualização de pacotes funciona. Essas etapas são descritas
abaixo.

Visual Studio
1. Vá para ferramentas > Gerenciador de pacotes NuGet > console do Gerenciador de pacotes
2. Definir o projeto em projeto padrão
3. Use esta sintaxe:

Install-Package [Pacotename]-versão [guia para o menu versão]

Você também pode copiar/colar o comando exato da página do NuGet do pacote. Exemplo para Xamarin.
Forms: https://www.nuget.org/packages/Xamarin.Forms/

Visual Studio para Mac


1. Em seu projeto, clique com o botão direito do mouse na pasta pacotes & selecione adicionar pacotes
2. No Searchbar, você pode usar a seguinte sintaxe para pesquisar os pacotes necessários:
[PackageName] version:*

Exemplos
Lista todos os pacotes Xamarin. Forms:
Xamarin.Forms version:

Lista todos os pacotes Xamarin. Forms 1.4. x:


Xamarin.Forms version:1.4

NOTE
Se você adicionar um espaço entre version: & o número de versão, a pesquisa se comportará como embora nenhuma
versão tenha sido especificada.
Erro de pacotes ausentes após a atualização dos
pacotes NuGet
23/04/2020 • 2 minutes to read • Edit Online

Esse problema foi relatado principalmente em soluções de aplicativo de exemplo do Xamarin. Forms, mas o
potencial para esse problema pode ocorrer em qualquer projeto que usa pacotes NuGet.
Se depois de atualizar os pacotes do NuGet em seu projeto ou solução, você verá um erro que faz referência aos
números de versão do pacote antigo, como:

Error: This project references NuGet package(s) that are missing on this computer.
Enable NuGet Package Restore to download them.
For more information, see http://go.microsoft.com/fwlink/?LinkID=322105

The missing file is ../../packages/Xamarin.Forms.1.3.1.6296/build/portable-


win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10/Xamarin.Forms.targets. (FormsGallery)

Neste exemplo, Xamarin. Forms. 1.3.1.6296 é o número de versão antigo que foi removido com a atualização do
pacote NuGet.
Isso pode acontecer se os elementos XML no arquivo. csproj que fazem referência ao número de versão do
pacote antigo tiverem sido adicionados ou editados manualmente, o NuGet não os removerá ou atualizará se
tiverem sido adicionados/editados manualmente, portanto, o projeto agora está procurando pacotes que foram
excluídos.
Para corrigir esse problema, edite manualmente os arquivos. csproj e exclua todos os elementos que fazem
referência ao número de versão antigo.
Elementos de exemplo a serem removidos (se tiverem o número de versão do pacote antigo):

<Reference Include="Xamarin.Forms.Maps">
<HintPath>..\..\packages\Xamarin.Forms.Maps.1.3.1.6296\lib\portable-
win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Maps.dll</HintPath>
</Reference>

<Import Project="..\..\packages\Xamarin.Forms.1.3.1.6296\build\portable-
win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets"
Condition="Exists('..\..\packages\Xamarin.Forms.1.3.1.6296\build\portable-
win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.1.3.1.6296\build\portable-
win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')"
Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.1.3.1.6296\build\portable-
win+net45+wp80+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets'))" />
Unificar os componentes do Google Play Services e
o NuGet
23/04/2020 • 4 minutes to read • Edit Online

Histórico
Você costumava ter vários componentes Google Play Services e pacotes NuGet:
Google Play Services (Froyo)
Google Play Services (Gingerbread)
Google Play Services (ICS)
Google Play Services (JellyBean)
Google Play Services (KitKat)
Na verdade, o Google envia apenas dois arquivos. jar para Google Play Services:
google-play-services-froyo.jar
google-play-services.jar

A discrepância existia porque nossas ferramentas não informaram corretamente aapt.exe qual era o nível
máximo de API de recurso a ser usado para um determinado aplicativo. Isso significa que recebemos erros de
compilação se tentarmos usar a associação de Google Play Services (KitKat) em um nível de API inferior, como
Gingerbread.

Unificando Google Play Services


Em versões mais recentes do Xamarin. Android, agora dizem aapt.exe qual versão de recurso máxima usar,
portanto, esse problema desaparece para nós.
Isso significa que não há nenhum motivo real para ter pacotes separados para Gingerbread/ICS/JellyBean/KitKat
(no entanto, ainda precisamos de uma associação separada para Froyo, uma vez que é um arquivo. jar
diferente).
Para facilitar as coisas para os desenvolvedores, agora nós unificamos os nossos componentes e pacotes NuGet
em duas:
Google Play Services (Froyo) (associa google-play-services-froyo.jar )
Google Play Services (associa google-play-services.jar )
Qual delas deve ser usada?
Em quase todos os casos, Google Play Services deve ser usado. O único motivo para usar o pacote (Froyo) é se
você estiver pretendendo ativamente a Froyo. O único motivo pelo qual esse arquivo. jar separado existe no
Google é que o Froyo está em um pequeno percentual de dispositivos, eles em si decidiram parar de dar
suporte a ele, portanto, esse arquivo. jar é um instantâneo congelado e sem suporte de Google Play Services.
Observação sobre Gingerbread
O Gingerbread não tem suporte de fragmento por padrão e, por isso, algumas das classes na associação não
serão utilizáveis em um aplicativo em tempo de execução em um dispositivo Gingerbread. Classes como
MapFragment não funcionarão em Gingerbread, e sua variante de suporte deverá ser usada em vez
SupportMapFragment . Cabe ao desenvolvedor saber o que usar. Essa incompatibilidade é observada pelo Google
em sua documentação Google Play Services.
O que acontece com os componentes antigos/NuGet?
Como eles não são mais necessários, desabilitamos/deslistamos os seguintes componentes/NuGets:
Google Play Services (Gingerbread)
Google Play Services (JellyBean)
Google Play Services (KitKat)
O componente/NuGet existente do Google Play Services (ICS) foi renomeado para Google Play Services e será
mantido atualizado no futuro. Todos os projetos que fazem referência a um dos pacotes
desabilitados/deslistados devem ser atualizados para usar este.
Os componentes desabilitados ainda existem e devem ser restauráveis para projetos nos quais eles ainda são
referenciados, para evitar dividi-los. Da mesma forma, os pacotes NuGet deslistados ainda existem e podem ser
restaurados. Eles não serão atualizados no futuro.
Onde meus componentes são armazenados no meu
computador?
23/04/2020 • 2 minutes to read • Edit Online

Sempre que você instala um componente do Xamarin em um projeto de aplicativo, ele é colocado em dois
locais:
1. Em uma pasta de componentes no nível raiz da pasta da solução. Se você remover o componente de
todos os projetos na solução, ele também será removido dessa pasta.
2. Uma cópia também é armazenada nos seguintes locais:
Windows: %LocalAppData%\Xamarin\Cache\Components
Mac: ~/Library/Caches/Xamarin/Components
Portanto, para remover completamente um componente do seu sistema, exclua-o de seus projetos/soluções e
da pasta de cache acima.
Onde posso encontrar informações e logs da minha
versão?
02/11/2020 • 7 minutes to read • Edit Online

Contorno
Informações de versão
Informações de versão do Windows
Informações de versão do Mac
Android SDK Tools, plataforma-ferramentas, compilação-ferramentas
Logs do IDE e do instalador
Logs do Windows
Xamarin Studio
Xamarin para Visual Studio
Instalador universal do Xamarin
.msi Instaladores individuais, logs detalhados
Inicialização do Visual Studio, logs detalhados
Logs do Mac
Host de compilação
Visual Studio para Mac
Xamarin Studio
Instalador do Xamarin
Saída de compilação detalhada
Logs de depuração para aplicativos Xamarin. Android e Xamarin. iOS
Logs de logcat do Android adb
logs do simulador do iOS (no Mac)
logs de dispositivo iOS (no Mac)

Informações de versão
Geralmente, é melhor enviar de volta todas as informações dos botões copiar informações . Caso contrário,
muitas vezes precisaremos solicitar informações adicionais. Por exemplo, as versões do sistema operacional, a
versão do Xcode, os níveis de API do Android instalados e a versão do .NET podem ser importantes ao ajudar a
solucionar um problema.
Informações de versão do Windows
Xamarin Studio
Ajuda > sobre > mostrar detalhes > copiar informações [botão]
Visual Studio
Ajuda > sobre Microsoft Visual Studio > copiar informações [botão]
Informações de versão do Mac
Visual Studio para Mac
Visual Studio > sobre o Visual Studio > mostrar detalhes > copiar informações [botão]
Android SDK Tools, plataforma-ferramentas, compilação -ferramentas
Abra o Gerenciador de SDK do Android e faça uma captura de tela da seção de ferramentas principais.
Visual Studio para Mac
Ferramentas > Abrir Gerenciador de SDK do Android
Visual Studio
Ferramentas > Android > Abrir Gerenciador de SDK do Android...

Logs do IDE e do instalador


Para cada local de log, não se esqueça de compactar e anexar a pasta de log inteira.
Logs do Windows
Ferramentas do Visual Studio para Xamarin
%LOCALAPPDATA%\Xamarin\Logs

Visual Studio 2017


Como obter os logs de instalação do Visual Studio
Visual Studio 2015
Instalador "Universal" do Xamarin
%LOCALAPPDATA%\Xamarin\Universal

Esses são os logs do XamarinInstaller.exe instalador.


.msi Instaladores individuais, logs detalhados

msiexec /i Xamarin.msi /l*vx "%USERPROFILE%\Desktop\Xamarin.log"

Referência: Opções de linha de comando


Inicialização do Visual Studio, logs detalhados

devenv.exe /log "%USERPROFILE%\Desktop\VisualStudio.log"

Referência: /log (devenv.exe)


Logs do Mac
Você pode selecionar o item de menu ir > ir para a pasta no localizador e, em seguida, copiar e colar
qualquer um desses caminhos na caixa de diálogo.
Visual Studio para Mac
~/Library/Logs/VisualStudio/7.0 (esse número pode mudar dependendo da versão que você está usando)
Essa pasta também pode ser aberta por meio de "ajuda-> abrir diretório de log".
Xamarin Studio
~/Library/Logs/XamarinStudio-6.0 (esse número pode mudar dependendo da versão que você está usando)
Essa pasta também pode ser aberta por meio de "ajuda-> abrir diretório de log".
Instalador "Universal" do Xamarin
~/Library/Logs/XamarinInstaller/Universal

Esses são os logs do XamarinInstaller.dmg instalador.


Host de Build do Xamarin
~/Library/Logs/Xamarin-[MAJOR.MINOR]
Saída de compilação detalhada
1. Habilite a saída do MSBuild de diagnóstico.
2. Para aplicativos iOS, também habilite a saída mTouch detalhada adicionando -v -v -v -v em
Propriedades do projeto > Build do IOS > geral (guia) > opções adicionais > argumentos
mTouch adicionais .
3. Limpar e recompilar o projeto.
4. Copie e cole a saída da compilação do IDE em um arquivo de texto.
Visual Studio (Windows): exibir > saída > Mostrar saída de: Build
Visual Studio para Mac: exibir > Pads > erros > saída da compilação (guia)

Logs de depuração para aplicativos Xamarin. Android e Xamarin. iOS


Visual Studio para Mac
Exibir > pads > saída do aplicativo
(Observe que esse item de menu aparecerá somente depois que o aplicativo tiver sido iniciado.)
Visual Studio
Exibir > saída > Mostrar saída de: Depurar
Logs de logcat do Android adb

Depois de executar o adb comando, anexe novamente o arquivo de android_logcat.txt da área de trabalho.
Essas instruções pressupõem que você tenha apenas um dispositivo anexado.
Consulte também a página log de depuração do Android .
Visual Studio
1. Ferramentas > Android > iniciar prompt de comando do ADB do Android
2. Limpe o log: adb logcat -c
3. Reproduza o problema.
4. Saída do log: adb logcat -vtime -d > "%USERPROFILE%\Desktop\android_logcat.txt"
Visual Studio para Mac
1. Ferramentas > abrir SDK do Android prompt de comando
2. Limpe o log: adb logcat -c
3. Reproduza o problema.
4. Saída do log: adb logcat -vtime -d > ~/Desktop/android_logcat.txt
logs do simulador do iOS (no Mac)
Para acessar o log do sistema, selecione depurar > abrir log do sistema... no aplicativo do simulador
de Ios.
Para exibir relatórios de falhas do simulador, abra o console. app e navegue até
~/Library/Logs > DiagnosticReports .

logs de dispositivo iOS (no Mac)


Visual Studio para Mac
Exibir painéis de > > log do dispositivo iOS
Xcode
Dispositivos > do Windows > $ {DeviceName}
Os relatórios de falha estão disponíveis no botão Exibir logs do dispositivo . O log do sistema para o
dispositivo aparece na parte inferior da janela sob a seta de divulgação.
Xcode 5
Windows > Galler y > dispositivos (guia) > $ {DeviceName}
Quando e como devo criar um relatório de bugs?
02/11/2020 • 7 minutes to read • Edit Online

TIP
Usar o item de menu relatar um problema no Visual Studio – , isso enviará informações de diagnóstico junto com o
relatório de bugs para ajudar a resolver o problema.
Há instruções detalhadas para o visual studio 2019 ou o visual studio 2017 e o Visual Studio para Mac.
Você pode pesquisar relatórios existentes no site da comunidade de desenvolvedores do Visual Studio .

Arquivar um bug se...


Você tem um conjunto de etapas que você considera que os engenheiros poderão usar para reproduzir um
problema.
OU
Você pode descrever cuidadosamente os sintomas visíveis do problema, especialmente se você também pode
descrever algumas circunstâncias precisas relacionadas ao problema. [1]

Práticas recomendadas para ajudar a resolver bugs com rapidez e


eficiência
1. Pesquise a comunidade de desenvolvedores do Visual Studio e a Web para obter relatórios de bugs ou
sugestões de uso existentes que possam resolver o problema diretamente. [2][3]
2. Descreva o problema da forma mais clara e concisa possível, incluindo uma descrição do que aconteceu e
deveria acontecer.
3. Inclua quaisquer rastreamentos de pilha relevantes, texto de mensagem de erro ou logs de falha (se você
usar o recurso relatar um problema , eles poderão ser incluídos automaticamente). quatro
4. Anote todas as mensagens de erro importantes que aparecem em anexos de captura de tela como texto
sem formatação.
5. Inclua um caso de teste pequeno e independente que reproduza o bug com o mínimo de código possível.
Se você não puder reproduzir o problema com um projeto novo (criado usando um dos modelos
internos), envie um projeto que demonstre o problema e anexe-o ao relatório de bugs. Torne o projeto de
exemplo o mais simples possível antes de anexá-lo. [5][6]
6. Descreva o ambiente em que o bug foi encontrado, incluindo o sistema operacional e as versões do
Xamarin e quaisquer dependências.

Detalhes adicionais
1. ^ Idealmente, a descrição dos "sintomas visíveis" deve incluir detalhes suficientes para que outros
clientes possam confirmar se estão vendo o mesmo problema (as mesmas mensagens de erro, a mesma
degradação de desempenho, o mesmo rastreamento de pilha de uma falha etc.). Para "circunstâncias
precisas", um bom exemplo seria se você disser algo como: "normalmente, atingi o problema de 75% do
tempo, mas se eu alterar essa coisa, posso evitar o problema completamente". Outro exemplo
semelhante de uma "circunstância precisa" é se o downgrade para uma versão anterior do Xamarin parar
o problema.
2. ^ Como você poderia esperar, os trechos de texto de erro (ou qualquer outro texto descritivo com
exclusividade) geralmente são os melhores termos de pesquisa. Se o relatório de bugs existente estiver
incompleto, você poderá adicionar detalhes ou arquivar um novo relatório de bugs melhor.
3. ^ Outra boa pergunta é se o mesmo problema foi relatado para aplicativos Java, Objective-C ou Swift.
Nesse caso, o problema é, provavelmente, parte do Android ou do iOS em vez de fazer parte do Xamarin.
4. ^ Alguns exemplos de informações a serem incluídas:
a. Para erros que ocorrem durante a compilação de um projeto, inclua a saída completa do Build de
diagnóstico no relatório de bugs.
b. Para erros que ocorrem ao criar ou depurar um projeto do iOS do Visual Studio, execute ajuda >
Xamarin > logs zip depois de acessar o erro e incluir o arquivo. zip resultante no relatório de
bugs.
c. Para exceções ou falhas em aplicativos Android ou iOS, inclua os logs de depuração relevantes
para aplicativos xamarin. Android e xamarin. Ios.
5. ^ Se possível para seu problema específico, uma opção é recriar o problema adicionando um pequeno
número de arquivos de sua solução original em uma solução totalmente nova. A equipe do Xamarin
muitas vezes será capaz de investigar problemas mesmo em casos de teste maiores (supondo que as
etapas para reproduzir sejam explicadas claramente), mas casos de teste mais simples dão a melhor
chance de que o bug seja resolvido rapidamente.
6. ^ Se não for possível reproduzir o problema adicionando um pequeno número de arquivos a uma
solução totalmente nova, você poderá compactar e anexar a pasta da solução inteira para seu aplicativo
completo. Exclua as bin obj pastas,, Components e packages para tornar o arquivo zip menor. (O IDE e
o processo de compilação geralmente restauram ou recriam o conteúdo dessas pastas conforme
necessário.) Você também pode excluir quantos arquivos de código e de recursos do projeto desejar,
desde que a solução resultante ainda demonstre o problema original.
Por que o Jenkins não tem suporte da Microsoft?
23/04/2020 • 3 minutes to read • Edit Online

Explicação de suporte do Jenkins


Jenkins é um pacote de CI de código-fonte aberto; por causa dessa quantidade de problemas que são
provocados diretamente pelo Jenkins em si , precisarão ser arquivados como problemas em relação ao local em
que você obteve o código; como o repositório Jenkins principalou o repositório para Jenkins. app.
A exceção a isso é para problemas que podem ser isolados para bugs específicos nas ferramentas do Xamarin;
Se você suspeitar disso para ser o caso, poderá verificar suas Opções de suporte, porém, o problema pode ser
algo fora do que a equipe de suporte do Xamarin pode ajudar diretamente .

Configurar o Jenkins com o Xamarin


Embora conforme observado acima, os problemas de Jenkins não têm suporte diretamente pela nossa equipe;
o guia usando o Jenkins com o xamarin pode ser usado para configurar um servidor de CI do Jenkins integrado
ao Xamarin.

Correções para problemas comuns


Jenkins não consegue localizar o SDK do Android
A mensagem de erro para esse problema é algo assim:

erro XA5205: não foi possível encontrar o diretório SDK do Android. Defina por meio de/p:
AndroidSdkDirectory

As opções para definir o local do SDK podem variar dependendo do plug-in exato do Jenkins do Android que
você está usando; um bom local para procurar como definir isso está no guia do plug-in. Por exemplo; o plug-in
Android Emulator procura automaticamente o SDK, mas se ele não conseguir encontrá-lo; o local também pode
ser definido por meio da página de configuração do sistema Jenkins para esse plug-in.

Erros preteridos
IMPORTANT
Esse problema foi resolvido nas versões recentes do Xamarin. No entanto, se o problema ocorrer na versão mais recente
do software, registre um novo bug com suas informações completas de controle de versão e saída de log de compilação
completa.

Jenkins relata uma licença do Xamarin inválida


As mensagens de erro para esse problema normalmente são algo como

Erro de XA9008: a criação da linha de comando requer uma licença de negócios

ou

Erro: a edição inicial do Xamarin. iOS não oferece suporte à compilação fora do Xamarin Studio
A causa mais comum desse cenário é o uso do Jenkins fazendo logon com uma conta de usuário não associada
à sua licença do Xamarin. A maneira mais simples de resolver isso é instalar o Jenkins como um aplicativo
diretamente por meio da conta de usuário. Esse processo e algumas considerações adicionais são descritos aqui:
https://forums.xamarin.com/discussion/comment/99397/#Comment_99397
Quais configurações do projeto são necessárias
para o depurador?
23/04/2020 • 2 minutes to read • Edit Online

Para que o depurador funcione conforme o esperado (pontos de interrupção de acesso, exibir logs de depuração
etc.), a instrumentação do desenvolvedor e a exibição de informações de depuração devem ser habilitadas.
Siga estas etapas para verificar as configurações do seu ambiente:

Visual Studio
1. Abrir as opções de projeto
2. Vá para compilação > avançado... Definir informações de depuração como completas
3. Configurações para cada plataforma:
Vá para Opções do Android > opções de depuração . Marque a caixa habilitar instrumentação
do desenvolvedor .
Vá para depuração do iOS > depuração de & instrumentação . Marque a caixa de seleção
Habilitar depuração .

Visual Studio para Mac


1. Abrir as opções de projeto
2. Vá para compilar > compilador > opções gerais . Definir informações de depuração como completas
3. Configurações para cada plataforma:
Acesse compilar > Android build > opções de depuração . Marque a caixa habilitar
instrumentação do desenvolvedor .
Vá para compilar > depuração do IOS . Marque a caixa de seleção Habilitar depuração .
Implantar caixas de seleção desabilitadas no
Configuration Manager
02/11/2020 • 2 minutes to read • Edit Online

Já que os projetos Xamarin 3.5, Xamarin.iOS eram implantados automaticamente sempre que você pressionava
o botão de barra de ferramentas Iniciar ou selecionava o item de menu Depurar > Iniciar depuração . Você
ainda precisará definir o projeto de aplicativo Xamarin. iOS desejado como o projeto de inicialização antes
de executar qualquer um desses comandos.
Por isso, as caixas de seleção Implantar são intencionalmente desabilitadas no Configuration Manager do
Visual Studio para projetos do Xamarin.iOS:

Essa alteração elimina um erro que pode aparecer em versões mais antigas do Xamarin (versão 3.3 e anterior)
quando o projeto do aplicativo Xamarin.iOS não era definido para implantação:
Extensões do Visual Studio ausentes após a
instalação
02/11/2020 • 4 minutes to read • Edit Online

Mensagem de erro: este projeto é incompatível com a edição atual do


Visual Studio
Verifique se o Visual Studio 2017 (Community, Professional ou Enterprise) ou mais recente está instalado.
Consulte também os requisitos do Windows.

Correção possível 1: altere a instalação para verificar se as extensões


do Visual Studio estão instaladas
Em determinadas situações, o instalador do Xamarin pode desmarcar automaticamente as opções de instalação
das extensões do Visual Studio. Se essa for a causa do problema, instale as extensões ausentes do Visual Studio
usando o comando Alterar do instalador. Por exemplo, para instalar as extensões do Visual Studio 2013:
1. Abra o Painel de Controle Programas e Recursos do Windows.
2. Clique com botão direito do mouse na entrada Xamarin e selecione Alterar .
3. Clique em Avançar e, em seguida, Alterar .
4. Verifique se a opção Xamarin para Visual Studio 2013 está definida como instalar:

5. Continue com o restante do Assistente de instalação.

Correção possível 2: solicitar que o Visual Studio configure as


extensões novamente
1. Verifique se as extensões do Xamarin foram copiadas para a pasta de extensões do Visual Studio:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\Xamarin\3.1.228.0

Se as extensões estiverem instaladas corretamente (para a versão 3.1.228), haverá 60 itens na pasta:

2. Depois de confirmar que essa pasta parece correta, informe ao Visual Studio para tentar configurar as
extensões novamente:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe" /setup

Correção possível 3: Tente uma reinstalação nova do Xamarin


1. No Painel de Controle do Windows, desinstale qualquer um dos seguintes itens que estiverem presentes:
Xamarin
Xamarin para Windows
Xamarin.Android
Xamarin.iOS
Xamarin para Visual Studio
2. No Explorer, exclua todos os arquivos restantes das pastas de extensão do Xamarin Visual Studio (todas
as versões, incluindo arquivos de programas e arquivos de programas (x86) ):
C:\Program Files*\Microsoft Visual Studio 1*.0\Common7\IDE\Extensions\Xamarin

3. Verifique também no diretório "VirtualStore" para ver se há alguma cópia de "sobreposição" de qualquer
um dos diretórios de extensão:
%LOCALAPPDATA%\VirtualStore

4. Abra o Editor do Registro (regedit).


5. Procure por esta chave:
HKEY _ local _ MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDlls
6. Localize e exclua as entradas que correspondem a esse padrão:
C:\Arquivos de programas * \Microsoft Visual Studio 1 * . 0 \ Common7\IDE\Extensions\Xamarin
7. Procure por esta chave:
HKEY\_CURRENT\_USER\Software\Microsoft\VisualStudio\1\*.0\ExtensionManager\PendingDeletions

8. Exclua as entradas que parecem ser relacionadas ao Xamarin. Por exemplo, aqui está uma que costumava
causar problemas em versões mais antigas do Xamarin:
Mono.VisualStudio.Shell,1.0
9. Reinicialize.
10. Reinstale a versão estável atual do Xamarin em VisualStudio.com.

Correção possível 4: reparar a instalação do Visual Studio


1. Abra o Painel de Controle Programas e Recursos do Windows.
2. Clique com botão direito do mouse na entrada pertinente do Microsoft Visual Studio e selecione Alterar
3. Clique no botão Reparar na caixa de diálogo do Visual Studio que é aberta.
Como executar uma desinstalação completa do
Xamarin para Visual Studio?
23/04/2020 • 4 minutes to read • Edit Online

1. No Painel de Controle do Windows, desinstale qualquer um dos seguintes itens que estiverem presentes:
Xamarin
Xamarin para Windows
Xamarin.Android
Xamarin.iOS
Xamarin para Visual Studio
2. No Explorer, exclua todos os arquivos restantes nas pastas de extensão do Xamarin para Visual Studio
(todas as versões, incluindo Arquivos de Programas e Arquivos de Programas (x86) ):
C:\Arquivos de Programas*\Microsoft Visual Studio 1*.0\Common7\IDE\Extensions\Xamarin
3. Exclua também o diretório de cache do componente MEF (Managed Extensibility Framework) do Visual
Studio:
%LOCALAPPDATA%\Microsoft\VisualStudio\1*.0\ComponentModelCache
Na verdade, essa etapa por si só geralmente é suficiente para resolver erros, como:
"O pacote 'XamarinShellPackage' não foi carregado corretamente"
"Não é possível carregar o arquivo de projeto... Há um subtipo de projeto ausente"
"Referência de objeto não definida para uma instância de um objeto. em
Xamarin.VisualStudio.IOS.XamarinIOSPackage.Initialize()"
"Falha de SetSite para o pacote" (no ActivityLog.xml do Visual Studio)
"Falha de LegacySitePackage para o pacote" (no ActivityLog.xml do Visual Studio)
(Consulte também a extensão Limpar Cache de Componente MEF do Visual Studio. E consulte o Bug
40781, comentário 19 para um pouco mais contexto sobre o problema upstream no Visual Studio que
pode causar esses erros.)
4. Verifique também no diretório VirtualStore para ver se o Windows pode ter armazenado arquivos de
sobreposição para os diretórios Extensões\Xamarin ou ComponentModelCache em:
%LOCALAPPDATA%\VirtualStore
5. Abra o Editor de Registro ( regedit ).
6. Procure a seguinte chave:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDlls
7. Localize e exclua as entradas que correspondem a esse padrão:
C:\Arquivos de Programas*\Microsoft Visual Studio 1*.0\Common7\IDE\Extensions\Xamarin
8. Procure por esta chave:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\1*.0\ExtensionManager\PendingDeletions
9. Exclua as entradas que parecem ser relacionadas ao Xamarin. Por exemplo, aqui está uma que costumava
causar problemas em versões mais antigas do Xamarin:
Mono.VisualStudio.Shell,1.0
10. Abra um prompt de comando cmd.exe como administrador e execute os comandos devenv /setup e
devenv /updateconfiguration para cada versão instalada do Visual Studio. Por exemplo, para o Visual
Studio 2015:

"%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" /setup


"%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" /updateconfiguration

11. Reinicialize.
12. Reinstale a versão estável atual do Xamarin usando do VisualStudio.com.

Etapas adicionais de solução de problemas para "o pacote não foi


carregado corretamente"
Aqui estão mais algumas etapas para experimentar, caso as etapas acima não resolvam o erro "o pacote não foi
carregado corretamente".
1. Crie uma nova conta de usuário do Windows.
2. Verifique se as extensões do Xamarin para Visual Studio carregam sem erro para o novo usuário.
3. Se as extensões carregarem corretamente, o problema será provavelmente causado por algumas das
configurações armazenadas do usuário original:
No Explorer – %LOCALAPPDATA%\Microsoft\VisualStudio\1*.0
No regedit – HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\1*.0
No regedit – HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\1*.0_Config
4. Se essas configurações armazenadas realmente parecem ser o problema, você pode tentar fazer o
backup e, em seguida, excluí-las.
Como posso coletar as pilhas de chamadas atuais
do processo do Visual Studio?
02/11/2020 • 2 minutes to read • Edit Online

Quando a GUI é bloqueada (trava, congela) no Visual Studio, uma parte importante das informações de
diagnóstico a serem coletadas é o conjunto de pilhas de chamadas de todos os threads do processo do Visual
Studio. Para salvar essas informações para uma instância suspensa do Visual Studio, você pode usar uma
segunda instância do Visual Studio:
1. Inicie uma segunda instância (uma nova janela) do Visual Studio.
2. Feche as soluções abertas na nova instância do Visual Studio.
3. Selecione Depurar > Anexar ao processo .

4. Selecione a instância original travada de devenv.exe da lista de processos Disponíveis .


5. Selecione Depurar > Interromper Tudo .

6. Selecione depurar > Salvar despejo como .


7. Altere salvar como tipo para minidespejo ( * . dmp) . Isso produzirá um arquivo muito menor do que
o minidespejo com heap , e o heap geralmente não é relevante para o diagnóstico de congelamento.

8. Salve o arquivo de despejo. Se estiver enviando o arquivo online, você poderá recompactá-lo para
reduzir o tamanho.
Por que o Visual Studio não inclui meu projeto de
biblioteca referenciado no build?
23/04/2020 • 2 minutes to read • Edit Online

O Visual Studio usa o Configuration Manager para determinar quais projetos em uma solução são incluídos
automaticamente em determinada configuração de build ou implantação.
Alguns modelos gerados com um projeto de biblioteca referenciada já terão a biblioteca referenciada incluída
na configuração; caso contrário, ela precisará ser definida manualmente.

Como usar o Configuration Manager


1. Abra Compilar > Configuration Manager
2. Selecione a configuração a ser personalizada, por exemplo, debug | iPhone
3. Marque as caixas de seleção para os projetos que deseja incluir.

NOTE
As caixas esmaecidas são manipuladas automaticamente e não precisam de nenhuma alteração.

Screencast destas etapas: https://screencast.com/t/zLoQOpEn


Atualizando referências de componente para o
NuGet
02/11/2020 • 9 minutes to read • Edit Online

IMPORTANT
A loja de componentes foi descontinuada a partir de 15 de maio de 2018 (este fechamento foi originalmente anunciado
em novembro de 2017).
Os componentes do Xamarin não têm mais suporte no Visual Studio e devem ser substituídos por pacotes NuGet. Siga as
instruções abaixo para remover manualmente as referências de componente de seus projetos.

Consulte estas instruções para adicionar pacotes NuGet no Windows ou Mac.


Uma lista de plug- ins e bibliotecas populares do Xamarin está disponível para ajudar a encontrar alternativas
para componentes que não estão disponíveis como pacotes NuGet.

Removendo referências de componente manualmente


A versão 15,6 do Visual Studio e a versão 7,4 do Visual Studio para Mac não oferecem mais suporte a
componentes em seu projeto.
Visual Studio
Visual Studio para Mac
Se você carregar um projeto no Visual Studio, a caixa de diálogo a seguir será exibida, explicando que você deve
remover manualmente todos os componentes do seu projeto:

Para remover um componente do seu projeto:


1. Abra o arquivo .csproj . Para fazer isso, clique com o botão direito do mouse no nome do projeto e
selecione descarregar projeto .
2. Clique com o botão direito do mouse novamente no projeto descarregado e selecione Editar {Your-
Project-Name}. csproj .
3. Localize todas as referências no arquivo para XamarinComponentReference . Ele deve ser semelhante ao
exemplo a seguir:
<ItemGroup>
<XamarinComponentReference Include="advancedcolorpicker">
<Version>2.0.1</Version>
<Visible>False</Visible>
</XamarinComponentReference>
<XamarinComponentReference Include="gunmetaltheme">
<Version>1.4.1</Version>
<Visible>False</Visible>
</XamarinComponentReference>
<XamarinComponentReference Include="signature-pad">
<Version>2.2.0</Version>
<Visible>False</Visible>
</XamarinComponentReference>
</ItemGroup>

4. Remova as referências para XamarinComponentReference e salve o arquivo. No exemplo acima, é seguro


remover todo o ItemGroup .
5. Depois que o arquivo tiver sido salvo, clique com o botão direito do mouse no nome do projeto e
selecione recarregar projeto .
6. Repita as etapas acima para cada projeto em sua solução.

WARNING
As instruções a seguir funcionam apenas com versões mais antigas do Visual Studio. O nó componentes não está mais
disponível nas versões atuais do Visual Studio 2017 ou Visual Studio para Mac.

As seções a seguir explicam como atualizar as soluções Xamarin existentes para alterar Referências de
componentes para pacotes NuGet.
Componentes que contêm pacotes NuGet
Componentes com substituições de NuGet
A maioria dos componentes se enquadra em uma das categorias acima. Se você estiver usando um componente
que não parece ter um pacote NuGet equivalente, leia a seção componentes sem um caminho de migração do
NuGet abaixo.

Componentes que contêm pacotes NuGet


Muitos componentes já contêm pacotes NuGet, e o caminho de migração é simplesmente para excluir a
referência de componente.
Você pode determinar se o componente já inclui um pacote NuGet clicando duas vezes no componente na
solução:
A guia pacotes listará todos os pacotes NuGet incluídos no componente:

Observe que a guia assemblies estará vazia:

Atualizando a solução
Para atualizar sua solução, exclua a entrada de componente da solução:

O pacote NuGet permanecerá listado no nó pacotes e seu aplicativo será compilado e executado como de
costume. No futuro, as atualizações para esse pacote serão executadas por meio do recurso de atualização do
NuGet :

Componentes com substituições de NuGet


Se a guia assemblies da página informações do componente contiver entradas, conforme mostrado abaixo,
você precisará localizar o pacote NuGet equivalente manualmente.
Observe que a guia pacotes provavelmente estará vazia:

Ele pode conter dependências do NuGet, mas eles podem ser ignorados.
Para confirmar se existe um pacote NuGet substituto, pesquise em NuGet.org, usando o nome do componente
ou, como alternativa, por autor.
Por exemplo, você pode encontrar o pacote SQLite-net-PCL popular procurando por:
sqlite-net-pcl – o nome do produto.
praeclarum – o perfil do autor.
Atualizando a solução
Depois de confirmar que o componente está disponível no NuGet, siga estas etapas:
Excluir o componente
Clique com o botão direito do mouse no componente na solução e escolha remover :

Isso excluirá o componente e todas as referências. Isso interromperá sua compilação, até que você adicione o
pacote NuGet equivalente para substituí-lo.
Adicionar o pacote NuGet
1. Clique com o botão direito do mouse no nó pacotes e escolha adicionar pacotes....
2. Procure a substituição do NuGet por nome ou autor:
3. Pressione Adicionar pacote .
O pacote NuGet será adicionado ao seu projeto, juntamente com quaisquer dependências. Isso deve corrigir a
compilação. Se a compilação continuar a falhar, investigue cada erro para ver se há diferenças de API entre o
componente e o pacote NuGet.

Componentes sem um caminho de migração do NuGet


Não se preocupe se você não encontrar imediatamente uma substituição para os componentes usados em seu
aplicativo. Os componentes existentes continuarão a funcionar no Visual Studio 15,5, e o nó componentes será
exibido em sua solução como de costume.
Futuras versões do Visual Studio, no entanto, não irão restaurar ou atualizar componentes. Isso significa que se
você abrir a solução em um novo computador, o componente não será baixado e instalado; e o autor não será
capaz de fornecer atualizações. Você deve planejar:
Extraia os assemblies do componente e faça referência a eles diretamente em seu projeto.
Entre em contato com o autor do componente e peça sobre os planos para migrar para o NuGet.
Investigue os pacotes do NuGet alternativos ou busque o código-fonte se o componente for de código-fonte
aberto.
Muitos fornecedores de componentes ainda estão trabalhando na migração para o NuGet, e outros (incluindo
produtos comercialmente disponíveis) podem estar investigando opções de entrega alternativas.

Links Relacionados
Lista de plug-ins e bibliotecas populares do Xamarin
Instalar e usar um pacote NuGet (Windows)
Incluindo um pacote NuGet (Mac)
Exemplos de plataforma cruzada
02/11/2020 • 2 minutes to read • Edit Online

Aplicativos de exemplo de plataforma cruzada do Xamarin e demonstrações de código para ajudar você a
começar a compilar aplicativos móveis com C# e Xamarin.
Todos os exemplos do Xamarin

Introdução

Todo
Este exemplo demonstra um aplicativo de Lista de tarefas em que os dados são armazenados e acessados em
um banco de dados local do SQLite, criado com o Xamarin.Forms.

My Shoppe
Aplicativo de demonstração para os vendedores acompanharem o desempenho de vendas, gerenciarem leads,
exibirem contatos, gerenciarem pedidos e consultarem o catálogo de produtos.
Xamarin CRM
Aplicativo de demonstração para os vendedores acompanharem o desempenho de vendas, gerenciarem leads,
exibirem contatos, gerenciarem pedidos e consultarem o catálogo de produtos.

Azure & Enterprise

Acquaint
Aplicativo de lista de contatos com uma tela de detalhes e edição. O código-fonte está disponível no
Xamarin.Forms e nas implementações nativas do Xamarin.
SmartHotel360
Demonstração na Connect 2017 de compilação de um pacote de aplicativos, incluindo o Xamarin e o Azure.

BikeSharing360
Demonstração na Connect 2016 de compilação de um pacote de aplicativos, incluindo o Xamarin e o Azure.

eShop
Diretrizes de arquitetura empresarial para a criação de aplicativos usando contêineres no Azure.
Todas as amostras
Para obter o conjunto completo de aplicativos de exemplo de plataforma cruzada do Xamarin e demonstrações
de código, consulte todos os exemplos do xamarin.