Xamarin.Forms WebView
WebView
é uma visualização para exibir conteúdo da Web e HTML no seu aplicativo:
Sumário
WebView
Suporta os seguintes tipos de conteúdo:
- Sites HTML e CSS – O WebView tem suporte total para sites escritos usando HTML e CSS, incluindo suporte a JavaScript.
- Documentos – Como o WebView é implementado usando componentes nativos em cada plataforma, o WebView é capaz de mostrar documentos nos formatos suportados pela plataforma subjacente.
- Strings HTML – O WebView pode mostrar strings HTML da memória.
- Arquivos locais – o WebView pode apresentar qualquer um dos tipos de conteúdo acima incorporados no aplicativo.
Observação
WebView
no Windows não oferece suporte a Silverlight, Flash ou quaisquer controles ActiveX, mesmo que sejam suportados pelo Internet Explorer nessa plataforma.
Sites
Para exibir um site da Internet, defina a WebView
propriedade do Source
como uma URL de cadeia de caracteres:
var browser = new WebView
{
Source = "https://dotnet.microsoft.com/apps/xamarin"
};
Observação
Os URLs devem ser totalmente formados com o protocolo especificado (ou seja, deve ter "http://" ou "https://" anexado a ele).
iOS e ATS
Desde a versão 9, o iOS só permitirá que seu aplicativo se comunique com servidores que implementam a segurança de práticas recomendadas por padrão. Os valores devem ser definidos para Info.plist
permitir a comunicação com servidores não seguros.
Observação
Se o seu aplicativo exigir uma conexão com um site não seguro, você deve sempre inserir o domínio como uma exceção usando NSExceptionDomains
em vez de desativar completamente o ATS usando NSAllowsArbitraryLoads
. NSAllowsArbitraryLoads
só deve ser usado em situações extremas de emergência.
O seguinte demonstra como habilitar um domínio específico (neste caso, xamarin.com) para ignorar os requisitos do ATS:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>xamarin.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
...
</key>
É uma prática recomendada permitir que apenas alguns domínios ignorem o ATS, permitindo que você use sites confiáveis enquanto se beneficia da segurança adicional em domínios não confiáveis. O seguinte demonstra o método menos seguro de desabilitar o ATS para o aplicativo:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads </key>
<true/>
</dict>
...
</key>
Consulte Segurança de Transporte de Aplicativos para obter mais informações sobre esse novo recurso no iOS 9.
HTML Strings
Se você quiser apresentar uma string de HTML definida dinamicamente no código, precisará criar uma instância de HtmlWebViewSource
:
var browser = new WebView();
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = @"<html><body>
<h1>Xamarin.Forms</h1>
<p>Welcome to WebView.</p>
</body></html>";
browser.Source = htmlSource;
No código acima, @
é usado para marcar o HTML como um literal de cadeia de caracteres literal, o que significa que a maioria dos caracteres de escape são ignorados.
Observação
Pode ser necessário definir as WidthRequest
propriedades e HeightRequest
do WebView
para ver o conteúdo HTML, dependendo do layout do qual é WebView
filho. Por exemplo, isso é necessário em um StackLayout
.
Conteúdo HTML local
O WebView pode exibir conteúdo de HTML, CSS e JavaScript incorporados ao aplicativo. Por exemplo:
<html>
<head>
<title>Xamarin Forms</title>
</head>
<body>
<h1>Xamarin.Forms</h1>
<p>This is an iOS web page.</p>
<img src="XamarinLogo.png" />
</body>
</html>
CSS:
html,body {
margin:0;
padding:10;
}
body,p,h1 {
font-family: Chalkduster;
}
Observe que as fontes especificadas no CSS acima precisarão ser personalizadas para cada plataforma, pois nem todas as plataformas têm as mesmas fontes.
Para exibir conteúdo local usando um WebView
, você precisará abrir o arquivo HTML como qualquer outro e, em seguida, carregar o conteúdo como uma cadeia de caracteres na Html
propriedade de um HtmlWebViewSource
. Para obter mais informações sobre como abrir arquivos, consulte Trabalhando com arquivos.
As capturas de tela a seguir mostram o resultado da exibição de conteúdo local em cada plataforma:
Embora a primeira página tenha sido carregada, o WebView
não tem conhecimento de onde veio o HTML. Isso é um problema ao lidar com páginas que fazem referência a recursos locais. Exemplos de quando isso pode acontecer incluem quando as páginas locais são vinculadas umas às outras, uma página usa um arquivo JavaScript separado ou uma página é vinculada a uma folha de estilo CSS.
Para resolver isso, você precisa informar onde WebView
encontrar arquivos no sistema de arquivos. Faça isso definindo a BaseUrl
HtmlWebViewSource
propriedade no usado pelo WebView
.
Como o sistema de arquivos em cada um dos sistemas operacionais é diferente, você precisa determinar essa URL em cada plataforma. Xamarin.Forms Expõe o DependencyService
para resolver dependências em tempo de execução em cada plataforma.
Para usar o , primeiro defina uma interface que possa ser implementada DependencyService
em cada plataforma:
public interface IBaseUrl { string Get(); }
Observe que, até que a interface seja implementada em cada plataforma, o aplicativo não será executado. No projeto comum, lembre-se de definir o uso do BaseUrl
DependencyService
:
var source = new HtmlWebViewSource();
source.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
As implementações da interface para cada plataforma devem ser fornecidas.
iOS
No iOS, o conteúdo da Web deve estar localizado no diretório raiz do projeto ou no diretório Resources com a ação de build BundleResource, conforme demonstrado abaixo:
O BaseUrl
deve ser definido para o caminho do pacote principal:
[assembly: Dependency (typeof (BaseUrl_iOS))]
namespace WorkingWithWebview.iOS
{
public class BaseUrl_iOS : IBaseUrl
{
public string Get()
{
return NSBundle.MainBundle.BundlePath;
}
}
}
Android
No Android, coloque HTML, CSS e imagens na pasta Assets com a ação de build AndroidAsset , conforme demonstrado abaixo:
No Android, o BaseUrl
deve ser definido como "file:///android_asset/"
:
[assembly: Dependency (typeof(BaseUrl_Android))]
namespace WorkingWithWebview.Android
{
public class BaseUrl_Android : IBaseUrl
{
public string Get()
{
return "file:///android_asset/";
}
}
}
No Android, os arquivos na pasta Ativos também podem ser acessados por meio do contexto atual do MainActivity.Instance
Android, que é exposto pela propriedade:
var assetManager = MainActivity.Instance.Assets;
using (var streamReader = new StreamReader (assetManager.Open ("local.html")))
{
var html = streamReader.ReadToEnd ();
}
Plataforma Universal do Windows
Em projetos UWP (Plataforma Universal do Windows), coloque HTML, CSS e imagens na raiz do projeto com a ação de build definida como Content.
O BaseUrl
deve ser definido como "ms-appx-web:///"
:
[assembly: Dependency(typeof(BaseUrl))]
namespace WorkingWithWebview.UWP
{
public class BaseUrl : IBaseUrl
{
public string Get()
{
return "ms-appx-web:///";
}
}
}
Navegação
O WebView oferece suporte à navegação por meio de vários métodos e propriedades que ele disponibiliza:
- GoForward() – se
CanGoForward
for verdadeiro, a chamadaGoForward
navega para a próxima página visitada. - GoBack() – se
CanGoBack
for verdadeiro, a chamadaGoBack
navegará até a última página visitada. - CanGoBack –
true
se houver páginas para navegar de volta,false
se o navegador estiver no URL inicial. - CanGoForward –
true
se o usuário navegou para trás e pode avançar para uma página que já foi visitada.
Dentro das páginas, WebView
não suporta gestos multitoque. É importante garantir que o conteúdo seja otimizado para dispositivos móveis e apareça sem a necessidade de zoom.
É comum que os aplicativos mostrem um link em um WebView
, em vez do navegador do dispositivo. Nessas situações, é útil permitir a navegação normal, mas quando o usuário retorna enquanto está no link inicial, o aplicativo deve retornar ao modo de exibição normal do aplicativo.
Use os métodos e propriedades de navegação internos para habilitar esse cenário.
Comece criando a página para a visualização do navegador:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebViewSample.InAppBrowserXaml"
Title="Browser">
<StackLayout Margin="20">
<StackLayout Orientation="Horizontal">
<Button Text="Back" HorizontalOptions="StartAndExpand" Clicked="OnBackButtonClicked" />
<Button Text="Forward" HorizontalOptions="EndAndExpand" Clicked="OnForwardButtonClicked" />
</StackLayout>
<!-- WebView needs to be given height and width request within layouts to render. -->
<WebView x:Name="webView" WidthRequest="1000" HeightRequest="1000" />
</StackLayout>
</ContentPage>
No code-behind:
public partial class InAppBrowserXaml : ContentPage
{
public InAppBrowserXaml(string URL)
{
InitializeComponent();
webView.Source = URL;
}
async void OnBackButtonClicked(object sender, EventArgs e)
{
if (webView.CanGoBack)
{
webView.GoBack();
}
else
{
await Navigation.PopAsync();
}
}
void OnForwardButtonClicked(object sender, EventArgs e)
{
if (webView.CanGoForward)
{
webView.GoForward();
}
}
}
É isso!
Eventos
O WebView gera os seguintes eventos para ajudá-lo a responder a alterações no estado:
Navigating
– gerado quando o WebView começa a carregar uma nova página.Navigated
– evento gerado quando a página é carregada e a navegação é interrompida.ReloadRequested
– evento gerado quando uma solicitação é feita para recarregar o conteúdo atual.
O WebNavigatingEventArgs
objeto que acompanha o Navigating
evento tem quatro propriedades:
Cancel
– indica se deve ou não cancelar a navegação.NavigationEvent
– o evento de navegação que foi gerado.Source
– o elemento que executou a navegação.Url
– o destino de navegação.
O WebNavigatedEventArgs
objeto que acompanha o Navigated
evento tem quatro propriedades:
NavigationEvent
– o evento de navegação que foi gerado.Result
– descreve o resultado da navegação, usando umWebNavigationResult
membro de enumeração. Os valores válidos sãoCancel
,Failure
,Success
eTimeout
.Source
– o elemento que executou a navegação.Url
– o destino de navegação.
Se você prevê o uso de páginas da Web que demoram muito para carregar, considere usar os Navigating
eventos and Navigated
para implementar um indicador de status. Por exemplo:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebViewSample.LoadingLabelXaml"
Title="Loading Demo">
<StackLayout>
<!--Loading label should not render by default.-->
<Label x:Name="labelLoading" Text="Loading..." IsVisible="false" />
<WebView HeightRequest="1000" WidthRequest="1000" Source="https://dotnet.microsoft.com/apps/xamarin" Navigated="webviewNavigated" Navigating="webviewNavigating" />
</StackLayout>
</ContentPage>
Os dois manipuladores de eventos:
void webviewNavigating(object sender, WebNavigatingEventArgs e)
{
labelLoading.IsVisible = true;
}
void webviewNavigated(object sender, WebNavigatedEventArgs e)
{
labelLoading.IsVisible = false;
}
Isso resulta na seguinte saída (carregamento):
Carregamento finalizado:
Recarregando conteúdo
WebView
tem um Reload
método que pode ser usado para recarregar o conteúdo atual:
var webView = new WebView();
...
webView.Reload();
Quando o método Reload
é chamado, o evento ReloadRequested
é acionado, indicando que uma solicitação foi feita para recarregar o conteúdo atual.
Desempenho
Navegadores populares adotam tecnologias como renderização acelerada por hardware e compilação JavaScript. Antes da Xamarin.Forms versão 4.4, o Xamarin.FormsWebView
foi implementado no iOS pela UIWebView
classe. No entanto, muitas dessas tecnologias não estavam disponíveis nesta implementação. Portanto, desde Xamarin.Forms a WkWebView
versão 4.4, o Xamarin.FormsWebView
é implementado no iOS pela classe, que suporta navegação mais rápida.
Observação
No iOS, o WkWebViewRenderer
tem uma sobrecarga de construtor que aceita um WkWebViewConfiguration
argumento. Isso permite que o renderizador seja configurado na criação.
Um aplicativo pode voltar a usar a classe iOS UIWebView
para implementar o Xamarin.FormsWebView
, por motivos de compatibilidade. Isso pode ser feito adicionando o seguinte código ao arquivo AssemblyInfo.cs no projeto da plataforma iOS para o aplicativo:
// Opt-in to using UIWebView instead of WkWebView.
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(Xamarin.Forms.Platform.iOS.WebViewRenderer))]
Observação
Na Xamarin.Forms versão 5.0, a WebViewRenderer
classe foi removida. Portanto, Xamarin.Forms 5.0 não contém uma referência ao UIWebView
controle.
WebView
no Android, por padrão, é quase tão rápido quanto o navegador embutido.
O UWP WebView usa o mecanismo de renderização do Microsoft Edge. Os dispositivos desktop e tablet devem ter o mesmo desempenho que usar o próprio navegador Edge.
Permissões
Para WebView
funcionar, você deve certificar-se de que as permissões estejam definidas para cada plataforma. Observe que, em algumas plataformas, WebView
funcionará no modo de depuração, mas não quando criado para lançamento. Isso ocorre porque algumas permissões, como aquelas para acesso à Internet no Android, são definidas por padrão pelo Visual Studio para Mac quando no modo de depuração.
- UWP – requer o recurso de Internet (Cliente e Servidor) ao exibir conteúdo de rede.
- Android – requer
INTERNET
apenas ao exibir conteúdo da rede. O conteúdo local não requer permissões especiais. - iOS – não requer permissões especiais.
Layout
Ao contrário da maioria das outras Xamarin.Forms exibições, WebView
requer isso HeightRequest
e WidthRequest
são especificadas quando contidas em StackLayout ou RelativeLayout. Se você não especificar essas propriedades, o não WebView
será renderizado.
Os exemplos a seguir demonstram layouts que resultam em trabalho, renderizando WebView
s:
StackLayout com WidthRequest e HeightRequest:
<StackLayout>
<Label Text="test" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
RelativeLayout com WidthRequest & HeightRequest:
<RelativeLayout>
<Label Text="test"
RelativeLayout.XConstraint= "{ConstraintExpression
Type=Constant, Constant=10}"
RelativeLayout.YConstraint= "{ConstraintExpression
Type=Constant, Constant=20}" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
RelativeLayout.XConstraint="{ConstraintExpression Type=Constant,
Constant=10}"
RelativeLayout.YConstraint="{ConstraintExpression Type=Constant,
Constant=50}"
WidthRequest="1000" HeightRequest="1000" />
</RelativeLayout>
AbsoluteLayout sem WidthRequest & HeightRequest:
<AbsoluteLayout>
<Label Text="test" AbsoluteLayout.LayoutBounds="0,0,100,100" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
AbsoluteLayout.LayoutBounds="0,150,500,500" />
</AbsoluteLayout>
Grade sem WidthRequest & HeightRequest. Grid é um dos poucos layouts que não requer a especificação de alturas e larguras solicitadas.:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="test" Grid.Row="0" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin" Grid.Row="1" />
</Grid>
Invocando JavaScript
WebView
inclui a capacidade de invocar uma função JavaScript do C# e retornar qualquer resultado para o código C# de chamada. Isso é feito com o método WebView.EvaluateJavaScriptAsync
:
var numberEntry = new Entry { Text = "5" };
var resultLabel = new Label();
var webView = new WebView();
...
int number = int.Parse(numberEntry.Text);
string result = await webView.EvaluateJavaScriptAsync($"factorial({number})");
resultLabel.Text = $"Factorial of {number} is {result}.";
O método WebView.EvaluateJavaScriptAsync
avalia o JavaScript especificado como o argumento e retorna qualquer resultado como um string
. Neste exemplo, a função JavaScript factorial
é invocada, que retorna o fatorial de number
como resultado. Essa função JavaScript é definida no arquivo HTML local que o WebView
carrega e é mostrada no seguinte exemplo:
<html>
<body>
<script type="text/javascript">
function factorial(num) {
if (num === 0 || num === 1)
return 1;
for (var i = num - 1; i >= 1; i--) {
num *= i;
}
return num;
}
</script>
</body>
</html>
Cookies
Os cookies podem ser definidos em um WebView
, que são enviados com a solicitação da web para o URL especificado. Isso é feito adicionando Cookie
objetos a um CookieContainer
, que é então definido como o valor da WebView.Cookies
propriedade associável. O código a seguir mostra um exemplo disso:
using System.Net;
using Xamarin.Forms;
// ...
CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://dotnet.microsoft.com/apps/xamarin", UriKind.RelativeOrAbsolute);
Cookie cookie = new Cookie
{
Name = "XamarinCookie",
Expires = DateTime.Now.AddDays(1),
Value = "My cookie",
Domain = uri.Host,
Path = "/"
};
cookieContainer.Add(uri, cookie);
webView.Cookies = cookieContainer;
webView.Source = new UrlWebViewSource { Url = uri.ToString() };
Neste exemplo, um Cookie
é adicionado ao objeto CookieContainer
, que é definido como o valor da propriedade WebView.Cookies
. Quando o WebView
envia uma solicitação da Web para a URL especificada, o cookie é enviado com a solicitação.
Substituição do UIWebView e rejeição da App Store (ITMS-90809)
A partir de abril de 2020, a Apple rejeitará aplicativos que ainda usam a API obsoleta UIWebView
. Embora Xamarin.Forms tenha mudado para WKWebView
como padrão, ainda há uma referência ao SDK mais antigo nos Xamarin.Forms binários. O comportamento atual do vinculador do iOS não remove isso e, como resultado, a API obsoleta UIWebView
ainda parecerá ser referenciada do seu aplicativo quando você enviar para a App Store.
Importante
Na Xamarin.Forms versão 5.0, a WebViewRenderer
classe foi removida. Portanto, Xamarin.Forms 5.0 não contém uma referência ao UIWebView
controle.
Uma versão prévia do vinculador está disponível para corrigir esse problema. Para habilitar a versão prévia, você precisará fornecer um argumento --optimize=experimental-xforms-product-type
adicional para o vinculador.
Os pré-requisitos para que isso funcione são:
- Xamarin.Forms 4.5 ou superior. Xamarin.Forms 4.6 ou superior é necessário se o aplicativo usar o Material Visual.
- Xamarin.iOS 13.10.0.17 ou superior. Verifique sua versão do Xamarin.iOS no Visual Studio. Esta versão do Xamarin.iOS está incluída no Visual Studio para Mac 8.4.1 e no Visual Studio 16.4.3.
- Remova as referências a
UIWebView
. Seu código não deve ter referênciasUIWebView
ou classes que usemUIWebView
.
Para obter mais informações sobre como detectar e remover UIWebView
referências, consulte Substituição de UIWebView.
Configurar o vinculador
Siga estas etapas para que o vinculador remova UIWebView
referências:
- Abra as propriedades do projeto iOS – Clique com o botão direito do mouse no projeto iOS e escolha Propriedades.
- Navegue até a seção iOS Build – Selecione a seção iOS Build .
- Atualize os argumentos adicionais do mtouch – nos argumentos adicionais do mtouch, adicione esse sinalizador
--optimize=experimental-xforms-product-type
(além de qualquer valor que já possa estar lá). Observação: esse sinalizador funciona em conjunto com o Comportamento do Vinculador definido como Somente SDK ou Vincular Tudo. Se, por qualquer motivo, você vir erros ao definir o Comportamento do Vinculador como Todos, isso provavelmente é um problema no código do aplicativo ou em uma biblioteca de terceiros que não é segura para o vinculador. Para obter mais informações sobre o vinculador, consulte Vinculando aplicativos Xamarin.iOS. - Atualizar todas as configurações de compilação – Use as listas Configuração e Plataforma na parte superior da janela para atualizar todas as configurações de compilação. A configuração mais importante a ser atualizada é a configuração Release/iPhone , já que normalmente é usada para criar compilações para envio na App Store.
Você pode ver a janela com o novo sinalizador nesta captura de tela:
Agora, quando você cria uma nova compilação (versão) e a envia para a App Store, não deve haver avisos sobre a API obsoleta.