【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同樣)。

相關文章
相關標籤/搜索