Windowsフォーム開発者のためのWindows 10 UWPアプリ開発入門(後編):特集:UWPとは何か(5/5 ページ)
本稿ではデータバインド/非同期処理/ファイル操作/クラウド型アーキテクチャという、Windowsフォームとは異なるUWPプログラミングの特徴を取り上げる。
6. Webサービスの利用〜「クラウド型」アーキテクチャ
UWPアプリでは、上記のようにファイルアクセスが制限されていたり、あるいはコードから印刷を自動的に開始できなかったりする。また、ADO.NETのようなデータベースサーバーにアクセスする機能も用意されていない。前述したように、エンドユーザーのプライバシーやセキュリティを侵害するようなアプリを作りにくくしてあるのだ。
そうなると、データベースを使う業務アプリはどうやって作ればよいのだろう? セーブポイントやハイスコアを記録するゲームアプリはどうすればいいのだろう? その答えはマイクロソフトが最近よく口にしている「クラウドファースト」という語にある。業務アプリのデータベースや基幹業務のロジック、ゲームアプリのスコアデータなどは、クラウドに置くのである。そして、UWPアプリは、クラウドに対するフロントエンドとして設計するのだ。筆者はこれを「クラウド型」システムアーキテクチャと呼んでいる(次の図)。
「クラウド型」システムアーキテクチャ
筆者の造語である。すでに適切な呼び名があるかもしれない。
UWPは、このようなアーキテクチャを前提として設計されている。
基幹サーバー群と一般のクライアントとはネットワークを分離し、クライアントとサーバーの間のやり取りには必ずWebサービス(=Web API)を介するようにする。クライアントのアプリはWebサービスのフロントエンドとして作成し、業務アプリでは情報の取得は必要最小限にとどめる。データを全件取得するといった「危険な」Webサービスを作らない限り、クライアントがサイバー攻撃を受けたとしても重要な情報が大量に漏えいするリスクは極めて低くなるだろう。また、重要な情報の印刷(例えばDM封筒の大量印刷)などのタスクも基幹ネットワーク側の物理的に隔離された場所で行うようにする。
このような構成にすることにはもう一つのメリットもある。デバイスをまたいだユーザーエクスペリエンスを提供できるのだ。例えば自宅のPCで読んでいた小説や遊んでいたゲームの続きを、モバイルデバイスで行えるのである。逆にいえば、「モバイルファースト」時代に対応するアプリを作るには「クラウドファースト」なシステムアーキテクチャが必要になるのだ。
クラウドのフロントエンドとしてのUWPアプリは、クラウドと主にHTTPプロトコルで通信する。すなわち、Web APIの利用がメインになる。HTTPのリクエストとして処理をクラウドに要求し、処理結果をJSONフォーマットやXMLフォーマットで受け取るのである。そのため、UWPアプリのAPIには、JSONフォーマットやXMLフォーマットを扱うものが用意されている。さらには、XMLフォーマットの一種であるRSSフィードに特化した名前空間(Windows.Web.Syndication名前空間)などもあるのだ。
ここでは、JSONフォーマットで結果を返してくるWeb APIを利用するUWPアプリの作り方を紹介しよう(別途公開のサンプルでは、「S5_WebAPI」ディレクトリの下にある「S5_02_Uwp」プロジェクト)。
UWPアプリで「現在の天気」Web APIを利用する
Web API側の構築から説明していたのでは紙面が足りないので、ここでは既存のWeb APIを利用する。現在では、オープンなWeb API(誰でも使えるWeb API)が数多く公開されている。その中から、OpenWeatherMap社のWeather APIを使わせてもらおう。このWebサービスは、特定の場所の天気を教えてくれるものだ。
例えば、東京の現在の天気を問い合わせるコードは次のようになる。
private async void GetWeatherDataAsync()
{
// 例:東京の現在の天気を、摂氏で取得する
var url
= "http://api.openweathermap.org/data/2.5/weather?q=Tokyo,jp&units=metric";
// Web APIを呼び出して、結果をJSONデータで得る
var hc = new Windows.Web.Http.HttpClient();
string jsonString = await hc.GetStringAsync(new Uri(url));
// JSONデータから必要なデータを取り出して、UIのデータコンテキストにセットする
rootGrid.DataContext = (new WeatherData(jsonString)).Data;
}
最後の行に出てくる「WeatherData」クラスについては次で説明する。また、画面には「rootGrid」という名前のGridコントロールが配置してある(後述)。
ご覧のように、Web APIを呼び出して結果をJSONフォーマットの文字列として受け取るまでのコードは、実に簡単だ(認証が必要な場合は少々面倒になる)。
なお、ローカル変数「url」の中の「q=Tokyo,jp」はお分かりだろう。天気を知りたい場所を指定するパラメーターである。そして、「units=metric」は温度の単位として摂氏を指定するパラメーターだ。
次に、JSONフォーマットの文字列として受け取った結果を、画面に表示できるデータへと変換する。それにはWindows.Data.Json名前空間のJsonObjectクラスが利用できる。例えば、JSONフォーマットの文字列を匿名型のデータに変換するコードは、次のクラスのように書ける。
public class WeatherData
{
// 画面に表示するための匿名型データ
public object Data { get; private set; }
// コンストラクターはJSONフォーマットの文字列を受け付けられるようにする
public WeatherData() // XAMLにバインドするため引数なしのコンストラクターも必要
{
}
public WeatherData(string json)
{
LoadData(json);
}
// JSONフォーマットの文字列から匿名型データを作る
private void LoadData(string json)
{
// JSONフォーマットの文字列からJsonObjectオブジェクトを作る
var data = new Windows.Data.Json.JsonObject();
bool success
= Windows.Data.Json.JsonObject.TryParse(json, out data);
if (success)
{
// JsonObjectオブジェクトから画面表示に必要なデータを取り出し、
// 匿名型のオブジェクトに詰め込む
Windows.Data.Json.JsonObject weather
= data.GetNamedArray("weather", null)?.GetObjectAt(0);
Windows.Data.Json.JsonObject main
= data.GetNamedObject("main", null);
string iconId
= weather?.GetNamedString("icon", string.Empty);
Data = new
{
Main = weather?.GetNamedString("main", "(不明)"),
Temp = main?.GetNamedNumber("temp", -999),
TempMin = main?.GetNamedNumber("temp_min", -999),
TempMax = main?.GetNamedNumber("temp_max", -999),
Place = data.GetNamedString("name", "(不明)"),
IconUrl = iconId != null
? $"http://openweathermap.org/img/w/{iconId}.png"
: null,
};
}
}
}
JSONフォーマットの文字列を解析してJsonObjectオブジェクトを生成するには、JsonObjectクラスのTryParseメソッドを使う。
JsonObjectオブジェクトから必要なデータを取り出すコードは、少々煩雑になる(さすがにJsonObjectオブジェクトをそのままデータバインドしても上手くいかないようだ)。
太字にした部分が、画面に表示するプロパティである。
なお、ここで匿名型を使っているのは、データのためのクラス定義を(紙面の都合で)書きたくなかったからである。コンパイル時に型の解決ができないため、データバインドには実行時バインディングしか使えない。
また、このコードではVisual Studio 2015から利用可能になったNull条件演算子と補間文字列(Interpolated Strings)を使っている。
あとは、次のコードのようにして画面にバインドすれば完成である。
<Grid x:Name="rootGrid" ……省略……>
……省略……
<TextBlock ……省略……>Weather at <Run
Text="{Binding Place}"/></TextBlock>
<StackPanel ……省略……>
……省略……
<Image Source="{Binding IconUrl}" ……省略…… />
<StackPanel ……省略……>
<TextBlock Text="天候"/>
<TextBlock TextAlignment="Right"
Text="{Binding Main}"/>
</StackPanel>
<StackPanel ……省略……>
<TextBlock Text="現在気温" />
<TextBlock TextAlignment="Right"><Run
Text="{Binding Temp}"/>℃</TextBlock>
</StackPanel>
<StackPanel ……省略……>
<TextBlock Text="最低気温" />
<TextBlock TextAlignment="Right"><Run
Text="{Binding TempMin}"/>℃</TextBlock>
</StackPanel>
<StackPanel ……省略……>
<TextBlock Text="最高気温" />
<TextBlock TextAlignment="Right"><Run
Text="{Binding TempMax}"/>℃</TextBlock>
</StackPanel>
</StackPanel>
……省略……
</Grid>
太字の部分がバインドしているプロパティ名である。
このGridコントロール(名前「rootGrid」)のDataContextプロパティには、前述したコード(「GetWeatherDataAsync」メソッド)で「WeatherData」クラスのオブジェクトがセットされる。DataContextプロパティの内容(=データコンテキスト)は、そのコントロールの中に配置したコントロール(この例ではTextBlockコントロールなど)にも引き継がれる。そのため、それぞれのコントロールではデータコンテキストを所与のものとして、その中のプロパティ名を指定するだけで目的のデータをバインドできるのである。
実行すると、次の画像のように東京の天気データが表示される。
このように、Web APIを利用するUWPアプリを簡単に作成できるのである。
【コラム】 Web APIの利用についてさらに詳しく!
UWPアプリでRSSフィードを取得する方法については、次の記事をご覧いただきたい。Windows 8.1時代の記事であるが、Windows 10でも基本は同じだ。
Web APIによっては、リクエストをJSONデータで送信することもある。そんなときは次の記事が参考になる。
- MSDN Blogs: HttpClient を使って JSON データを POST する方法
本文ではJsonObjectクラスを使ったが、JSONデータと同じ構造のデータクラスを定義した場合にはDataContractJsonSerializerクラス(System.Runtime.Serialization.Json名前空間)も使える。その場合はデータを詰め替える手間が不要になる。次の記事を参考にしてほしい。
- MSDN Blogs: WinRT APIでJSONフォーマットをデシリアライズする方法
- MSDN Blogs: WinRT APIでJSONフォーマットをデシリアライズする方法(続編)
まとめ
前/後編にわたって、Windowsフォーム開発者がUWPアプリ開発に挑戦するときの大きなギャップに重点を置いて解説してきたが、いかがだっただろうか? もちろんその他にも相違点は多々あるが、Windowsフォームのスキルを高めてきた皆さんなら大した障害にはならないだろう。
Windows 10にはさまざまなデバイスがある。PCの他に、スマートフォン/IoT Core/Xbox One(Windows 10へのアップデート)/Surface Hubが2015年のうちに登場するだろう。来年にはHoloLensが登場するといわれている。これら全てで動作するUWPアプリの世界に飛び込んでいこう!
【コラム】 UWPアプリ開発についてさらに詳しく!
UWPアプリに関する開発者向けの情報は、Windowsデベロッパーセンターに集約されている。次のページから始めるとよいだろう。
- Windows デベロッパー センター: Windows アプリの概要
なお、本稿執筆時点でのMSDNのAPIドキュメントは、日本語化が不完全である。古い情報が残っているし、Device family(Windows 10のどのデバイスで動作するか)が書かれていない。適宜、英語ページに切り替えて確認してほしい(URL中の「ja-jp」を「en-us」に変える)。
Microsoft Virtual Academy(MVA)には、学習に適したコンテンツがいくつもある。UWPアプリ開発を学ぶには、英語が苦にならないのであれば次のコースがベストだ。
また、連載「WinRT/Metro TIPS」ではUWPアプリ開発のTIPSを紹介していく。ぜひ参考にしてほしい。
Copyright© Digital Advantage Corp. All Rights Reserved.