Xamarin.Forms WebView
WebView
est une vue permettant d’afficher du contenu web et HTML dans votre application :
Contenu
WebView
prend en charge les types de contenu suivants :
- Sites web HTML &CSS : WebView prend entièrement en charge les sites web écrits à l’aide de HTML &CSS, y compris la prise en charge de JavaScript.
- Documents : Étant donné que WebView est implémenté à l’aide de composants natifs sur chaque plateforme, WebView est capable d’afficher des documents dans les formats pris en charge par la plateforme sous-jacente.
- Chaînes HTML : WebView peut afficher des chaînes HTML à partir de la mémoire.
- Fichiers locaux : WebView peut présenter l’un des types de contenu ci-dessus incorporés dans l’application.
Remarque
WebView
sur Windows ne prend pas en charge Silverlight, Flash ou aucun contrôle ActiveX, même s’ils sont pris en charge par Internet Explorer sur cette plateforme.
Sites web
Pour afficher un site web à partir d’Internet, définissez la WebView
propriété sur Source
une URL de chaîne :
var browser = new WebView
{
Source = "https://dotnet.microsoft.com/apps/xamarin"
};
Remarque
Les URL doivent être entièrement formées avec le protocole spécifié (c’est-à-dire qu’elles doivent avoir « http:// » ou « https:// » ajoutées à celle-ci).
iOS et ATS
Depuis la version 9, iOS autorise uniquement votre application à communiquer avec les serveurs qui implémentent la sécurité recommandée par défaut. Les valeurs doivent être définies pour Info.plist
activer la communication avec des serveurs non sécurisés.
Remarque
Si votre application nécessite une connexion à un site web non sécurisé, vous devez toujours entrer le domaine en tant qu’exception à l’aide NSExceptionDomains
d’ATS au lieu de désactiver complètement ATS à l’aide NSAllowsArbitraryLoads
. NSAllowsArbitraryLoads
ne doit être utilisé que dans des situations d’urgence extrêmes.
L’exemple suivant montre comment activer un domaine spécifique (dans ce cas xamarin.com) pour contourner les exigences 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>
Il est recommandé d’autoriser uniquement certains domaines à contourner ATS, ce qui vous permet d’utiliser des sites approuvés tout en bénéficiant de la sécurité supplémentaire sur les domaines non approuvés. L’exemple suivant illustre la méthode moins sécurisée de désactivation d’ATS pour l’application :
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads </key>
<true/>
</dict>
...
</key>
Pour plus d’informations sur cette nouvelle fonctionnalité dans iOS 9, consultez App Transport Security .
Chaînes HTML
Si vous souhaitez présenter une chaîne de code HTML définie dynamiquement dans le code, vous devez créer une instance 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;
Dans le code ci-dessus, @
est utilisé pour marquer le code HTML comme littéral de chaîne détaillée, ce qui signifie que la plupart des caractères d’échappement sont ignorés.
Remarque
Il peut être nécessaire de définir les propriétés et HeightRequest
les WidthRequest
propriétés de l’affichage WebView
du contenu HTML, en fonction de la disposition dont il WebView
est un enfant. Par exemple, cela est requis dans un StackLayout
.
Contenu HTML local
WebView peut afficher du contenu à partir de HTML, CSS et JavaScript incorporés dans l’application. Par exemple :
<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;
}
Notez que les polices spécifiées dans le CSS ci-dessus doivent être personnalisées pour chaque plateforme, car toutes les plateformes n’ont pas les mêmes polices.
Pour afficher le contenu local à l’aide d’un WebView
fichier HTML, vous devez ouvrir le fichier HTML comme tout autre, puis charger le contenu sous forme de chaîne dans la Html
propriété d’un HtmlWebViewSource
. Pour plus d’informations sur l’ouverture de fichiers, consultez Utilisation des fichiers.
Les captures d’écran suivantes montrent le résultat de l’affichage du contenu local sur chaque plateforme :
Bien que la première page ait été chargée, elle WebView
n’a aucune connaissance de l’emplacement du code HTML. Il s’agit d’un problème lors de la gestion des pages qui font référence aux ressources locales. Par exemple, lorsque cela peut se produire, notamment lorsque des pages locales sont liées les unes aux autres, une page utilise un fichier JavaScript distinct ou un lien de page vers une feuille de style CSS.
Pour résoudre ce problème, vous devez indiquer WebView
où rechercher des fichiers sur le système de fichiers. Pour ce faire, définissez la BaseUrl
propriété sur l’objet HtmlWebViewSource
utilisé par le WebView
.
Étant donné que le système de fichiers sur chacun des systèmes d’exploitation est différent, vous devez déterminer cette URL sur chaque plateforme. Xamarin.Forms expose la DependencyService
résolution des dépendances au moment de l’exécution sur chaque plateforme.
Pour utiliser , DependencyService
commencez par définir une interface qui peut être implémentée sur chaque plateforme :
public interface IBaseUrl { string Get(); }
Notez que tant que l’interface n’est pas implémentée sur chaque plateforme, l’application ne s’exécute pas. Dans le projet commun, assurez-vous que vous n’oubliez pas de définir l’utilisation de BaseUrl
:DependencyService
var source = new HtmlWebViewSource();
source.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
Les implémentations de l’interface pour chaque plateforme doivent ensuite être fournies.
iOS
Sur iOS, le contenu web doit se trouver dans le répertoire racine ou le répertoire Ressources du projet avec l’action de génération BundleResource, comme illustré ci-dessous :
La BaseUrl
valeur doit être définie sur le chemin d’accès de l’offre groupée principale :
[assembly: Dependency (typeof (BaseUrl_iOS))]
namespace WorkingWithWebview.iOS
{
public class BaseUrl_iOS : IBaseUrl
{
public string Get()
{
return NSBundle.MainBundle.BundlePath;
}
}
}
Android
Sur Android, placez HTML, CSS et images dans le dossier Assets avec l’action de génération AndroidAsset , comme illustré ci-dessous :
Sur Android, la BaseUrl
valeur doit être définie sur "file:///android_asset/"
:
[assembly: Dependency (typeof(BaseUrl_Android))]
namespace WorkingWithWebview.Android
{
public class BaseUrl_Android : IBaseUrl
{
public string Get()
{
return "file:///android_asset/";
}
}
}
Sur Android, les fichiers du dossier Assets sont également accessibles via le contexte Android actuel, qui est exposé par la MainActivity.Instance
propriété :
var assetManager = MainActivity.Instance.Assets;
using (var streamReader = new StreamReader (assetManager.Open ("local.html")))
{
var html = streamReader.ReadToEnd ();
}
Plateforme Windows universelle
Sur les projets plateforme Windows universelle (UWP), placez HTML, CSS et images dans la racine du projet avec l’action de génération définie sur Contenu.
La BaseUrl
valeur doit être définie sur "ms-appx-web:///"
:
[assembly: Dependency(typeof(BaseUrl))]
namespace WorkingWithWebview.UWP
{
public class BaseUrl : IBaseUrl
{
public string Get()
{
return "ms-appx-web:///";
}
}
}
Navigation
WebView prend en charge la navigation via plusieurs méthodes et propriétés qu’il met à disposition :
- GoForward() : s’il
CanGoForward
est vrai, l’appelGoForward
navigue vers la page suivante visitée. - GoBack() : si
CanGoBack
c’est vrai, l’appelGoBack
accède à la dernière page visitée. - CanGoBack :
true
s’il existe des pages vers lesquelles revenir,false
si le navigateur se trouve à l’URL de départ. - CanGoForward :
true
si l’utilisateur a navigué vers l’arrière et peut passer à une page déjà visitée.
Dans les pages, WebView
ne prend pas en charge les mouvements tactiles multiples. Il est important de s’assurer que le contenu est optimisé pour les appareils mobiles et s’affiche sans avoir besoin de zoomer.
Il est courant que les applications affichent un lien au sein d’un WebView
navigateur, plutôt que dans le navigateur de l’appareil. Dans ces situations, il est utile d’autoriser la navigation normale, mais lorsque l’utilisateur accède au lien de départ, l’application doit revenir à l’affichage normal de l’application.
Utilisez les méthodes et propriétés de navigation intégrées pour activer ce scénario.
Commencez par créer la page pour l’affichage du navigateur :
<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>
Dans le 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();
}
}
}
Et voilà !
Événements
WebView déclenche les événements suivants pour vous aider à répondre aux modifications apportées à l’état :
Navigating
: événement déclenché lorsque le WebView commence à charger une nouvelle page.Navigated
: événement déclenché lorsque la page est chargée et que la navigation s’est arrêtée.ReloadRequested
: événement déclenché lorsqu’une demande est effectuée pour recharger le contenu actuel.
L’objet WebNavigatingEventArgs
qui accompagne l’événement Navigating
a quatre propriétés :
Cancel
: indique si la navigation doit être annulée ou non.NavigationEvent
: événement de navigation déclenché.Source
: élément qui a effectué la navigation.Url
: destination de navigation.
L’objet WebNavigatedEventArgs
qui accompagne l’événement Navigated
a quatre propriétés :
NavigationEvent
: événement de navigation déclenché.Result
: décrit le résultat de la navigation à l’aide d’unWebNavigationResult
membre d’énumération. Les valeurs valides sontCancel
,Failure
,Success
etTimeout
.Source
: élément qui a effectué la navigation.Url
: destination de navigation.
Si vous prévoyez d’utiliser des pages web qui prennent beaucoup de temps à charger, envisagez d’utiliser les événements et Navigated
les Navigating
événements pour implémenter un indicateur d’état. Par exemple :
<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>
Les deux gestionnaires d’événements :
void webviewNavigating(object sender, WebNavigatingEventArgs e)
{
labelLoading.IsVisible = true;
}
void webviewNavigated(object sender, WebNavigatedEventArgs e)
{
labelLoading.IsVisible = false;
}
Cela entraîne la sortie suivante (chargement) :
Chargement terminé :
Rechargement du contenu
WebView
a une Reload
méthode qui peut être utilisée pour recharger le contenu actuel :
var webView = new WebView();
...
webView.Reload();
Lorsque la méthode Reload
est appelée, l’événement ReloadRequested
est déclenché, indiquant qu’une demande a été effectuée pour recharger le contenu actuel.
Performances
Les navigateurs web populaires adoptent des technologies telles que le rendu accéléré matériel et la compilation JavaScript. Xamarin.Forms Avant la version 4.4, l’application Xamarin.FormsWebView
a été implémentée sur iOS par la UIWebView
classe. Toutefois, la plupart de ces technologies n’étaient pas disponibles dans cette implémentation. Par conséquent, étant donné Xamarin.Forms que la version 4.4, elle Xamarin.FormsWebView
est implémentée sur iOS par la WkWebView
classe, qui prend en charge la navigation plus rapide.
Remarque
Sur iOS, le WkWebViewRenderer
constructeur a une surcharge qui accepte un WkWebViewConfiguration
argument. Cela permet au renderer d’être configuré lors de la création.
Une application peut revenir à l’utilisation de la classe iOS UIWebView
pour implémenter le Xamarin.FormsWebView
, pour des raisons de compatibilité. Pour ce faire, ajoutez le code suivant au fichier AssemblyInfo.cs dans le projet de plateforme iOS pour l’application :
// Opt-in to using UIWebView instead of WkWebView.
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(Xamarin.Forms.Platform.iOS.WebViewRenderer))]
Remarque
Dans Xamarin.Forms la version 5.0, la WebViewRenderer
classe a été supprimée. Par conséquent, Xamarin.Forms la version 5.0 ne contient pas de référence au UIWebView
contrôle.
WebView
sur Android par défaut est aussi rapide que le navigateur intégré.
UWP WebView utilise le moteur de rendu Microsoft Edge. Les appareils de bureau et de tablette doivent voir les mêmes performances que l’utilisation du navigateur Edge lui-même.
autorisations
Pour WebView
fonctionner, vous devez vous assurer que les autorisations sont définies pour chaque plateforme. Notez que sur certaines plateformes, WebView
fonctionne en mode débogage, mais pas en cas de génération pour la version. Cela est dû au fait que certaines autorisations, comme celles pour l’accès à Internet sur Android, sont définies par défaut par Visual Studio pour Mac en mode débogage.
- UWP : nécessite la fonctionnalité Internet (client &serveur) lors de l’affichage du contenu réseau.
- Android : nécessite
INTERNET
uniquement l’affichage du contenu à partir du réseau. Le contenu local ne nécessite aucune autorisation spéciale. - iOS : ne nécessite aucune autorisation spéciale.
Disposition
Contrairement à la plupart des autres Xamarin.Forms affichages, WebView
requiert cela HeightRequest
et WidthRequest
sont spécifiés lorsqu’ils sont contenus dans StackLayout ou RelativeLayout. Si vous ne spécifiez pas ces propriétés, le WebView
rendu n’est pas effectué.
Les exemples suivants illustrent les dispositions qui entraînent le fonctionnement, le rendu WebView
des éléments suivants :
StackLayout avec WidthRequest &HeightRequest :
<StackLayout>
<Label Text="test" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
RelativeLayout avec 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 sans 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>
Grille sans WidthRequest &HeightRequest. La grille est l’une des rares dispositions qui ne nécessitent pas de spécification de hauteurs et de largeurs demandées.
<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>
Appel de JavaScript
WebView
inclut la possibilité d’appeler une fonction JavaScript à partir de C#, et de renvoyer tout résultat au code C# appelant. Cette opération est effectuée avec la méthode 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}.";
La méthode WebView.EvaluateJavaScriptAsync
évalue le JavaScript spécifié en tant qu’argument et retourne les résultats sous la forme de string
. Dans cet exemple, la fonction factorial
JavaScript est appelée et retourne la factorielle de number
comme résultat. Cette fonction JavaScript est définie dans le fichier HTML local chargé par WebView
et est illustrée dans l’exemple suivant :
<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
Les cookies peuvent être définis sur un WebView
, qui sont ensuite envoyés avec la requête web à l’URL spécifiée. Pour ce faire, ajoutez Cookie
des objets à un CookieContainer
, qui est ensuite défini comme valeur de la WebView.Cookies
propriété pouvant être liée. Le code suivant en est un exemple :
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() };
Dans cet exemple, un seul Cookie
est ajouté à l’objet CookieContainer
, qui est ensuite défini comme valeur de la propriété WebView.Cookies
. Quand WebView
envoie une requête web à l’URL spécifiée, le cookie est envoyé avec la demande.
Dépréciation UIWebView et rejet de l’App Store (ITMS-90809)
À compter d’avril 2020, Apple rejette les applications qui utilisent toujours l’API déconseillée UIWebView
. Bien qu’il Xamarin.Forms ait basculé comme WKWebView
valeur par défaut, il existe toujours une référence au sdk plus ancien dans les Xamarin.Forms fichiers binaires. Le comportement actuel de l’éditeur de liens iOS ne supprime pas cette opération. Par conséquent, l’API déconseillée UIWebView
semble toujours être référencée à partir de votre application lorsque vous envoyez à l’App Store.
Important
Dans Xamarin.Forms la version 5.0, la WebViewRenderer
classe a été supprimée. Par conséquent, Xamarin.Forms la version 5.0 ne contient pas de référence au UIWebView
contrôle.
Une préversion de l’éditeur de liens est disponible pour résoudre ce problème. Pour activer la préversion, vous devez fournir un argument --optimize=experimental-xforms-product-type
supplémentaire à l’éditeur de liens.
Les conditions préalables à ce fonctionnement sont les suivantes :
- Xamarin.Forms 4,5 ou version ultérieure. Xamarin.Forms La version 4.6 ou ultérieure est requise si votre application utilise le visuel matériel.
- Xamarin.iOS 13.10.0.17 ou version ultérieure. Vérifiez votre version de Xamarin.iOS dans Visual Studio. Cette version de Xamarin.iOS est incluse dans Visual Studio pour Mac 8.4.1 et Visual Studio 16.4.3.
- Supprimez les références à
UIWebView
. Votre code ne doit pas avoir de références àUIWebView
des classes qui utilisentUIWebView
.
Pour plus d’informations sur la détection et la suppression de UIWebView
références, consultez dépréciation UIWebView.
Configurer l’éditeur de liens
Procédez comme suit pour que l’éditeur de liens supprime les UIWebView
références :
- Ouvrez les propriétés du projet iOS : cliquez avec le bouton droit sur votre projet iOS, puis choisissez Propriétés.
- Accédez à la section Build iOS : sélectionnez la section Build iOS.
- Mettez à jour les arguments mtouch supplémentaires : dans les arguments mtouch supplémentaires, ajoutez cet indicateur
--optimize=experimental-xforms-product-type
(en plus de toute valeur qui peut déjà être présente). Remarque : cet indicateur fonctionne conjointement avec le comportement de l’éditeur de liens défini sur le KIT DE développement logiciel (SDK) uniquement ou Link All. Si, pour une raison quelconque, vous voyez des erreurs lors de la définition du comportement de l’éditeur de liens sur Tout, il s’agit probablement d’un problème au sein du code de l’application ou d’une bibliothèque tierce qui n’est pas sécurisée par l’éditeur de liens. Pour plus d’informations sur l’éditeur de liens, consultez Liaison d’applications Xamarin.iOS. - Mettez à jour toutes les configurations de build : utilisez les listes configuration et plateforme en haut de la fenêtre pour mettre à jour toutes les configurations de build. La configuration la plus importante à mettre à jour est la configuration Release/iPhone , car elle est généralement utilisée pour créer des builds pour la soumission d’App Store.
Vous pouvez voir la fenêtre avec le nouvel indicateur en place dans cette capture d’écran :
Maintenant, lorsque vous créez une build (version) et que vous la soumettez à l’App Store, il ne doit y avoir aucun avertissement concernant l’API déconseillée.