Within the outdated days, accessing an area web site in UWP was comparatively simple. Even if you happen to wished to load your third-party libs. The essential code you required:
The WebView:
<WebView x:Title="webView1" Supply="ms-appx-web:///Property/index.html" NavigationStarting="WebView1_NavigationStarting" NavigationCompleted="WebView1_NavigationCompleted" />
Right here you outlined the Supply and a few additional occasions like NavigationStarting
or NavigationCompleted
for loading your JS or enabling JS interplay together with your third-party lib (that you simply had so as to add as a reference in your most important venture).
Loading your third-party lib:
personal void WebView1_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
sender.AddWebAllowedObject("CallJSCSharp", new CallJSCSharp());
}
Including additional code to load further JS:
personal async void WebView1_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
string filename = $"ms-appx:///Property/js/lang/en.json";
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filename));
string contents = await FileIO.ReadTextAsync(file);
string[] arg = { contents };
_ = await webView1.InvokeScriptAsync("UpdateData", arg);
}
And that is the perform to execute additional capabilities from my app:
namespace CallJSInterface
{
personal Home windows.System.Show.DisplayRequest _displayRequest;
public sealed partial class CallJSCSharp
{
public void KeepScreenOn()
{
//create the request occasion if wanted
if (_displayRequest == null)
{
_displayRequest = new Home windows.System.Show.DisplayRequest();
}
//make request to place in energetic state
_displayRequest.RequestActive();
}
}
}
Now, what are all of the modifications required for the brand new WebView2, there are a number of modifications to be thought of. The primary one is to obtain the lib Microsoft.UI.Xaml
from NuGet in your most important venture:
This lib lets you add WebView2. It requires two modifications:
Add this lib in your XAML’s libs:
xmlns:controls="utilizing:Microsoft.UI.Xaml.Controls"
After which, you’ll be able to add your WebView2:
<controls:WebView2 x:Title="webView1" NavigationCompleted="WebView1_NavigationCompleted" />
Now comes the difficult elements. The primary change is in regards to the Supply. With WebView2, we will solely load exterior web sites like bing.com or fb.com. Any native web site goes to fail.
The brand new method follows creating an asynchronous perform that creates a digital host (it must be referred to as within the Constructor), the place you map your present native web site like this:
personal CoreWebView2 core_wv2;
personal async void LoadLocalPage()
{
string fakeDomain = "myapp.one thing";
string assetsLocation = "Property";
string firstPage = "index.html";
await webView1.EnsureCoreWebView2Async();
core_wv2 = webView1.CoreWebView2;
if (core_wv2 != null)
{
core_wv2.SetVirtualHostNameToFolderMapping(
fakeDomain, assetsLocation,
CoreWebView2HostResourceAccessKind.Enable);
webView1.Supply = new Uri($"https://{fakeDomain}/${firstPage}");
}
}
Each path that you’ve in your outdated app appears to be like like this:
ms-appx-web:///Property/
have to be modified to:
https://myapp.one thing/
Subsequently, if you happen to loaded Bootstrap like this:
ms-appx-web:///Property/css/boostrap.min.css
Now, it will be like this:
https://myapp.one thing/css/bootstrap.min.css
The following half is find out how to work together together with your third-party lib, and this half is sophisticated.
The primary half includes including a brand new and really particular C++ venture, Home windows Runtime Part (C++/WinRT), to your answer that have to be referred to as WinRTAdapter.
You need to set up a lib from NuGet Microsoft.Internet.WebView2
:
Add as a reference your third-party lib.
Go to your C++ venture properties go to Frequent Properties and select WebView2:
Right here it’s a must to do 4 modifications:
- Set Use WebView2 WinRT APIs to No.
- Set Use the wv2winrt device to Sure.
- Set Use Javascript case to Sure.
- Edit Embrace filters and add the next ones:
Home windows.System.UserProfile
Home windows.Globalization.Language
CallJSInterface
CallJSInterface is the identify of my third-party’s namespace.
You click on on OK and constructed your C++ lib.
After you could have constructed your C++ lib (WinRTAdapter), you could add it to your most important venture as a reference.
Now, we have to do some modifications to have the ability to invoke the capabilities from our third-party lib. The primary one is to register it. We do it in the identical LoadLocalPage()
perform from earlier than or on NavigationCompleted:
var namespacesName = "CallJSInterface";
var dispatchAdapter = new WinRTAdapter.DispatchAdapter();
core_wv2.AddHostObjectToScript(namespacesName, dispatchAdapter.WrapNamedObject(namespacesName, dispatchAdapter));
The place CallJSInterface
is your namespace. After this, you want to register your perform in your JS like this:
var callJS;
if (chrome && chrome.webview) {
chrome.webview.hostObjects.choices.defaultSyncProxy = true;
chrome.webview.hostObjects.choices.forceAsyncMethodMatches = [/Async$/];
chrome.webview.hostObjects.choices.ignoreMemberNotFoundError = true;
window.CallJSInterface = chrome.webview.hostObjects.sync.CallJSInterface;
callJS = new CallJSInterface.CallJSCSharp();
}
The place CallJSInterface
is yet another time your namespace. Now, you’ll be able to invoke JS like this (the async()
is necessary):
callJS.async().KeepScreenOn()
The final half is find out how to load your scripts as earlier than. The outdated perform InvokeScriptAsync("UpdateData", arg)
would not exit. The easiest way is to create a category Extension like this:
public static class Extensions
{
public static async Process<string> ExecuteScriptFunctionAsync(this WebView2 webView2, string functionName, params object[] parameters)
{
string script = functionName + "(";
for (int i = 0; i < parameters.Size; i++)
{
script += JsonConvert.SerializeObject(parameters[i]);
if (i < parameters.Size - 1)
{
script += ", ";
}
}
script += ");";
return await webView2.ExecuteScriptAsync(script);
}
}
Now, from the NavigationCompleted, you’ll be able to load it within the outdated method:
_ = await webView1.ExecuteScriptFunctionAsync("UpdateData", arg);
With all these steps, you are able to do it once more your complete course of.
Banner credit: