Reputation: 3274
I'm developing a Web App application that is almost finished, the app has a local WebApp that has some links and I'd like to open them in an external browser (Edge, Chrome, etc.).
My code is split in 3 parts:
1) Windows Runtime Component:
using System;
using System.Collections.Generic;
using Windows.Foundation.Metadata;
using Windows.Storage;
using Windows.System;
namespace CallJSInterface
{
[AllowForWeb]
public sealed class CallJSCSharp
{
public async void OpenURL(string url)
{
await Launcher.LaunchUriAsync(new Uri(url));
}
}
}
2) WebView code:
XAML:
<WebView x:Name="webView1" Source="ms-appx-web:///Assets/index.html" NavigationStarting="webView1_NavigationStarting" />
C#:
private void webView1_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
sender.AddWebAllowedObject("CallJSCSharp", pObject: new CallJSCSharp());
}
3) JavaScript (jQuery):
$("a").click(function (event) {
event.preventDefault();
CallJSCSharp.OpenURL($(this).attr('href'));
});
But nothing happens, no error, no message, nothing. Does anyone know what should I change? Thanks for your help.
I'm using the same configuration for both projects.
Upvotes: 2
Views: 1104
Reputation: 39082
There are two issues that cause the code not to work.
First - the Windows Runtime Component automatically modifies the naming conventions to match the target platform on which it is executed. Because JavaScript method names by convention start with a lowercase letter, you must call the OpenURL
method like this:
CallJSCSharp.openURL($(this).attr('href'));
Now you should be able to set a breakpoint in the Windows Runtime Component and see the method is actually called. But there is another catch - the OpenURL
method is not called on the UI thread which is required for Launcher
to work properly. To circumvent this you need to use Dispatcher
:
[AllowForWeb]
public sealed class CallJSCSharp
{
public async void OpenURL(string url)
{
await CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
async () => {
await Launcher.LaunchUriAsync(new Uri(url));
});
}
}
With this change in place, the code should work as intended.
Finally - thank you for a perfectly written question :-) .
Upvotes: 4