【Win10 UWP】URI Scheme(二):自定義協議的處理和適用場景


上一篇提到Windows Store協議的使用,其實Windows Store協議僅是系統內建的一種協議規則。我們也可以自己定義一套規范的URI-Scheme,除了可以給其他App調用外,本應用也可以進行調用,解決一些特殊的場景,本講具體探討這一問題。

關於Windows Store協議的解析和使用,可先閱讀上一篇:http://www.cnblogs.com/zhxilin/p/4819372.html

 

一.自定義協議的處理

前面提到,通過協議,應用可以被“激活(Activated)”,並且可以自行處理激活之后的操作。應用商店這個App的原理很簡單,它在Package.appxmanifest里定義了一個“協議”類型的聲明叫ms-windows-store,我們可以模擬一下:

由於ms-windows-store被定義為內建的協議,我們自定義協議時並不能使用這個名稱,這里用ms-windows-store1代替。

關於更多內建協議的使用規則,請參考:https://msdn.microsoft.com/en-us/library/windows/apps/mt228340.aspx

回到App.cs里,重載OnActivated方法,該方法接收一個IActivatedEventArgs類型的參數:

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

通過args參數的Kind屬性來確定具體是哪種類型激活了應用,我們這里只處理Protocol類型的激活(因為自定義協議就是一種Protocol):

 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頁面的交互

App和Web頁面的交互是非常普遍的情景,一般頁面都會考慮直接使用腳本進行通知,並且我相信絕大部分前端開發者都已經被逼瘋:WP需要一種處理,iOS又是另一種處理;前端得判斷請求來自什么平台,而且還不准確,BlaBla....總之問題非常多!

現在有這樣一個需求,比如在一個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一樣)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM