April 2017

Volume 32 Number 4

UWP アプリ - UWP 用のホストされた Web アプリを作成する

Sagar Bhanudas Bhanudas

多くの開発者や企業は、自身の製品とサービスがすぐに見つかり、簡単にアクセスできるように、Web インターフェイスを作成します。これ以外のプラットフォームに、アプリ プラットフォームがあります。ネイティブ アプリは、Web アプリに比べてリッチな UX や機能を提供します。そこで、Project Westminster の出番です。これは、開発者が最新 Web サイトをネイティブ アプリに変換できるようにします。

Project Westminster ブリッジにより、Web 開発者は、既存のコードを利用しながら、レスポンシブ Web アプリをユニバーサル Windows プラットフォーム (UWP) 対応にすることができます。詳しくは、Windows Developer のブログ記事「Project Westminster の概要」(bit.ly/2jyhVQo、英語) を参照してください。「ブリッジ」の考え方は、既存の Web サイトのコードを再利用し、UWP 固有のコード用に層を追加することで、基盤となる Windows プラットフォームと Web アプリの統合ポイントを形成するというものです。前述のブログ記事では、UX の一貫性を確保するコーディング手法がいくつか紹介されています。

Web 開発者は、最新の Web アプリが Cortana などと連携するよう、どのように統合できるのでしょう。 両者に共通する JavaScript を利用するというのがその答えです。Windows は、JavaScript と Windows 名前空間を使用してアプリのフレームワーク機能 (Windows ランタイム API) を公開します。ここでは、結果として作成されたアプリを、「ホストされた Web アプリ」と呼びます。

今回は、独立系ソフトウェア ベンダー (ISV) やパートナーに協力して Project Westminster ツールを使ってアプリを UWP に移植した経験から学んだことを紹介します。Web アプリをプラットフォーム アプリとして実行しながら最適な UX を提供するよう Web アプリを調整する最善の方法を詳しく説明することに重点を置きます。

作業の開始

Project Westminster ツールを使うには、まず Web サイトを UWP に変換する必要があります (Channel 9 ビデオ「Project Westminster を使用してホストされた Web アプリを作成する (bit.ly/2jp4srs、英語) を参照してください)。

予備テストとして、Microsoft Edge ブラウザーで Web サイトをテストします。このテストでは、Web サイトが想定どおりにレンダリングされ、見た目に一貫性があることを確認します。そうすることで、Windows 機能のコーディング統合に着手する前にレンダリングの問題を特定して解決できます。

ほとんどの Web サイトには共通機能がいくつかあります。ユーザーが特定のタスクを完了できる機能 (フォームへの入力など) や、参考として任意の情報を取得できる機能 (マニュアルのダウンロードなど) がその例です。このようなシナリオでは、こうした共通機能が保たれ、新しく生成されるホストされた Web アプリと元の Web サイトのエクスペリエンスに一貫性があることが不可欠です。場合によっては、ユーザーの期待に添うように、コードのテスト、レビュー、リファクタリングが必要になることもあります。ここからはいくつか重要なシナリオを検討します。その中で、Project Westminster ツールと関連するコード ワークフローで作業を進める際に開発者が利用できるさまざまなクラスとオブジェクトを説明していきます。アプリを UWP に移植しながら、UX をリッチにし、アプリのエクスペリエンスを向上するために、プラットフォームのネイティブ機能をいくつか統合することを考えるのがお勧めです。以下は、アプリの開発者がよく実装する機能の一部です。

  • 連絡先
  • Cortana 統合
  • ライブ タイル
  • トースト通知
  • カメラとマイク
  • フォト ライブラリ
  • リッチ グラフィックスとメディア Windows ランタイム スタック
  • 他のアプリケーションとのコンテンツの共有

今回は UWP 機能の統合に注目します。たとえば、音声ベースのコマンドでアプリを起動する Cortana や、ユーザーに情報を配信するライブ タイルなどの機能です。つまり、UWP アプリのインフラストラクチャのサポートによって UX 全体を強化します。Windows 10 の開発者向け最新機能に関する Web ページ (bit.ly/2iKufs6、英語) では、さらなる統合の機会についての概要を簡単に説明しています。今回アプリに変換する Web ページは、以下の情報を提供します。

  1. Web アプリとしての機能
    1. ファイルのダウンロード
    2. セッション管理またはシングル サインオン
    3. 備え付けの戻るボタンで前のページに移動する機能
  2. UWP 統合機能
    1. ライブ タイル
    2. Cortana

アプリに期待されるエクスペリエンスを提供するために、移植とリファクタリングの最中にこうした機能を検討する必要があります。

ファイル ダウンロードのシナリオ

最近の Web アプリのほとんどは、さまざまなコンテンツのファイル ダウンロードを可能にしています。図 1 に示すように、ブラウザーの既定のファイル ダウンロード エクスペリエンスでは、ボタンやハイパーリンクをクリックすると、ブラウザーがダウンロードを開始し、また、(ほとんどの場合) ルートディレクトリ:\ユーザー\ユーザー名\ダウンロードに保存します。

既定のダウンロード エクスペリエンス

図 1 既定のダウンロード エクスペリエンス

これが行われるのは、ブラウザーが完全信頼の特権で実行されるネイティブ Win32 アプリケーションで、ファイルを [ダウンロード] フォルダーに直接書き込むためです。

ここで、同じシナリオを Web サイトがアプリ (具体的には WWAHost.exe) のコンテキストで実行されていて、ダウンロード ボタンをクリックした場合で考えてみましょう。何が起きるでしょう。 おそらく、何も起こりません。単純にコードが機能しないようにみえます。ボタンが反応しないか、ファイルのダウンロードが始まっても、保存先がわからないように思えます。

WWAHost.exe は Web サイト用のアプリ コンテナーで、ブラウザーと比べると、機能のサブセットしか含みません。この機能サブセットには、レンダリング機能 (ほとんどの場合 HTML による表示) や標準スクリプトの実行などが含まれます。

今回操作しているのはアプリです。アプリ環境では、ファイルのダウンロードを開発者が明示的にコーディングしなければなりません。そうしなければ、リモート ファイルは単なる URL にすぎません。アプリやコンテナーはリモート ファイル URL に対して何をするのかわかりません (特殊なデバッグ ツールを使って、内部で何が起きているかを調べることもできますが、ここでは詳しく扱いません)。

この種のシナリオを処理するには、適切な UWP API を呼び出す必要があります。これらの API は、ブラウザーを使用して Web サイトを実行しているときに、これらの機能を稼働させるコードと共存できます。図 2 に必要なコードを示します。

図 2 ファイル ダウンロードの JavaScript コード (サイズの大きいファイル)

(function() {
  if (typeof Windows !== 'undefined' &&
    typeof Windows.UI !== 'undefined' &&
    typeof Windows.ApplicationModel !== 'undefined') {
  function WinAppSaveFileBGDownloader() {
    // This condition is only true when running inside an app.
    // The else condition is effective when running inside browsers.
    // This function uses the Background Downloader class to download a file.
    // This is useful when downloading a file more than 50MB. 
    // Downloads continue even after the app is suspended/closed.
    if (typeof Windows !== 'undefined' &&
      typeof Windows.UI !== 'undefined' &&
      typeof Windows.ApplicationModel !== 'undefined') {
        var fileSavePicker = new Windows.Storage.Pickers.FileSavePicker();
        // Example: You can replace the words EXTENSION and ext with the word PNG. 
        fileSavePicker.fileTypeChoices.insert(
          "EXTENSION file", [".ext"]);
            // Insert appropriate file format through code.
        fileSavePicker.defaultFileExtension = ".ext";
          // Extension of the file being saved.
        fileSavePicker.suggestedFileName = "file.ext";
          // Name of the file to be downloaded.
        fileSavePicker.settingsIdentifier = "fileSavePicker1";
        var fileUri =
          new Windows.Foundation.Uri("<URL of the file being downloaded>");
        fileSavePicker.pickSaveFileAsync().then(function (fileToSave) {
          var downloader =
            new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
          var download = downloader.createDownload(
            fileUri,
            fileToSave);
          download.startAsync().then(function (download) {
            // Any post processing.
            console.log("Done");
          });
        });
      }
      else {
        // Use the normal download functionality already implemented for browsers,
        // something like <a href="<URL>" />.
      }
    }
}
})();

図 2 のコードを、ボタンのクリック イベントか、ファイル ダウンロード機能を提供する予定の場所に記述します。

このコード スニペットでは BackgroundDownloader クラス (bit.ly/2jQeuBw) を使用します。このクラスには、アプリ停止後のバックグラウンドでのダウンロードの続行や、サイズの大きなファイルのダウンロードなど、多くのメリットがあります。

図 2 のコードは、実際はブラウザーと同じエクスペリエンスを生み出します。たとえば、ユーザーにファイルの場所を選択するよう依頼 (fileSavePicker 変数) し、ダウンロードを開始 (downloader 変数) して、選択した場所に書き込みます。

また、図 3 のコードを使用して、よりサイズの小さいファイルをダウンロードすることもできます。このコードは、アプリが稼働中のみ実行されます。

図 3 ファイル ダウンロードの JavaScript コード (サイズの小さいファイル)

// Use the Windows.Web.Http.HttpClient to download smaller files and
// files are needed to download when the app is running in foreground.
(function() {
  if (typeof Windows !== 'undefined' &&
    typeof Windows.UI !== 'undefined' &&
    typeof Windows.ApplicationModel !== 'undefined') {
  function WinAppSaveFileWinHTTP() {
    var uri = new Windows.Foundation.Uri("<URL of the file being downloaded>");
    var fileSavePicker = new Windows.Storage.Pickers.FileSavePicker();
    fileSavePicker.fileTypeChoices.insert("EXT file",
      [".ext"]); //insert appropriate file format through code.
    fileSavePicker.defaultFileExtension = ".ext";
      // Extension of the file being saved.
    fileSavePicker.suggestedFileName = "file.ext";
      // Name of the file to be downloaded. Needs to be replaced programmatically.
    fileSavePicker.settingsIdentifier = "fileSavePicker1";
    fileSavePicker.pickSaveFileAsync().then(function (fileToSave) {
      console.log(fileToSave);
      var httpClient = new Windows.Web.Http.HttpClient();
      httpClient.getAsync(uri).then(function (remoteFile) {
        remoteFile.content.readAsInputStreamAsync().then(
           function (stream) {
          fileToSave.openAsync(
            Windows.Storage.FileAccessMode.readWrite).then(
            function (outputStream) {
            Windows.Storage.Streams.RandomAccessStream.copyAndCloseAsync(
              stream, outputStream).then(function (progress, progress2) {
          // Monitor file download progress.
            console.log(progress);
            var temp = progress2;
          });
        });
        });
      });
    });
  }
}
})();

図 3 のコードは、Windows.Web.Http.HttpClient を使用してファイルのダウンロード操作を処理します (bit.ly/2k5iX2E)。図 2図 3 のコード スニペットを比較すると、図 3 のコードの方がやや高度なコーディングが必要になることがわかります。こちらでは、ファイル ダウンロードをより細かく制御しています。このようにして、UWP アプリを使用してファイルにストリームを保存する複数の方法を調べることもできます。

また、既にダウンロードされたファイルをアプリケーションが処理する場合、FutureAccessList プロパティを使用してファイルが保存された場所をキャッシュしてアクセスすることをお勧めします (bit.ly/2k5fXn6)。この方法は重要で、ユーザーがダウンロードされたファイルをシステム上の好きな場所 (たとえば、D:\ファイル\ や C:\ユーザー\マイユーザー\マイファイル\) に保存することができ、処理をサンドボックス化するアプリ コンテナーではユーザーがダウンロード操作を開始しないとファイル システムに直接アクセスできない場合があるためです。このクラスは、ユーザーが同じファイルを再度開くときに追加手順の必要性をなくすのに便利です。このクラスを使用するには、少なくとも 1 回 FileOpenPicker を使用してファイルを開く必要があります。

これは、ホストされた Web アプリのファイル ダウンロード機能を効率化し、直観的な UX を提供するのに役立ちます (ヒント: 実行時例外を避けるため、bit.ly/2jsN1WS の ApplicationContentURI にファイルの URL ドメインを追加するようにします)。

セッション管理

最新アプリのほとんどは、ユーザーの複数のセッション間でデータを保持するのが一般的です。たとえば、頻繁に使用するアプリがあり、起動するたびに毎回ログインしなければならない状況を想像してみてください。1 日に何度もアプリを起動するとしたら、時間の無駄です。Windows ランタイム フレームワークには、UWP アプリに変換した Web アプリで利用できるクラスがあります。

同じユーザーの複数のセッション間で特定のパラメーターを保持する必要のあるシナリオを考えてみます。前回のセッション時刻やその他のキャッシュされたアイテムなど、ユーザーをはじめ、さまざまな情報を特定する文字列があるとします。

このシナリオで使用する適切なクラスは、Windows.Storage.ApplicationData クラスです。このクラスには、多くのプロパティとメソッドがありますが、今回のシナリオでは、localSettings について考えます。

この設定は、キーと値のペアとしてシステムに格納されます。次の実装用サンプル コードを見てください。

function getSessionData()
{
var applicationData = Windows.Storage.ApplicationData.current;
var localSettings = applicationData.localSettings;
// Create a simple setting.
localSettings.values["userID"] = "user998-i889-27";
// Read data from a simple setting.
var value = localSettings.values["userID"];
}

設定にデータを書き込むコードは、アプリ内のチェックポイントで記述するのが理想です。チェックポイントとは、特定の情報を取得して、リモート Web API や Web サービスに送信する必要がある場所です。設定を読み取るコードは、通常 App_activated イベント ハンドラーに記述します。このイベント ハンドラーは、アプリが起動し、前回のアプリ セッションから保持されている情報にアクセスする場所です。各設定の名前には 255 文字という制限があり、サイズには 8 KB という制限があるため注意が必要です。

音声 (Cortana) 統合のシナリオ

Web サイト (今はアプリに変わっています) が UWP への移植後に実装できるシナリオの 1 つが Cortana の統合です。Cortana は、Windows デバイスで利用できる音声ベースの対話型デジタル アシスタントです。

今回の Web サイトが旅行関連のポータルだとします。これを Windows 10 アプリに移植します。そして、Cortana 統合のユースケースの 1 つとして、利用者に旅の詳細を示します。利用者は「Show trip to London (ロンドンへの旅を表示して)」 (行き先はどこでもかまいません) といったコマンドを発話します。コマンドはアプリの開発者が構成する必要があります (図 4 参照)。

図 4 Cortana コマンドの XML

<?xml version="1.0" encoding="utf-8"?>
<VoiceCommands xmlns="https://schemas.microsoft.com/voicecommands/1.1">
  <CommandSet xml:lang="en-us" Name="AdventureWorksCommandSet_en-us">
    <CommandPrefix> Adventure Works, </CommandPrefix>
    <Example> Show trip to London </Example>
    <Command Name="showTripToDestination">
      <Example> Show trip to London </Example>
      <ListenFor RequireAppName=
        "BeforeOrAfterPhrase"> show trip to {destination} </ListenFor>
      <Feedback> Showing trip to {destination} </Feedback>
      <Navigate/>
    </Command>
    <PhraseList Label="destination">
      <Item> London </Item>
      <Item> Dallas </Item>
    </PhraseList>
  </CommandSet>
<!-- Other CommandSets for other languages -->
</VoiceCommands>

Cortana は、多くの組み込みアプリ (カレンダーなど) を使って作業の実現を支援します。また、カスタム アプリとのインターフェイスを取るための API を公開します。基本的には、Cortana は以下の方法でアプリと連携します。

  1. voicecommands.xml ファイルの登録内容に従ってコマンドを聞き取る。
  2. Windows の検索バーにテキスト入力または音声入力されたコマンドに対応する関連アプリをアクティブにする。
  3. 音声コマンドまたはテキスト コマンドを変数としてアプリに渡し、アプリがユーザー入力を処理できるようにする。

メモ: ファイル名は一例です。拡張子 XML を付ければ、名前は自由に指定できます。Windows Developer の記事「Cortana を使用して顧客と対話する (10 / 10)」(bit.ly/2iGymdE、英語) では、XML ファイルとそのスキーマでコマンドを構成する方法の概要がわかりやすく説明されています。

図 4 の XML コードによって、Cortana は以下のようなコマンドが発行されたときに、Adventure Works アプリを起動する必要があることがわかります。

'Adventure Works, Show trip to London'
'Adventure Works, Show trip to Dallas'

では、アクティベーションと、入力に応じたアプリ (Web サイト) 内の関連ページへの移動を Web のコードが処理する方法を見てみましょう。このシナリオをコーディングする場合、JavaScript ファイルを別途作成します。

図 5 のコードは、呼び出し側のページ (参照側のページ) の <body> セクションで、DOMContentLoaded イベントがトリガーされる直前に参照される必要があります。そのため、参照側ページの <body> 要素を終了する直前に <script src> を追加するのが最善です。

図 5 音声コマンド ハンドラー コード

<!-- In HTML page :
<meta name="msapplication-cortanavcd" content="http://<URL>/vcd.xml" />
-->
(function () {
  if (typeof Windows !== 'undefined' &&
    typeof Windows.UI !== 'undefined' &&
    typeof Windows.ApplicationModel !== 'undefined') {
    Windows.UI.WebUI.WebUIApplication.addEventListener("activated", activatedEvent);
  }
  function activatedEvent (args) {
    var activation = Windows.ApplicationModel.Activation;
    // Check to see if the app was activated by a voice command.
    if (args.kind === activation.ActivationKind.voiceCommand) {
      // Get the speech recognition.
      var speechRecognitionResult = args.result;
      var textSpoken = speechRecognitionResult.text;
      // Determine the command type {search} defined in vcd.
      switch (textSpoken) {
         case "London":
           window.location.href =
             'https://<mywebsite.webapp.net>/Pages/Cities.html?value=London';
        break;
      case "Dallas":
        window.location.href =
          'https://<mywebsite.webapp.net>/Pages/Cities.html?value=Dallas';
        break;
                              ...                                   
        <other cases>
                              ...               
      }
    }
  }
})();

 (メモ: Cortana は「activationKind」を「voiceCommand」としてアプリを「アクティブ化」するため、このアクティベーションのためにイベント ハンドラーを登録する必要があります。アプリがネイティブ WinJS でも C# でもない場合、アプリのライフサイクル イベントを登録するために、特定のイベントをサブスクライブまたは処理できる Windows.UI.WebUI.WebUIApplication 名前空間が提供されています)。

図 5 のコードでは、Cortana の API がユーザーからの音声入力を受け取り、activation クラスの SpeechRecognition プロパティを設定しています。これにより、変換後のテキストをコードで取得し、アプリが関連操作を実行できるようになります。このスニペットでは、switch-case ステートメントを使用して textSpoken 変数を評価し、クエリ文字列として追加された都市の値を含む Cities.html にユーザーをルーティングします。

明らかに、これはシナリオの 1 つにすぎません。各 Web サイトのルーティング構成 (MVC、REST など) に応じて状況は変わります。これで、アプリが Cortana と対話する準備が整いました。

(存在しない) 戻るボタン

最も高度な機能をいくつか説明しました。今度はアプリ エクスペリエンスの側面のうち、基本的でも重要なものの 1 つである「ナビゲーション」について考えます。アプリからの閲覧が容易で、直観的なナビゲーション階層があれば、利用者はアプリのエクスペリエンスを予測できます。

レスポンシブ Web サイトを UWP に移植する際、UI が想定どおりに動作することが前提となるため、このシナリオは特に重要です。ただし、アプリ内でのナビゲーションの処理については、ポインター以上のものをアプリ コンテナーに提供する必要があります。既定の UX は以下のようになります。

  1. ユーザーがアプリを起動する。
  2. ユーザーが、ページ上のハイパーリンクやメニューをクリックして、アプリのさまざまなセクションを閲覧する。
  3. ある時点で、ユーザーは前のページに戻りたくなり、ハードウェアの戻るボタンまたは Windows OS が提供するソフトウェアの戻るボタンをクリックする (アプリにはまだ戻るボタンはありません)。
  4. アプリが終了する。

4. は、想定外の結果で、修正が必要です。解決法は簡単です。通常の JavaScript API を使用して、アプリ コンテナー ウィンドウに戻るように指示を出すことなどが解決策です。図 6 にこのシナリオのコードを示します。

図 6 戻るボタンのコード

(function() {
  if (typeof Windows !== 'undefined' &&
    typeof Windows.UI !== 'undefined' &&
    typeof Windows.ApplicationModel !== 'undefined') {
   Windows.UI.Core.SystemNavigationManager.getForCurrentView().
     appViewBackButtonVisibility =
     Windows.UI.Core.AppViewBackButtonVisibility.visible;
        Windows.UI.Core.SystemNavigationManager.getForCurrentView().
        addEventListener("backrequested", onBackRequested);
function onBackRequested(eventArgs) {
      window.history.back();
      eventArgs.handled = true;
    }
  }
  })();

最初の数行で、フレームワークが提供する戻るボタンを有効にしています。このボタンはアプリの上部に表示されます。次に、タップまたはクリック イベントのイベント ハンドラーを登録します。このコードでは、“window” DOM オブジェクトにアクセスして、1 ページ戻るように指示するだけです。注意が必要な点がもう 1 つあります。 アプリがナビゲーション スタックの一番下にある場合、履歴内に戻るページがそれ以上存在しないため、アプリはこの時点で終了します。アプリにカスタム エクスペリエンスを追加する必要がある場合は、追加のコードを記述しなければなりません。

ライブ タイル

ライブ タイルは、アプリの更新に関する情報やユーザーが興味を持ちそうな情報を、アプリを起動せずに簡潔に表示する UWP アプリの機能です。Windows デバイスでスタート メニューを選択すると、簡単な例を表示できます。ニュース、マネー、スポーツなどのアプリのライブ タイルがいくつか表示されます。

以下に、ユースケースの例をいくつか示します。

  • e コマース アプリの場合、タイルに注文の状況や、お勧めの商品を表示する。
  • 基幹業務アプリの場合、タイルに自社の報告書の縮小版を表示する。
  • ゲーム アプリの場合、ライブ タイルに特典、ゲームの成績、新しいチャレンジなどを表示する。

図 7 に、Microsoft が組み込んでいるアプリのライブ タイルの例を 2 つ示しています。

ライブ タイルの例
図 7 ライブ タイルの例

ホストされた Web アプリにライブ タイルを統合する最も簡単な方法の 1 つは、Web API を作成してアプリのコード (図 8 参照) を設定し、数分おきにポーリングする方法です。Web API の役割は XML を送り返すことです。この XML は、Windows アプリのタイル コンテンツを作成するために使用されます (メモ: ライブ タイルを表示するには、エンド ユーザーがアプリをスタート メニューにピン留めする必要があります)。

図 8 シンプルなライブ タイルのコード

function enableLiveTile()
  {
    if (typeof Windows !== 'undefined' &&
      typeof Windows.UI !== 'undefined' &&
      typeof Windows.ApplicationModel !== 'undefined') {
      {
        var notification = Windows.UI.Notifications;
        var tileUpdater =
          notification.TileUpdateManager.createTileUpdaterForApplication();
        var recurrence = notification.PeriodicUpdateRecurrence.halfHour;
        var url = new Windows.Foundation.Uri("<URL to receieve the XML for tile>");
        tileUpdater.startPeriodicUpdate(url, recurrence);
      }
      }       
  }

ここで最も重要なクラスは、Windows.UI.Notifications 名前空間の TileUpdateManager です。このクラスは、内部でタイルに送信するためのテンプレートを作成するだけでなく、startPeriodicUpdate メソッドを使って、タイルの XML コンテンツに指定された URL をポーリングします。ポーリングの期間は、PeriodicUpdateRecurrence 列挙値を使用して、タイルの XML コンテンツを抽出する間隔に設定します。これはサーバー駆動型の傾向が強いアプローチで、Web API からクライアントに XML コードとタイル テンプレートを送信します。そのため、開発者がアプリ層とサービス層を制御できる場合のみ実現可能です。

では、今回のアプリが天気や市場調査データなどの情報をサード パーティの Web API から受け取るとしましょう。このようなシナリオでは通常、Web API が、本文、ヘッダーなどに関する標準の HTTP 応答を送信することになります。ここで、Web API の応答を解析し、JavaScript を使用してクライアント側の UWP アプリ コードでコンテンツの XML タイルを形成します。これにより、アプリの開発者はデータを表示するテンプレートの種類を細かく制御できるようになります。また、TileNotification クラスを使用して、タイルの有効期限を示すこともできます。これを実行するコードを図 9 に示します。

図 9: ライブ タイルを作成する場合のもう 1 つのオプション

function createLiveTile() /* can contain parameters */
{
  var notifications = Windows.UI.Notifications,
  tile = notifications.TileTemplateType.tileSquare310x310ImageAndText01,
  tileContent = notifications.TileUpdateManager.getTemplateContent(tile),
  tileText = tileContent.getElementsByTagName('text'),
  tileImage = tileContent.getElementsByTagName('image');
  // Get the text for live tile here [possibly] from a remote service through xhr.
  tileText[0].appendChild(tileContent.createTextNode('Demo Message')); // Text here.
  tileImage[0].setAttribute('src','<URL of image>');
  var tileNotification = new notifications.TileNotification(tileContent);
  var currentTime = new Date();
  tileNotification.expirationTime = new Date(currentTime.getTime() + 600 * 1000);
    notifications.TileUpdateManager.createTileUpdaterForApplication().
    update(tileNotification);
}

TileTemplateType クラスが、画像またはテキストを表示する 310 x 310 ピクセルの正方形のタイル テンプレートを作成する機能を提供します。また、タイルの有効期限がコードによって 10 分間に設定されています。つまり、この期間をすぎると、アプリで新しい通知をプッシュ通知の形式で送信しない限り、ライブ タイルはアプリ パッケージで提供した既定アプリのタイルに戻ります。利用可能なテンプレートの詳細については、bit.ly/2k5PDJj (英語) を参照してください。

まとめ

Web アプリから UWP アプリへの移行を計画する場合、検討すべきことがいくつかあります。

  1. アプリのレイアウトとレンダリングを最新ブラウザー (Microsoft Edge など) でテストする。
  2. Web アプリが ActiveX コントロールやプラグインを利用している場合、最新ブラウザーで実行するとき、または UWP アプリとして実行するときに機能するように、代替え手段を確保する。
  3. bit.ly/1PJBcpi (英語) の SiteScan ツールを使用して、ライブラリや機能に関連する推奨事項を確認する。
  4. Web サイトが参照する外部リソースの URL を特定する。このような URL は、Appx.manifest ファイルの ApplicationContentUriRules セクションに追加する必要があります。

また、JavaScript Windows オブジェクトを使用して実現でき、リッチなエクスペリエンスによってアプリの機能に磨きをかけることができる密接な統合も数多くあります。連絡先、カメラ、マイク、トースト通知などの多くの機能が、Web サイトとアプリの個性を融合するチャンスを広げます。今回のコードは、プロジェクト テンプレートに変換し、開発者が GitHub (bit.ly/2k5FlJh、英語) から入手できるようにしています。


Sagar Bhanudas Joshi は、開発者や ISV に協力し、6 年以上ユニバーサル Windows プラットフォームと Microsoft Azure に携わっています。彼は、職務の一環として、新興企業がオンボード ソリューションやアプリを設計、デザインして、Azure、Windows および Office 365 プラットフォームで提供するのを支援しています。Joshi はインドのムンバイで生活し、働いています。Twitter (@sagarjms、英語) で彼をフォローできます。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Sandeep Alur と Ashish Sahu に心より感謝いたします。