WebView

.NET マルチプラットフォーム アプリ UI (.NET MAUI) WebView は、リモート Web ページ、ローカル HTML ファイル、HTML 文字列をアプリに表示します。 WebView に表示されたコンテンツには、カスケード スタイル シート (CSS) と JavaScript のサポートが含まれています。 既定では、.NET MAUI プロジェクトには、WebView がリモート Web ページを表示するために必要なプラットフォームのアクセス許可が含まれています。

WebView には、次のプロパティが定義されています。

  • CookieContainer 型の Cookies は、Cookie のコレクションのストレージを提供します。
  • bool 型の CanGoBack は、ユーザーが前のページに移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • bool 型の CanGoForward は、ユーザーが前方に移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • WebViewSource 型の Source は、WebView が表示する場所を表します。
  • string 型の UserAgent は、ユーザー エージェントを表します。 既定値は、基になるプラットフォーム ブラウザーのユーザー エージェントか、判断できない場合は null です。

これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。

Source プロパティは、HtmlWebViewSource オブジェクトまたは UrlWebViewSource オブジェクトに設定できます。この両方の派生元は WebViewSource です。 UrlWebViewSource は URL で指定された Web ページの読み込みに使用され、HtmlWebViewSource オブジェクトはローカル HTML ファイルまたはローカル HTML の読み込みに使用されます。

WebView は、ページ ナビゲーションの開始時に発生する Navigating イベントと、ページ ナビゲーションの完了時に発生する Navigated イベントを定義します。 Navigating イベントに付随する WebNavigatingEventArgs オブジェクトは、ナビゲーションを取り消すために使用できる bool 型の Cancel プロパティを定義します。 Navigated イベントに付随する WebNavigatedEventArgs オブジェクトは、ナビゲーション結果を示す WebNavigationResult 型の Result プロパティを定義します。

WebView は、次のイベントを定義します。

  • Navigating: ナビゲーションの開始時に発生します。 このイベントに付随する WebNavigatingEventArgs オブジェクトには、ナビゲーションを取り消すために使用できる bool 型の Cancel プロパティが定義されています。
  • Navigated: ページ ナビゲーションが完了したときに発生します。 このイベントに付随する WebNavigatedEventArgs オブジェクトには、ナビゲーション結果を示す WebNavigationResult 型の Result プロパティが定義されています。
  • ProcessTerminated: WebView プロセスが予期せず終了したときに発生します。 このイベントに付随する WebViewProcessTerminatedEventArgs オブジェクトには、プロセスが失敗した理由を示すプラットフォーム固有のプロパティが定義されています。

重要

WebView は、HorizontalStackLayoutStackLayout、またはVerticalStackLayout に含まれている場合は、HeightRequest プロパティと WidthRequest プロパティを指定する必要があります。 これらのプロパティを指定しないと、WebView はレンダリングされません。

Web ページを表示する

リモート Web ページを表示するには、URI を指定する stringSource プロパティを設定します。

<WebView Source="https://video2.skills-academy.com/dotnet/maui" />

同等の C# コードを次に示します。

WebView webvView = new WebView
{
    Source = "https://video2.skills-academy.com/dotnet/maui"
};

URI は、指定されたプロトコルで完全に形成されている必要があります。

Note

Source プロパティは WebViewSource 型ですが、このプロパティは文字列ベースの URI に設定できます。 これは、.NET MAUI に型コンバーターと、文字列ベースの URI を UrlWebViewSource オブジェクトに変換する暗黙的な変換演算子が含まれているためです。

iOS と Mac Catalyst でアプリケーション トランスポート セキュリティを構成する

バージョン 9 以降、iOS ではセキュリティで保護されたサーバーとの通信のみがアプリに許可されます。 アプリは、セキュリティで保護されていないサーバーとの通信を有効にすることを選択する必要があります。

次の Info.plist 構成は、特定のドメインを有効にして Apple Transport Security (ATS) 要件をバイパスする方法を示しています。

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSExceptionDomains</key>
		<dict>
			<key>mydomain.com</key>
			<dict>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
				<true/>
				<key>NSTemporaryExceptionMinimumTLSVersion</key>
				<string>TLSv1.1</string>
			</dict>
		</dict>
	</dict>

ATS をバイパスするには、特定のドメインのみを有効にすることをお勧めします。それにより、信頼されていないドメインのセキュリティを強化しながら、信頼済みサイトを使用できます。

次の Info.plist 構成は、アプリの ATS を無効にする方法を示しています。

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

重要

安全でない Web サイトへの接続がアプリで必要な場合は、常に、NSAllowsArbitraryLoads キーを使用して ATS を完全にオフにするのではなく、NSExceptionDomains キーを使用してドメインを例外として入力する必要があります。

ローカル HTML を表示する

インライン HTML を表示するには、Source プロパティを HtmlWebViewSource オブジェクトに設定します。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource Html="&lt;HTML&gt;&lt;BODY&gt;&lt;H1&gt;.NET MAUI&lt;/H1&gt;&lt;P&gt;Welcome to WebView.&lt;/P&gt;&lt;/BODY&gt;&lt;HTML&gt;" />
    </WebView.Source>
</WebView>

XAML では、<> のシンボルがエスケープされるため、HTML 文字列が読み取れなくなる可能性があります。 したがって、読みやすくするために、HTML を CDATA セクションにインライン化できます。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <HTML>
                <BODY>
                <H1>.NET MAUI</H1>
                <P>Welcome to WebView.</P>
                </BODY>
                </HTML>
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

同等の C# コードを次に示します。

WebView webView = new WebView
{
    Source = new HtmlWebViewSource
    {
        Html = @"<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY></HTML>"
    }
};

ローカル HTML ファイルを表示する

ローカル HTML ファイルを表示するには、アプリ プロジェクトの Resources\Raw フォルダーにファイルを追加し、そのビルド アクションを MauiAsset に設定します。 その後、Source プロパティの値として設定されている HtmlWebViewSource オブジェクトで定義されているインライン HTML からファイルを読み込むことができます。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <html>
                <head>
                </head>
                <body>
                <h1>.NET MAUI</h1>
                <p>The CSS and image are loaded from local files!</p>
                <p><a href="localfile.html">next page</a></p>
                </body>
                </html>                    
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

ローカル HTML ファイルは、MauiAsset ビルド アクションを使用してアプリ プロジェクトにも追加されている場合、カスケード スタイル シート (CSS)、JavaScript、イメージを読み込むことができます。

生アセットの詳細については、「生アセット」を参照してください。

コンテンツの再読み込み

WebView には、ソースを再読み込みするために呼び出すことができる Reload メソッドがあります。

WebView webView = new WebView();
...
webView.Reload();

Reload メソッドが呼び出されると、現在のコンテンツを再読み込みする要求が行われていることを示す ReloadRequested イベントが発生します。

ナビゲーションを実行する

WebView では、GoBack メソッドと GoForward メソッドによるプログラム ナビゲーションをサポートしています。 これらのメソッドは、WebView ページ スタック内のナビゲーションを有効にし、CanGoBack プロパティと CanGoForward プロパティの値を調べた後にのみ呼び出す必要があります。

WebView webView = new WebView();
...

// Go backwards, if allowed.
if (webView.CanGoBack)
{
    webView.GoBack();
}

// Go forwards, if allowed.
if (webView.CanGoForward)
{
    webView.GoForward();
}

プログラムかユーザーによって開始されたページ ナビゲーションが WebView で発生すると、次のイベントが発生します。

  • Navigating は、ページ ナビゲーションの開始時に発生します。 Navigating イベントに付随する WebNavigatingEventArgs オブジェクトは、ナビゲーションを取り消すために使用できる bool 型の Cancel プロパティを定義します。
  • Navigated は、ページ ナビゲーションが完了したときに発生します。 Navigated イベントに付随する WebNavigatedEventArgs オブジェクトは、ナビゲーション結果を示す WebNavigationResult 型の Result プロパティを定義します。

Android でのアクセス許可の処理

カメラやマイクなど、デバイスの録音ハードウェアへのアクセスを要求するページを参照する場合は、WebView コントロールによってアクセス許可が付与されている必要があります。 WebView コントロールでは、Android 上の Android.Webkit.WebChromeClient 型を使用してアクセス許可要求に対応します。 ただし、.NET MAUI によって提供される WebChromeClient 実装では、アクセス許可要求は無視されます。 MauiWebChromeClient から継承してアクセス許可要求を承認する新しい型を作成する必要があります。

重要

この方法を使用してアクセス許可要求を承認するように WebView をカスタマイズするには、Android API 26 以降が必要です。

Web ページから WebView コントロールへのアクセス許可要求は、.NET MAUI アプリからユーザーへのアクセス許可要求とは異なります。 .NET MAUI アプリのアクセス許可は、アプリ全体に対してユーザーによって要求され、承認されます。 WebView コントロールは、ハードウェアにアクセスするアプリの機能に依存します。 この概念を説明するために、デバイスのカメラへのアクセスを要求する Web ページを検討します。 その要求が WebView コントロールによって承認されているにもかかわらず、.NET MAUI アプリがユーザーによるカメラへのアクセスの承認を得ていなかった場合、Web ページはカメラにアクセスできません。

次の手順では、カメラを使用するために WebView コントロールからのアクセス許可要求をインターセプトする方法を示します。 マイクを使用する場合は、カメラ関連のアクセス許可ではなくマイク関連のアクセス許可を使用すること以外は、手順は似ています。

  1. まず、必要なアプリのアクセス許可を Android マニフェストに追加します。 Platforms/Android/AndroidManifest.xml ファイルを開き、manifest ノードに以下を追加します。

    <uses-permission android:name="android.permission.CAMERA" />
    
  2. WebView コントロールを含むページが読み込まれる場合など、アプリのある時点で、カメラへのアプリのアクセスを許可するアクセス許可をユーザーに要求します。

    private async Task RequestCameraPermission()
    {
        PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
    
        if (status != PermissionStatus.Granted)
            await Permissions.RequestAsync<Permissions.Camera>();
    }
    
  3. Platforms/Android フォルダーに次のクラスを追加し、プロジェクトの名前空間に合わせてルート名前空間を変更します。

    using Android.Webkit;
    using Microsoft.Maui.Handlers;
    using Microsoft.Maui.Platform;
    
    namespace MauiAppWebViewHandlers.Platforms.Android;
    
    internal class MyWebChromeClient: MauiWebChromeClient
    {
        public MyWebChromeClient(IWebViewHandler handler) : base(handler)
        {
    
        }
    
        public override void OnPermissionRequest(PermissionRequest request)
        {
            // Process each request
            foreach (var resource in request.GetResources())
            {
                // Check if the web page is requesting permission to the camera
                if (resource.Equals(PermissionRequest.ResourceVideoCapture, StringComparison.OrdinalIgnoreCase))
                {
                    // Get the status of the .NET MAUI app's access to the camera
                    PermissionStatus status = Permissions.CheckStatusAsync<Permissions.Camera>().Result;
    
                    // Deny the web page's request if the app's access to the camera is not "Granted"
                    if (status != PermissionStatus.Granted)
                        request.Deny();
                    else
                        request.Grant(request.GetResources());
    
                    return;
                }
            }
    
            base.OnPermissionRequest(request);
        }
    }
    

    前のスニペットでは、MyWebChromeClient クラスは MauiWebChromeClient から継承し、OnPermissionRequest メソッドをオーバーライドして Web ページのアクセス許可要求をインターセプトします。 各アクセス許可の項目は、カメラを表す PermissionRequest.ResourceVideoCapture 文字列定数と一致するかどうかを確認するためにチェックされます。 カメラのアクセス許可が一致した場合、アプリがカメラを使用するアクセス許可を持っているかどうかをコードが確認します。 アクセス許可がある場合は、Web ページの要求が付与されます。

  4. Chrome クライアントを MyWebChromeClient に設定するには、Android の WebView コントロールの SetWebChromeClient メソッドを使用します。 次の 2 つの項目は、Chrome クライアントを設定する方法を示しています。

    • theWebViewControl という .NET MAUI WebView コントロールを指定すると、Android コントロールであるプラットフォーム ビューで Chrome クライアントを直接設定できます。

      ((IWebViewHandler)theWebViewControl.Handler).PlatformView.SetWebChromeClient(new MyWebChromeClient((IWebViewHandler)theWebViewControl.Handler));
      
    • また、ハンドラー プロパティ マッピングを使用して、すべての WebView コントロールに Chrome クライアントの使用を強制することもできます。 詳細については、「イベント ハンドラー」を参照してください。

      次のスニペットの CustomizeWebViewHandler メソッドは、MauiProgram.CreateMauiApp メソッド内など、アプリの起動時に呼び出す必要があります。

      private static void CustomizeWebViewHandler()
      {
      #if ANDROID26_0_OR_GREATER
          Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(
              nameof(Android.Webkit.WebView.WebChromeClient),
              (handler, view, args) => handler.PlatformView.SetWebChromeClient(new MyWebChromeClient(handler)));
      #endif
      }
      

Cookie の設定

Cookie は、Web 要求と共に指定された URL に送信されるように WebView に設定できます。 Cookie オブジェクトを CookieContainer に追加して Cookie を設定し、コンテナーを WebView.Cookies バインド可能なプロパティの値として設定します。 次に例を示します。

using System.Net;

CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://video2.skills-academy.com/dotnet/maui", UriKind.RelativeOrAbsolute);

Cookie cookie = new Cookie
{
    Name = "DotNetMAUICookie",
    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() };

この例では、1 つの CookieCookieContainer オブジェクトに追加し、WebView.Cookies プロパティの値として設定します。 WebView が指定したURL に Web 要求を送信すると、要求と共に Cookie が送信されます。

JavaScript の呼び出し

WebView は、C# から JavaScript 関数を呼び出して、呼び出し元の C# コードに結果を返すことができます。 次の例に示すように、この相互運用は EvaluateJavaScriptAsync メソッドで実現されます。

Entry numberEntry = new Entry { Text = "5" };
Label resultLabel = new Label();
WebView webView = new WebView();
...

int number = int.Parse(numberEntry.Text);
string result = await webView.EvaluateJavaScriptAsync($"factorial({number})");
resultLabel.Text = $"Factorial of {number} is {result}.";

WebView.EvaluateJavaScriptAsync メソッドは、引数として指定された JavaScript を評価し、結果を string として返します。 この例では、factorial JavaScript 関数が呼び出され、結果として number の階乗が返されます。 この JavaScript 関数は、WebView が読み込むローカル HTML ファイルで定義されており、次の例に示されています。

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

iOS および Mac Catalyst でネイティブ WebView を構成する

ネイティブ WebView コントロールは、WKWebView から派生した iOS と Mac Catalyst の MauiWKWebView です。 MauiWKWebView コンストラクターのオーバーロードの 1 つを使用すると WKWebViewConfiguration オブジェクトを指定できます。これにより、WKWebView オブジェクトの構成方法に関する情報が提供されます。 一般的な構成には、ユーザー エージェントの設定、Web コンテンツで Cookie を使用できるようにする指定、Web コンテンツへのカスタム スクリプトの挿入などがあります。

アプリに WKWebViewConfiguration オブジェクトを作成し、そのプロパティを必要に応じて構成できます。 または、静的 MauiWKWebView.CreateConfiguration メソッドを呼び出して .NET MAUI の WKWebViewConfiguration オブジェクトを取得し、それを変更することもできます。 その後、WKWebViewConfiguration オブジェクトを MauiWKWebView コンストラクター オーバーロードの引数として指定できます。

ハンドラーのプラットフォーム ビューが作成されると、iOS や Mac Catalyst ではネイティブ WebView の構成を変更できないため、カスタム ハンドラー ファクトリ デリゲートを作成して変更する必要があります。

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();
        config.ApplicationNameForUserAgent = "MyProduct/1.0.0";
        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

Note

WebView がアプリに表示される前に、WKWebViewConfiguration オブジェクトを使用して MauiWKWebView を構成する必要があります。 これを行うのに適した場所は、MauiProgram.csApp.xaml.cs などのアプリのスタートアップ パスにあります。

iOS および Mac Catalyst でメディアの再生設定を設定する

iOS と Mac Catalyst の WebView では、自動再生やピクチャ イン ピクチャを含む HTML5 ビデオのインライン メディア再生が既定で有効になっています。 この既定値を変更したり、他のメディア再生設定を設定したりするには、ハンドラーのプラットフォーム ビューを作成した後でメディア再生の基本設定を変更できないため、カスタム ハンドラー ファクトリ デリゲートを作成する必要があります。 次のコードは、これを行う例を示しています。

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();

        // True to play HTML5 videos inliine, false to use the native full-screen controller.
        config.AllowsInlineMediaPlayback = false;

        // True to play videos over AirPlay, otherwise false.
        config.AllowsAirPlayForMediaPlayback = false;

        // True to let HTML5 videos play Picture in Picture.
        config.AllowsPictureInPictureMediaPlayback = false;

        // Media types that require a user gesture to begin playing.
        config.MediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.All;

        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

iOS での WebView の構成の詳細については、「 iOS および Mac Catalyst でネイティブ WebView を構成する」をご覧ください。

Mac Catalyst で WebView を検査する

Safari 開発者ツールを使用して Mac Catalyst 上の WebView のコンテンツを検査するには、アプリに次のコードを追加します。

#if MACCATALYST
        Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("Inspect", (handler, view) =>
        {
            if (OperatingSystem.IsMacCatalystVersionAtLeast(16, 6))
                handler.PlatformView.Inspectable = true;
        });
#endif

このコードでは、Mac Catalyst 上の WebViewHandler のプロパティ マッパーをカスタマイズして、WebView コンテンツを Safari 開発者ツールで検査できるようにします。 ハンドラーの詳細については、「ハンドラー」をご覧ください。

Mac Catalyst アプリで Safari 開発者ツールを使用するには、次の手順で行います。

  1. Mac で Safari を開きます。
  2. Safari で、[Safari] > [環境設定] > [詳細] > [メニュー バーに開発メニューを表示] チェックボックスを選択します。
  3. .NET MAUI Mac Catalyst アプリを実行します。
  4. Safari で、[開発] > [{デバイス名}] メニューを選択します。ここで、{Device name} プレースホルダーは Macbook Pro などのデバイス名です。 次に、アプリ名の下にあるエントリを選択します。これにより、実行中のアプリも強調表示されます。 その結果、[Web インスペクタ] ウィンドウが表示されます。

システム ブラウザーを起動する

Microsoft.Maui.Essentials で提供される Launcher クラスを使用して、システムの Web ブラウザーで URI を開くことができます。 ランチャーの OpenAsync メソッドを呼び出し、開く URI を表す string または Uri 引数を渡します。

await Launcher.OpenAsync("https://video2.skills-academy.com/dotnet/maui");

詳細については、「ランチャー」をご覧ください。