実際に開発していくに当たっては、WindowsとPhoneの使い分けが必要な場面が出てくる。気が付いた点をいくつか挙げておこう。
編集コンテキスト
上で作ったユニバーサルプロジェクトの「App.xaml.cs」ファイルを開いてみる。共有プロジェクトに入っているファイルだから、Windows用にコンパイルされたりPhone用にコンパイルされたりする。編集しているときには、どちらのコンテキストで見えているのだろうか? エディターの上にドロップダウンが追加されていて、現在のコンテキストはそこに表示されており、簡単に切り替えられる(次の画像)。
#ifディレクティブ
テンプレートでは共有プロジェクトに「Common」フォルダーがあるが、果たしてWindowsとPhoneでは完全に同じにできるものなのだろうか? 例えば「Common」フォルダーの「NavigationHelper.cs」ファイルを開いてみよう。そのコンストラクターには次のような記述がある(次の画像とコード)。
public NavigationHelper(Page page)
{
this.Page = page;
this.Page.Loaded += (sender, e) =>
{
<b>#if WINDOWS_PHONE_APP</b>
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
<b>#else</b>
……省略……
Phoneのプロジェクトには「WINDOWS_PHONE_APP」という条件付きコンパイルシンボルが定義されていて、#ifディレクティブを使ってPhoneに特有のコードとWindowsに特有のコードとを切り分けている。ちなみに上のコードでは、Phoneの場合だけ、Windows Phoneの[戻る]ハードウェアボタンのイベントハンドラーを設定している。
generic.xaml
上の話から、「なるほど、それなら」と思うだろう。「画面のXAMLファイルをWindows用のプロジェクトから共有プロジェクトに持っていっても、[戻る]ボタンはちゃんと切り分けできるはずだ」と。
ところが実際にやってみると、[戻る]ボタンのスタイル定義がPhoneのプロジェクトには存在せず、ランタイムエラーになってしまう。これは、「generic.xaml」ファイルがWindowsとPhoneで別々に定義されているためだ*13。
また、「generic.xaml」ファイルの相違を克服したとしても、やはりWindowsとPhoneではUIのデザインが違ってくる(特に画面のヘッダー部分)。そういったことから、画面のXAMLファイルを共有プロジェクトに置くのはお勧めできない。開発上の戦略としては、画面定義はWindowsとPhoneに置くが、できるだけロジックを含めない「薄い」UI層にすること。そして、WindowsとPhoneでほとんど変わらない画面は、ヘッダー部分を除いた部分をユーザーコントロールとして共有プロジェクトに置くのがよいだろう。
*13 「generic.xaml」ファイルは、筆者の環境では次のフォルダーにインストールされていた。
Windows用: \Program Files (x86)\Windows Kits\8.1\Include\Winrt\Xaml\Design\
Phone用: \Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design\
双方の「generic.xaml」ファイルには相違があり、例えば「HeaderTextBlockStyle」の定義はどちらにもあるが、定義内容が違う。あるいは本文にも書いたように、[戻る]ボタンのスタイル(=NavigationBackButtonNormalStyle)はWindows用の「generic.xaml」ファイルだけに定義されている。
パーシャルクラス
#ifディレクティブによるソースコードの切り替えは手軽だが、その分コードが汚くなっていく。そこで、プラットフォームごとに異なるコードがある程度の量になったら、そのコードはメソッドとして切り出して、Windows用かPhone用のプロジェクトにパーシャルクラスとして配置するとよい。
最後に、マイクロソフトのクラウド側の対応を簡単に紹介しておく。クラウドのサポートがあって初めて、エンドユーザーにとってのユニバーサルWindowsアプリとなるのである。
WindowsアプリとPhoneアプリでAppIDが同じものは、両方のストアで同じアプリとして扱われる。一方で購入すれば、他方でもその権利が有効となる。
Buildの資料によれば、開発者がAppIDを同じにすればWindowsとPhoneのアプリが同一のアプリとして扱われるとのことなのだが、まだ実際に試せておらず詳細は不明である。今まではアプリの名前を登録した時点でAppIDが確定していたので、後からAppIDをそろえられるようになるのかどうか、定かではない。
なお、ユニバーサルWindowsアプリとは関係ないが、エンドユーザーが記入してくれたレビューに対して開発者からレスポンスを書き込めるようになることがBuildの複数のセッションで発表されていた。
これまで、Windowsストアアプリがローミング用のフォルダーに設定やデータを書き込むと、自動的にそのユーザーの全てのWindows 8.xデバイスにローミングされていた。これは、Windows 8.xとOneDrive協調によって実現している。
Windows Phone 8.1もこのローミングの仕組みを備え、Windows Runtimeアプリからローミングが利用できるようになった。そしてAppIDを合わせておけば、WindowsとPhoneの間でローミングされるのだ(次の図)。
プッシュ通知も同様だ。例えばライブタイルをプッシュ通知で更新しようとすると、これまではWindowsとPhoneでその作り方が違うだけでなく、通知自体もWindowsとPhoneとで別々に送信しなければならなかった。これもAppIDが同じなら、WindowsとPhoneで合わせて1回の通知を送るだけでよくなる。
ユニバーサルWindowsアプリの特徴とその3要素について、駆け足で見てきた。
最後に筆者の感想を述べさせてもらえば、「Windowsストアアプリの新規開発は、ユニバーサルWindowsアプリにしない理由がない」ということだ。
PhoneのWindows Runtimeアプリを新規開発するときも同じだ。未来に他方のアプリを開発する可能性がそれほど高くなくとも、ユニバーサルWindowsアプリにしておくコストはとても低いので、わずかな可能性であっても十分に見合うはずである。
これからの新規開発はユニバーサルWindowsアプリで!
5月29日(木)〜5月30日(金)、本稿で解説したような、マイクロソフトの最新技術情報を日本語で日本人向けに提供するカンファレンス「de:code」が日本マイクロソフト主催で開催される。このカンファレンスは、米国時間で4月2〜4日に開催された「Build 2014」の内容をベースにした上で、日本向けのプラスアルファを含めたものになる。詳しい内容は、リンク先を参照されたい。
Copyright© Digital Advantage Corp. All Rights Reserved.