[開發] 關於Universal App開發二三事

作者: hoyunxian (WildDagger)   2014-05-31 11:22:47
剛剛看到版上有人在問Universal App,這邊就稍微講一下自己開發的經驗。
首先,是關於Universal App的架構,它會分成三個專案:
(專案名).Shared ←這是共用專案
(專案名).Windows ←這是Windows 8.1用的專案
(專案名).WindowsPhone ←這是Windows Phone 8.1用的專案
三者間的關係基本上是:
共用的東西(如程式庫、頁面與圖片)放在Shared專案中
如果頁面用到了只有某平台才合適的APP,或者是頁面的設計只適合某個平台
又或者是某些圖片是專門針對某個平台(例如APP的Logo等圖案)
那就把這些檔案放在該平台的專案
因此剛開一個Universal APP的時候,
你會看到Shared裡面有App.xaml與App.xaml.cs
然後另外兩個專案底下各一個
MainPage.xaml、MainPage.xaml.cs、Package.appxmanifest
雖然說是三個專案,但你要是開程式碼出來,會發現三個專案用的namespace是一樣的。
要測試的時候,只要更改啟始專案就可以同時測試Win8.1/WP8.1的專案
(Visual Studio Express for Windows Update 2已經內建WP8.1模擬器,
再加上未來所有WP8手機都可以升級WP8.1的情況下,
真的建議各位可以準備把WP8 SDK移除掉,除非你放不下WP7使用者)
另外要特別注意的是,當你準備打包的時候一定要看清楚有沒有選對起始專案,
因為選錯的話可能會出狀況(後述)
發揮Universal APP最大效用的方法,
就是把一些共用的東西通通擺到Shared裡面
比方說,如果你已經確定App的背景要用純色或者是圖片
那麼你就可以把App的背景筆刷設定成一個資源放進App.xaml裡面
又或者,你使用資料繫結的時候使用的範本、值轉換器也可以全放到Shared專案裡面
這樣就不需要再去兩邊都開一個檔去處理值轉換了
(有去載我那個核能APP就會看到資料呈現上幾乎一模一樣,
那就是因為我把資料呈現範本也直接擺在Shared專案中了)
不過Shared專案有個十分嚴重的缺點,
就是Shared專案本身不支援NuGet與參考程式庫這兩個功能
因此如果要在Shared專案裡面使用程式庫的話,
Windows專案和Windows Phone專案都必須安裝同樣的程式庫,
不然Shared裡面就不能用那些程式庫了
(估計是因為Shared參照的其實是設定為起始專案的那個專案的功能)
而另外一點必須注意的,是當你設定不同的起始專案時,系統變數會不一樣
會造成部分API被註解起來,有可能會造成編譯錯誤
比方說,你的起始專案設定成Windows,但是你卻要編譯Windows Phone的專案
那麼可能會發生Windows Phone找不到Win8專用API(還不少,比方說設定窗格WP就沒有)
於是會跳出「找不到API無法編譯」的錯誤
所以記得起始專案與編譯的專案要設成一樣
(設定的方法是在專案上面按右鍵選擇「設定為起始專案」,
或者是在啟動測試的下拉選單中選擇起始專案)
此外當你在Shared專案新增檔案時,
會發現裡面沒有設定窗格、分享目標視窗、搜尋結果等Win8專用的頁面
甚至連程式頁面也只有空白頁可以選
就是因為Shared專案是兩個專案的交集,所以能新增的也必定是兩者的交集
同樣的,在寫Code的時候,也要注意Win8.1能用的WP8.1不見得能用(反過來一樣)
雖然你寫的程式碼是正確的,但是你的平台不支援,那一樣會報錯
要避免這個狀況,就要善用系統變數「WINDOWS_PHONE_APP」
以及C#內建的語法「#if......#else......#endif」
簡單來說,#if......#else......#endif的語法跟if/else相同
都是條件符合就執行,否則就執行另一個區塊的語法
不同的是這個加上#號的程式碼是給編譯器看的
打開App.xaml.cs就馬上可以看到一個#if WINDOWS_PHONE_APP的語法
這邊是說「當WINDOWS_PHONE_APP系統變數設定為true的時候執行下列程式碼」
而Windows專案預設該變數是false,WindowsPhone專案則是true
因此,設定窗格之類只有Win8.1才有的功能,
可以在其前後加上「#if !WINDOWS_PHONE_APP」與「#endif」的指令
這樣子編譯器碰到的時候,就會自動跳過去不編譯區塊內的程式碼
也就不會因此發生找不到API的錯誤了
之前看微軟的資料,未來Universal APP還會加上XBOX One等平台
到時應該會變得更多樣化吧......
作者: Famicom (ファミコン)   2014-05-31 11:40:00
加上XBOne的話...正式的Youtube app有望了嗎(誤)
作者: hungys (hungys)   2014-05-31 11:52:00
樓上怎麼會有這種錯覺O_o
作者: felaray (傲嬌魚)   2014-05-31 12:06:00
推...說到前幾天我要上傳影片,手機版網頁還真不知道怎麼傳原來要兩個專案都Nuget以後Shared才能使用呀..呆會來試試
作者: Obama19 (^_^)   2014-05-31 12:32:00
不支援reference很正常阿 兩個平台api又不是全互通
作者: BenShiuan (璇璇)   2014-05-31 12:44:00
為什麼 VB.net 沒有通用應用程式 =..=
作者: Kelunyang (可倫)   2014-05-31 13:08:00
一堆 nuget 都不支援,從頭開發起Orz兩個都 nuget 的替代方案也可以用 portable class library 啦
作者: abian5566 (ˊ.ω.ˋ)   2014-05-31 16:10:00
實用
作者: Severine (賽非茵)   2014-05-31 21:03:00
謝謝H大~整天下來總算有點概念>< 現在嘗試改中樞範例讓他讀到我的Json...阿扁大大也是改用Universal來支援RT的嗎?開始幻想在XB1也能支援MoPTT了~~~
作者: TsaoCCFGOGO (書唸累時,就算數學吧)   2014-05-31 22:34:00
腦袋還不太清楚,先推,有空再慢慢理解。
作者: Xp3310 (Nokia)   2014-06-09 15:39:00
大推阿阿阿

Links booklink

Contact Us: admin [ a t ] ucptt.com