【Win10 UWP】URI Scheme(二):自定义协议的处理和适用场景

上一篇提到Windows Store协议的使用,其实Windows Store协议仅是系统内建的一种协议规则。咱们也能够本身定义一套规范的URI-Scheme,除了能够给其余App调用外,本应用也能够进行调用,解决一些特殊的场景,本讲具体探讨这一问题。html

关于Windows Store协议的解析和使用,可先阅读上一篇:http://www.cnblogs.com/zhxilin/p/4819372.html前端

 

一.自定义协议的处理

前面提到,经过协议,应用能够被“激活(Activated)”,而且能够自行处理激活以后的操做。应用商店这个App的原理很简单,它在Package.appxmanifest里定义了一个“协议”类型的声明叫ms-windows-store,咱们能够模拟一下:web

因为ms-windows-store被定义为内建的协议,咱们自定义协议时并不能使用这个名称,这里用ms-windows-store1代替。windows

关于更多内建协议的使用规则,请参考:https://msdn.microsoft.com/en-us/library/windows/apps/mt228340.aspxapp

回到App.cs里,重载OnActivated方法,该方法接收一个IActivatedEventArgs类型的参数:async

1 protected override async void OnActivated(IActivatedEventArgs args)
2 {
3    // TODO: handle activate action
4 }

经过args参数的Kind属性来肯定具体是哪一种类型激活了应用,咱们这里只处理Protocol类型的激活(由于自定义协议就是一种Protocol):ide

 1 protected override async void OnActivated(IActivatedEventArgs args)
 2 {
 3     if (args.Kind == ActivationKind.Protocol)
 4     {
 5          if (!_hasLaunched)
 6         {
 7             CreateRootFrame();
 8             _hasLaunched = true;
 9         }
10  
11         var protocalArgs = (ProtocolActivatedEventArgs) args; 12         if (protocalArgs.Uri.Scheme == AppConfig.MyAppScheme) 13         {
14             UrlSchemeHelper.ParseScheme(protocalArgs.Uri);
15         }
16     }
17     Window.Current.Activate();
18 }

肯定了属于协议激活后,将args转成对应类型的参数ProtocolActivatedEventArgs,最终咱们如同处理一个普通http url同样,自定义个一个UrlSchemeHelper类进行解析和页面导航,具体处理请自行脑洞。函数

 

二.自定义协议的意义

自定义协议,对呼叫协议做不一样的响应,这是一件很是酷的事情。不只能够给第三方应用调用,还能够给应用自己调用,处理一些特殊场景!我这里要说的一个特殊的适用场景就是App和Web页面的交互url

App和Web页面的交互是很是广泛的情景,通常页面都会考虑直接使用脚本进行通知,而且我相信绝大部分前端开发者都已经被逼疯:WP须要一种处理,iOS又是另外一种处理;前端得判断请求来自什么平台,并且还不许确,BlaBla....总之问题很是多!spa

如今有这样一个需求,好比在一个Web页面里有一个按钮,触发了这个按钮以后要求App跳转到某一个指定页面,一般写个脚本的话应该是这样的(UWP应使用window.external.notify("")函数,且只能返回字符串)

1 function onNavigateClick() {
2    window.external.notify("navigate:some_page");
3 }

App在WebView上注册void Browser_ScriptNotify(object sender, NotifyEventArgs e)事件,经过参数e.Value将web页面的通知内容“navigate:some_page”取出来作相应处理。

 

然而ScriptNotify事件的局限性很是大:

1.window.external.notify只能返回字符串

2.只有本地的Web页面(ms-appdata、ms-local-stream或ms-appx-web),或者受信任的HTTPS才能触发事件;普通HTTP没法触发

 

大多数Web页面都是HTTP的,而且若是下载到本地再显示每每有问题,所以对UWP来讲,这种交互方式简直就是噩梦!不只前端痛苦,客户端也痛苦!

 

这时候自定义协议就能够发挥其功力了!一样的例子,如今彻底能够改为协议的形式来进行通知:

1 function onNavigateClick() {
2    window.location.href = 'myapp://page?id=1&title=hero';
3 }

App里就用上述提到的方式接收通知!

 

且慢,在UWP项目中,在一个WebView里,某一个html页面经过自定义的URI-Scheme的形式来通知APP时,WebView会触发一个UnsupportedUriSchemeIdentified事件,表示WebView并不认识这个协议,是否要处理取决于你。

UWP的WebView默认只能处理http, https, ms-appx-web和ms-local-stream这几种协议,对于其余协议,都会触发UnsupportedUriSchemeIdentified事件,而且会弹出一个警告对话框:

为了避免显示这个对话框,咱们须要手动处理一下:

1 private async void WebView_OnUnsupportedUriSchemeIdentified(WebView sender, WebViewUnsupportedUriSchemeIdentifiedEventArgs args)
2 {
3       args.Handled = true; 4       if (args.Uri.Scheme == AppConfig.MyAppScheme)
5       { 
6            await Launcher.LaunchUriAsync(args.Uri); 
7       } 
8 }

先将args.Handled标记为true,警告对话框就不会弹出了;而后再经过Launcher尝试启动这个WebView不识别的URI;最后用咱们上述讲到的处理方式在App.OnActivated中接收并解析。

 

这样的好处彻底解放了前端开发的压力,这套机制适用于各类各样的客户端(iOS、Android、WP、Windows等);对于客户端而言,定义规范化的URI-Scheme有助于维护和扩展,甚至能够发展成开发平台或开放应用(如同商店APP同样)。

相关文章
相关标签/搜索