連載
» 2014年01月10日 13時35分 公開

連載:Windowsストア・アプリ開発入門:第9回 効果的に情報を提示する (3/7)

[山本康彦(http://www.bluewatersoft.jp/),BluewaterSoft]

ライブタイルを作る

 さまざまな情報提示手段の中から、今回はローカル通知のライブタイルとセカンダリタイルを作ってみよう。まずは、ライブタイルから。

ライブタイルのスペックを考える

 本連載で作ってきたアプリは、2つのRSSフィードをダウンロードしている。それぞれに含まれている記事タイトルの中から、新しいものをタイルに表示することにしよう。

 ローカル通知のライブタイルでは、いつ処理をして/どんな内容を/どのように見せるかを決めておく。今回は以下のようにしよう。

  • 通知の処理をいつ行うか?⇒RSSフィードをダウンロードしたとき
  • 通知する内容は?⇒フィードのタイトル、および、記事のタイトルを新しいものから可能な限り
  • どのように見せるか?⇒ワイドタイル(310×150ピクセル)と大タイル(310×310ピクセル)に以下のテンプレートを使って表示する

 ライブタイルの外観は、タイル テンプレート カタログから選択する。使用する画像も決めておかねばならない。次のようにしよう。

ワイドタイル

 ワイドタイルにはTileWide310x150PeekImage02テンプレートを使う。画像は、既定のワイドタイル用として第3回で作成したものをそのまま使おう。

ワイドタイルの外観 ワイドタイルの外観
このテンプレートでは、画像のタイルとテキストのタイルが交互に表示される。小さいロゴは、第3回でマニフェストに設定したものが自動的に使われる。

大タイル

 大タイルにはTileSquare310x310ImageAndTextOverlay03テンプレートを使う。画像は、既定の大タイル用に第3回で作成したものをそのまま使おう。

大タイルの外観 大タイルの外観
テキストに明るい色を指定すると、画像はシステムによって自動的に暗く補正される。小さいロゴは、第3回でマニフェストに設定したものが自動的に使われる。

ライブタイルを実装する

 ライブタイルの通知を登録するクラスを作り、それを呼び出すメソッドを書き、そのメソッドを呼び出すイベントを追加する。

ライブタイルの通知を登録するクラス

 まず、ライブタイルの通知を登録するクラスを作る。プロジェクトに「Tile」というフォルダーを作り、そこに新しいクラスを「LiveTile.cs」というファイル名で作成する。

 ライブタイルに必要な情報は、フィードのタイトルと記事のタイトルだけである。その情報を表すクラスから作る(次のコード)。

internal class LiveTileData
{
  public string FeedTitle{get;set;}  // フィードのタイトル
  public IList<string> ArticleTitles = new List<string>(); // 記事のタイトルのコレクション
}

「LiveTile.cs」ファイルにLiveTileDataクラスを追加する(C#)
これはライブタイルの作成に必要な情報を表すクラスだ。

 呼び出す側では、このLiveTileDataクラスのコレクションを用意して渡すようにしよう。すると、ライブタイルの通知を登録するUpdateLiveTileメソッドは、LiveTileクラスを作って次のように書ける。

internal static class LiveTile
{
  public static void UpdateLiveTile(IEnumerable<LiveTileData> tileDataCollection)
  {
    // TileUpdateManagerクラスからTileUpdaterオブジェクトを取得する
    var tileUpdater = Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForApplication();

    tileUpdater.EnableNotificationQueueForWide310x150(true);   // ワイドタイル用のキューを有効化
    tileUpdater.EnableNotificationQueueForSquare310x310(true); // 大タイル用のキューを有効化
    tileUpdater.Clear(); // 既存の通知があるなら削除

    foreach (var tileData in tileDataCollection)
    {
      // 300×150と300×300のライブタイルのコンテンツを表すXmlDocumentを作る
      var wideXml = CreateWideTile(tileData);   // このメソッドについては後述する
      var largeXml = CreateLargeTile(tileData); // このメソッドについては後述する

      // largeXmlの中にwideXmlをマージしてXMLを完成させる
      Windows.Data.Xml.Dom.IXmlNode node = largeXml.ImportNode(wideXml.GetElementsByTagName("binding").Item(0), true);
      largeXml.GetElementsByTagName("visual").Item(0).AppendChild(node);

      // ライブタイル通知を生成し、TileUpdaterオブジェクトを通じて登録する
      var tileNotification = new Windows.UI.Notifications.TileNotification(largeXml);
      tileUpdater.Update(tileNotification);
    }
  }
  ……省略……
}

「LiveTile.cs」ファイルにLiveTileクラスを追加しUpdateLiveTileメソッドを記述する(C#)
ライブタイルを出すにはこのようなステップを踏む。
1. TileUpdateManagerクラスからTileUpdaterオブジェクトを取得する
2. タイルを管理するキューを有効化する。既存のタイルがある場合は、不要なものを削除する
3. ライブタイルのコンテンツをXmlDocumentオブジェクトとして作成する
4. XmlDocumentオブジェクトからタイル通知オブジェクトを生成し、それをキューに登録する

 ここで面倒なのが、ライブタイルのコンテンツをXmlDocumentオブジェクト(上記コード中のwideXml変数とlargeXml変数)として作成するコードだ。XMLをハードコーディングするのではなく、システムからXMLのテンプレートを取得してそれを加工することが推奨されている。ワイドタイルと大タイルのXmlDocumentオブジェクトを作るメソッドは次のようになる。

private static Windows.Data.Xml.Dom.XmlDocument CreateWideTile(LiveTileData tileData)
{
  // TileWide310x150PeekImage02
  // このテンプレートは次のようなXMLになっている(実際には値は入っていない)
  // 下線の部分に実際の値をセットする
  /*
    <tile>
      <visual version="2">
        <binding template="TileWide310x150PeekImage02" fallback="TileWidePeekImage02">
          <image id="1" src="image1.png" alt="alt text"/>
          <text id="1">Text Field 1 (larger text)</text>
          <text id="2">Text Field 2</text>
          <text id="3">Text Field 3</text>
          <text id="4">Text Field 4</text>
          <text id="5">Text Field 5</text>
        </binding>
      </visual>
    </tile>
  */

  // テンプレートを取得する
  Windows.Data.Xml.Dom.XmlDocument tileXml
    = Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(
              Windows.UI.Notifications.TileTemplateType.TileWide310x150PeekImage02);

  // <image>タグの属性をセットする
  Windows.Data.Xml.Dom.XmlNodeList tileImageAttributes = tileXml.GetElementsByTagName("image");
  ((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/WideLogo.png");
  ((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("alt", "@IT RSS Reader");

  // <text>タグ(属性id=1〜5)を順にセットする
  int index = 0;
  tileXml.GetElementsByTagName("text")[index++].InnerText = tileData.FeedTitle;
  foreach (var articleTitle in tileData.ArticleTitles)
  {
    tileXml.GetElementsByTagName("text")[index++].InnerText = articleTitle;
    if (index > 4)
      break;
  }

  return tileXml;
}

ワイドタイル用のXmlDocumentオブジェクトを作成するCreateWideTileメソッド(C#)
TileUpdateManagerオブジェクトからテンプレートを取得し、必要な値をセットする。XMLのツリー構造を操作するのが少々面倒である。

private static Windows.Data.Xml.Dom.XmlDocument CreateLargeTile(LiveTileData tileData)
{
  // TileSquare310x310ImageAndTextOverlay03
  // このテンプレートは次のようなXMLになっている(実際には値は入っていない)
  // 下線の部分に実際の値をセットする
  /*
    <tile>
      <visual version="2">
        <binding template="TileSquare310x310ImageAndTextOverlay03">
          <image id="1" src="image1.png" alt="alt text"/>
          <text id="1">Text Field 1 (larger text)</text>
          <text id="2">Text Field 2</text>
          <text id="3">Text Field 3</text>
          <text id="4">Text Field 4</text>
        </binding>
      </visual>
    </tile>
  */

  // テンプレートを取得する
  Windows.Data.Xml.Dom.XmlDocument tileXml
    = Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(
              Windows.UI.Notifications.TileTemplateType.TileSquare310x310ImageAndTextOverlay03);

  // <image>タグの属性をセットする
  Windows.Data.Xml.Dom.XmlNodeList tileImageAttributes = tileXml.GetElementsByTagName("image");
  ((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/LargeLogo.png");
  ((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("alt", "@IT RSS Reader");

  // <text>タグ(属性id=1〜4)を順にセットする
  int index = 0;
  tileXml.GetElementsByTagName("text")[index++].InnerText = "¥n" + tileData.FeedTitle;
  foreach (var articleTitle in tileData.ArticleTitles)
  {
    tileXml.GetElementsByTagName("text")[index++].InnerText = articleTitle;
    if (index > 3)
      break;
  }

  return tileXml;
}

大タイル用のXmlDocumentオブジェクトを作成するCreateLargeTileメソッド(C#)
TileUpdateManagerオブジェクトからテンプレートを取得し、必要な値をセットする。

 これら2つのメソッドで作ったXmlDocumentオブジェクトを、UpdateLiveTileメソッドの中で1つにまとめてから、ライブタイルの通知を生成する。マージした後のXMLの例を次に示しておく。

<tile>
  <visual version="2">
    <binding template="TileSquare310x310ImageAndTextOverlay03">
      <image id="1" src="ms-appx:///Assets/LargeLogo.png" alt="@IT RSS Reader"/>
      <text id="1">¥r¥n@IT Insider.NETフォーラム</text>
      <text id="2">ファイルアクセスの便利機能を使うには?</text>
      <text id="3">第4回 ルーティングの設定/検証/例外処理</text>
      <text id="4">第8回 入力されたデータを保存する</text>
    </binding>
    <binding template="TileWide310x150PeekImage02" fallback="TileWidePeekImage02">
      <image id="1" src="ms-appx:///Assets/WideLogo.png" alt="@IT RSS Reader"/>
      <text id="1">@IT Insider.NETフォーラム</text>
      <text id="2">ファイルアクセスの便利機能を使うには?</text>
      <text id="3">第4回 ルーティングの設定/検証/例外処理</text>
      <text id="4">第8回 入力されたデータを保存する</text>
      <text id="5">アプリのモダン化とその技術としての.NET Framework</text>
    </binding>
  </visual>
</tile>


マージ後のXmlDocumentの内容の例(XML)
XmlDocumentクラスのGetXmlメソッドを使って取得したXMLに、読みやすいように改行とインデントを入れてある。
上の2つのメソッド内のコメントに載せておいたテンプレートのXMLと見比べてみてほしい。両方の<binding>要素が入っている。
XMLを扱うコードは煩雑に見えるが、やっていることは値を当てはめて合体させているだけである。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。