Windows 10 UWA( UWP APP) 開發入門 (附範例)
本篇主要是介紹如何開發第一個Windows 10 UWP 的應用程式, 並整理目前的一些相關開發資源。本篇適合對開發Windows 10 App (UWA) 有興趣的新手及iOS、Android 開發者。
如果你是Windows App 開發的新手 ( 沒有Windows 8/8.1市集App 或 Windows Phone App 的開發經驗) 建議可以先到 Windows 開發人員中心 逛逛, 了解一下上面提供的資訊。
在Windows 開發人員中心上面有蠻多的開發資源, 包括:
- Windows 應用程式入門
- 開發 Universal Windows app
- 設計 UWP 應用程式
- 發佈 Windows 應用程式
都值得看一看。
[主要用語 UWP、 UWA、 Bridges]
UWP ( Universal Windows Platform ) : 又稱作 "通用Windows 平台" 。 由於Windows 10 的系統架構設計是可以在多種裝置 ( 平板、手機、桌機、筆電、Xbox One、HoloLens、Surface Hub、Raspberry Pi 2.. )上運行, 為了要方便開發者在各型裝置上設計應用程式, 不用面對各式不同的API介面、呼叫方式以及App 生命週期;同時開發好的APP也可以輕易地在不同裝置上執行,因此微軟定義了UWP(通用Windows 平台)。
開發者無論是在那一種Windows 10 裝置上開發, 都只要面對UWP (所以才叫通用),同時編譯出來的程式也只有需要一種編譯檔 (Binary) 即可。 每個Windows 10 裝置上都有UWP, 而UWP 也會負責讓程式人員開發好的APP 順暢地在各裝置上執行,大大減少開發成本以及開發人員負擔。
也因為程式是在UWP 架構上開發, 所以開發人員在開發時需要在專案的設定檔 package.appxmanifest中指定所支援的UWP 版本。
另外果遇到在特定類型裝置才能夠使用的API, 則要是透過 Extension 的方式來擴充。
UWA ( Universal Windows App) : 是指在UWP 架構上執行的原生 App 程式 。也有人稱作UWP App。
目前支援四種開發語言, 分別是 Visual C#、Visual Basic、Visual C++ 以及JavaScript。
Bridges ( UWP 的造橋計畫) : 除了原生的UWA 外, Windows 10 也透過Bridges 計劃裡的Project Westminster (西敏專案), Project Centennial( 百年專案), Project Astoria ( 阿斯托利亞專案), Project IslandWood (島木專案), 讓 無論是熟悉JavaScript/CSS的前端網頁開發人員、熟悉傳統Windows 應用程式的 。Net 或C++ 開發人員、熟悉 Android 平台的Java開發人員、或者是熟悉iOS 的Objective C 開發人員,都可以藉由這四大專案將他們開發的軟體快速地帶到通用Windows 平台上 。不過API 及 跨Windows 裝置支援最完整的還是原生的UWA 程式。 Project Westminster 已經於2015年七月發表, 可以參考這篇 : Windows 10 造橋計畫, 第一橋 W專案 (Project Westminster )。
介紹了一些基本概念, 接下來說明如何開發第 一個UWP App。
[開發工具及環境]
UWA 的開發會需要 :
- Windows 10 作業系統 (所有Windows Vista, Windows 7, Windows 8/8.1 使用者都可以免費升級)
- Visual Studio 2015 ( 個人或年營收小於3000萬台幣的小型團隊可以使用免費版的Visual Studio Community 版 ) 及 Windows 10 SDK (安裝方式已內建在Visual Studio 2015 中)
建立開發環境的相關資源都可以在這裡(https://dev.windows.com/zh-tw/downloads)找到。
準備好環境後, 接下來開啟 Visual Studio , 選擇建立新的專案。
接下來選擇 Windows -> Windows Universal -> Blank App ( Windows Universal ) 專案範本 建立專案。
接下來我們準備要App 要使用的資料源, 這邊我們用行政院環境保護署提供的紫外線即時監測資料 每小時UV 指數當作資料源。
https://data.gov.tw/node/6076
紫外線即時監測資料 的JSON資料格式如下:
我們先為上面JSON資料 建立Data Object, 以方便後續讀取及使用。
在專案中建立一個Models 資料夾, 然後建立 名為TaiwanCityUV 的Class
接著根據Json 的格式將TaiwanCity Data Object 撰寫如下 :
這邊比較特別的是在 "PublishTime" 還有 "UVI" 這兩個properties 加上NotifyPropertyChanged Event, 主要是這兩個欄位是比較容易更新的欄位,我們加上這兩個屬性可以確保一旦我們更新資料時,在UI介面上的值也會跟著更新。
(有關NotifyPropertyChanged 可以參考INotifyPropertyChanged Interface)
接下來我們要讀取網路上的紫外線即時監測公開資料 :
先建立一個Services 資料夾,然後再建立TaiwanUVOpenDataService Class。
在這邊我們利用 HttpClient 物件取得JSON內容, 然後透過 DataContractJsonSerializer 的 ReadObject 物件去 DeSerialize (反序列化) 而將所有Json 格式的紫外線即時資料轉成 放在List 中DataObject TaiwanCityUV, 以方便我們後續作資料使用及顯示。
在使用HttpClient 物件時, 建議用Windows.Web.Http 命名空間下的 HttpClient, 不要用 System.Net.Http 的命名空間。
這邊比較特別的是我們希望後續可以很容易追蹤 App 的Crash 狀況 以及使用狀況。 這部分微軟的雲端服務 Azure 提供了Application Insight 功能, 它可以很方便地提供App使用狀況分析及Crash 分析, 而且支援UWP、iOS、Android、Web (PHP、Python、Ruby、 Node.js、WordPress..etc) 及傳統Windows Desktop 程式。 同時它也提供每個月 5百萬個Data Points 免費的額度, 對大部分中小型 App 應該相當夠用,也適合本範例使用。
為了追蹤我們連到網路取得資料時是否有異常, 我們直接宣告 Application Insight SDK 中的 TelemetryClient , 並且呼叫TrackException method 來將 遇到的Exception 送到Application Insight 服務做分析。 只要兩行程式碼就完成。
接下來開始開發 App 前端介面的部分。
在Windows 10 Univeral App 的設計上有幾個有別於過去Windows 8 設計的地方, 特別是透過 SplitView 控制項做出漢堡圖的效果已經被大量應用在官方的 App 上。
另外幾個重要的新控制項功能包括 :
- AdaptiveTrigger
- VisualState.Setters
- RelativePanel
如一開頭所提的, UWA 很重要的一個特性就是能橫跨多種不同的裝置,由於不同的裝置的螢幕大小差異很大,以上幾個新的控制項功能可以很快的協助開發者針對不同的螢幕尺寸動態調整UI 上的配置。
以下我們就透過這些新的控制項功能做出能同時適應大尺寸螢幕(eg。 PC, 平板,Surface Pro) 及小尺寸螢幕(eg。 手機)的UI 介面。
首先先做主版型,先打開 MainPage.xaml, 在 Grid 下面加入 SplitView 控制項, 用來做出漢堡圖功能。 同時把Grid 命名為 rootGrid。 在SplitView
在漢堡圖的Button 上新增 Click Event : clickHamburgerBtn
在 clickHamburgerBtn Method 中加入讓 漢堡圖選單開關的程式碼。
為了建立選單內容, 我們在Model 資料夾下建立MenuItem Data Object。
接下來要處理MainPage 頁面相關的DataBinding。 我們在專案下面建立一個ViewModels 資料夾, 再建立一個 MainViewModel Class。 這個Class 的內容如下:
由於這個Class 會被用來做UI 的Data Binding, 因此我們繼承了INotifyPropertyChanged Interface 以確保資料的更新可以立即反映在UI 上。
同時我們也加入了 MenuItems 屬性作為UI 上漢堡圖選單在做DataBinding 時的資料源。 針對MenuItems 的預設值, 我們也加入這次會用到的 三個功能選項, 分別是 " 地圖瀏覽模式", "列表瀏覽模式" 以及"關於紫外線指數" 。
準備好 MainPage 所需要的 ViewModel "MainViewModel" 後, 在 MainPage.cs 的程式碼中 Override OnNavigatedTo Methond, 並在其中 Create MainViewModel 物件, 設定為 roodGrid的 DataContext。
這時候按下 F5 執行, 一個簡單的漢堡圖功能選單就已經完成。
接下來我們透過 AdaptiveTrigger、 VisualState.Setters, 改變SplitView 的顯示模式, 讓這個UI 可以在不同大小的螢幕上做變化。
在MainPage.xaml 中, 加入 "WideState"、"MiddleStee" 及 "NarrowState" 三種ViewState。
這三個ViewState 的StateTriggers 都用 AdaptiveTrigger, 同時設定 MiniWindowWidth 分別為 1000、600 及 0
然後在ViewState.Setters 中設定 SplitView 的 DisplayMode、 IsPaneOpen 及 PaneBackground 屬性。 這時在按F5 執行App, 然後拖拉App 的寬度, 就可以看到 不同的顯示狀態。
接下來要實作各個選單功能的功能介面。
先在ViewModels 目錄下建立 UVMapViewModel Class , 加入會用到的 TaiwanUVData 屬性及 LoadData Method。
接下來在專案下來建立一個Views 資料夾, 分別新增UVMapView.xaml、UVDetailView、AboutView 三個 空白的XAML 頁面。
首先 在UVMapView.xaml 上新增 Title 跟 Map控制項。因為我們希望這頁的標題顯示一樣可以根據 螢幕大小來做不同版型變化, 因此 將 顯示 Title 的 TextBlock 控制項 titleText 及 subTitleText 放在 RelativePanel 中 , 同時設定 subTitleText 的位置在titleText的上方 (RelativePanel.Above="titleText")
要使用MapControl 前先要取得 微軟Bing Map Services 的Token, 取得方式可以到 Bing Map 開發者中心 https://www.bing.com/dev/
點選Maps, 或者直接到 https://www.bingmapsportal.com/
登入後在 My Account 功能底下選擇 Create or View Keys,
再選擇Create a New Key。
最後填入你的App 名稱, Application Type 後就可以取得Bing Map 的授權 Key 值。
目前只要是給一般非企業使用者的免費UWP , 都可以每天享有最多 50000 次免費的 地圖資料Access。 詳細的使用規定可以參考 https://www.microsoft.com/maps/Licensing/licensing.aspx 。
再來因為紫外線即時監測資料所取得的經緯度是以 TWD97 的度分秒格式顯示, 而Bing Map 使用的是 WGS84 。 TWD97 跟WGS84 的誤差不大, 約數十公分, 因此我們可以直接使用, 只要把度分秒格式轉為 對應數字即可。
為了方面我們在Utils 資料夾下在增加一個GeoCoordinateTransformer Class, 並撰寫度分秒轉換的method。
這個頁面我們希望能將取得的資料顯示在地圖上, 因此加入 AddUVDataPinPoint 及 AddPushpin 兩個Method
另外我們希望能追蹤使用者看了這個頁面看了多久, 因此我們建立一個 Utils 資料夾, 在新增一個 BasicInfo 的物件協助取得 使用者及裝置的ID。 BasicInfo.cs 的內容如下:
這邊要注意的是 由於取得 使用者相關資料 跟 裝置ID 是透過 Windows.System.Profile 命名空間下的 HardewareIndentification 及 Windows.System.UserProfile 命名空間下的 UserInfomation 兩個Class。 而這兩個命名空間僅支援 Desktop 及 Mobile 版本的裝置 (如IoT 裝置就不能使用這兩個功能) 。 如一開始所提的, 這部分API 需要透過 Extension 來使用, 因此我們必須在專案中加入 Windows Desktop Extensions for the UWP 及 Windows Mobile Extensions for the UWP。
並且在呼叫要透過 Windows.Foundation.Metadata.ApiInformation.IsTypePresent 先檢查該API 是否存在。
最後在這頁我們加上預設地圖顯示的經緯度, 地圖顯示精細度 (ZoomLevel)。
在追蹤使用者瀏覽該頁面多久的部分, 我們透過Application Insight SDK 中的 TelemetryClient、PageViewTelemetry 來記錄使用者瀏覽該頁面瀏覽多久。
在開發過程中我們加入了 TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = true; 這樣可以讓Azure Portal 較快顯示所取得的App 分析資料。
接下來為了讓漢堡圖選單點選後可以瀏覽到指定頁面, 編輯 MainViewModel.cs 程式。
修改 InitialMenuItems、InitialMenuItems method 並加入 Navigate method
這時在按 F5 執行, 就可以看到 我們已經成功讀取地圖, 並將全台紫外線指數顯示在地圖上了。
接下來一樣我們透過 VisualState 及 VisualState.Setters 設定不同顯示寬度大小時 版面的變化
再次按下F5, 這時 "全台紫外線指數" 的標題文字格式已經可以隨著版面大小變化。
接下來開發列表模式的頁面。
首先在 ViewModels 資料夾下建立 UVDetailViewModel Class, 其內容如下:
然後編輯先前建立好的 UVDetailView.xaml
在修改 UVDetailView.xaml.cs 如下 :
在這頁我們一樣透過Application Insight SDK 來追蹤使用者瀏覽這個頁面的時間跟次數。
在按 F5 , 就可以看到執行成果。
接下來我們修改 AboutView.xaml, 透過WebView 讓此頁顯示Wiki上有關紫外線指數的介紹。
從Windows Phone 7 時代開始, 一直到Windows/Windows Phone 8.1 及現在的 Windows 10, 動態磚的顯示方式一直是受使用者喜愛也是Windows Store App 很大的一個特色。
設定App 的動態磚有兩種常用的方式, 一種是透過Background Task, 在固定時間週期 (eg. 每小時or 每天) 去更新動態磚, 另一種方式是在App 打開時順邊也更新動態磚。
在這邊為了簡化程式, 我們先用第二種方式。
在MainPage.xaml.cs 程式中加入 UpdateTile method, 並且在程式一開始就更新動態磚。
UWP 的動態磚顯示方是有多種格式, 這裡我們用的是 TileSquare150x150Block。
更多的格式可以在這邊找到。
然後按F5 執行後, 把App 釘選到開始畫面後, 就可以看到動態磚的顯示。
最後為了把App 使用狀況透過Application Insight 收集, 要設定一下 Application Insights。
這樣日後隨時都可以很方便的打開Applicatoin Insight 服務, 查看App 使用的狀況或是 Crash 的狀況。
以下是一些Application Insight 上的App 使用狀態分析介面 :
Applicatoin Insight App 分析報表 - 應用程式概觀
Applicatoin Insight App 分析報表 - 自訂分析圖表
Applicatoin Insight App 分析報表 - 使用者停留頁面分析
如先前所說明的, 目前Application Insight 提供每個月5百萬免費的資料點, 對於一般中小型的App 應該夠用。
相關定價資料可以參考 https://azure.microsoft.com/zh-tw/pricing/details/application-insights/
以上我們透過一個範例很快介紹UWA 的幾個主要核心概念,包括漢堡圖選單、可適性UI、App 使用狀態追蹤及動態磚。
為了精簡範例,我們捨棄使用一些熱門的第三方元件如 JSON.Net, MVVM Light 等,也避免太多繼承架構。如在實際的專案中,仍建議評估使用一些熱門的第三方資料處理及程式框架工具。
# 9/22 Update: 本範例專案發布在GitHub https://github.com/Herman-Wu/TaiwanUV
[其他學習資源]
A Developer's Guide to Windows 10
Windows 市集應用程式(Windows Store app) 討論區
[參考資料]
Guide to Universal Windows Platform (UWP) apps
Implementing an Awesome Hamburger Button with XAML’s new SplitView control in Windows 10
Building adaptive layout in Windows 10 with RelativePanel and AdaptiveTrigger
Microsoft Application Insights: Top Six Features to Get a 360⁰ View of Your App
Application Insights: Exception Telemetry
How to update Live Tile in Universal Windows apps?
Segoe MDL2 Assets - Cheatsheet
[Windows 10] Extension SDK: 讓同一隻應用程式能在不同裝置上執行的秘密