Partager via


Xamarin.Forms Webview

WebView est une vue permettant d’afficher du contenu web et HTML dans votre application :

Dans l’Explorateur d’applications

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 WebViewproprié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;

WebView affichant une chaîne HTML

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 WebViewfichier 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 :

Affichage de contenu local par WebView

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 , DependencyServicecommencez 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:///";
        }
    }
}

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’appel GoForward navigue vers la page suivante visitée.
  • GoBack() : si CanGoBack c’est vrai, l’appel GoBack 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 WebViewnavigateur, 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à !

Boutons de navigation WebView

É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’un WebNavigationResult membre d’énumération. Les valeurs valides sont Cancel, Failure, Success et Timeout.
  • 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) :

Capture d’écran montrant l’événement de navigation WebView lors du chargement.

Chargement terminé :

Capture d’écran montrant l’événement de navigation WebView après le chargement.

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 est appelée, l’événement ReloadReloadRequested 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 WebViewdes é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 WebView.EvaluateJavaScriptAsync méthode évalue le code JavaScript spécifié en tant qu’argument et retourne n’importe quel résultat sous la forme d’un string. Dans cet exemple, la factorial fonction JavaScript est appelée, qui retourne la factorielle du number résultat. Cette fonction JavaScript est définie dans le fichier HTML local que les WebView charges sont chargées 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 WebView.Cookies propriété. Lorsque l’envoi WebView d’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 utilisent UIWebView.

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 :

  1. Ouvrez les propriétés du projet iOS : cliquez avec le bouton droit sur votre projet iOS, puis choisissez Propriétés.
  2. Accédez à la section Build iOS : sélectionnez la section Build iOS.
  3. 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.
  4. 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/i Téléphone, 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 :

Définition de l’indicateur dans la section Build iOS

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.