Metro スタイル アプリの開発を始めるとすぐに行き当たるのがコントラクトです。コントラクトは Windows 8 で導入された強力な新しいコンセプトで、Metro スタイル アプリはこれを利用して、他のアプリや Windows との間の対話的操作のサポートを宣言することができます。検索コントラクト、共有コントラクトなど、いくつかはおそらく既に耳にされていることと思います。コントラクトを活用することで、アプリはシステムや他のアプリとの連携能力が増し、インストールされているコントラクト対応アプリの数が増えるほど、機能が向上していきます。この記事では、アクティベーションの流れをご紹介します。アクティベーションは、アプリにコントラクトを追加する際に考慮する必要のある中心的な概念の 1 つです。

Metro スタイル アプリの起動を行い、ユーザーがアプリを起動した理由をそのアプリに通知するのに使用されるのが、Windows アクティベーション プラットフォームです。アプリ起動の理由はさまざまで、ユーザーがスタート画面でアプリのタイルを使って起動した場合もあれば、たとえばユーザーが検索を行った際の結果表示など、具体的なタスクのために起動される場合もあります。Windows はアプリに、起動された理由と、必要な場合はタスクを完了するための追加情報を提供します。Windows 8 アクティベーション プラットフォーム以前、こういった情報をアプリに受け渡すために使用されていたのは、コマンド ライン パラメーターでした。新しいモデルでは、StorageFile、ShareOperation などのライブ オブジェクトを受け渡して、アプリにコンテキスト情報を与えることもできます。これはコントラクトの有用性がさらに際立つ要素の 1 つと言えるでしょう。それでは、コントラクトによる起動をサポートするために必要な知識を、詳しく見ていきましょう。

コントラクト: 目的に応じた、コンテキストを伴う Metro スタイル アプリの起動

Windows 8 Consumer Preview のデモ (英語) でご覧いただけるとおり、Windows 8 のコントラクトは、他の Metro スタイル アプリやシステム UI とアプリをつなぐ糊のような役割を果たします。たとえば、File Open Picker (ファイル オープン ピッカー) コントラクトを使用すると、ユーザーはアプリ内から別のアプリのファイルをインポートすることができます。検索コントラクトでは、システム内のどこからでもアプリを検索することができ、クエリを複数のアプリ間で迅速に受け渡すことができます。いずれの場合も、そして他の多くのコントラクト使用シナリオでも、ユーザーが目的のタスクをすばやく効率的に完了できるよう、Windows がアプリの UI の特定の部分を直接指定して起動できるようになっている必要があります。そこで活躍するのが、アクティベーション プラットフォームと API です。

ユーザーがアプリの対話的操作を開始する方法は 2 種類あります。

    1. アプリのイマーシブ ビューをフォアグラウンド表示する必要があるアクションによるもの。これを別名 "メイン ビュー アクティベーション" と言います。検索コントラクトなどが該当します。

      検索ペインのアプリをクリックすると、そのアプリの検索結果ビューが起動される
      メイン ビュー アクティベーションの例

    1. 実行中のアプリケーションのコンテキスト内にとどまったまま、インラインでホストされるアクションによるもの。これを別名 "ホステッド ビュー アクティベーション" と言います。以下に例を 2 つ示します。1 つはファイル選択機能に参加しているアプリ、もう 1 つは共有ターゲットとして使用されているアプリです。

ファイル選択ツールでアプリを選択すると、そのアプリのファイル選択 UI が起動される
ファイル選択ツールでのホステッド ビュー アクティベーションの例

共有チャームからメール アプリを起動して、操作中の写真を共有する
共有ターゲットとしてのホステッド ビュー アクティベーションの例

両者の違いをまとめると、次のようになります。

メイン ビュー アクティベーション

ホステッド ビュー アクティベーション

完全なイマーシブ表示で、メイン アプリとして起動

システムのクロム内で UI を表示

幅広い用途に使用可能

流れの決まった短いタスクに使用され、コードもそのタスクのみに特化

切り替えリストに表示される

切り替えリストに表示されることはない

ジェスチャによって閉じることができる

同じアプリのメイン ウィンドウのビューには影響しない

それでは、各アクティベーション モデルについて見ていきましょう。いくつかの一般的なシナリオに適用して紹介しますので、優れた Metro スタイル アプリを開発する参考としていただければと思います。

シナリオ 1: アプリに検索アクティベーションを組み込む

Windows 8 では、検索コントラクトによる検索機能をアプリに追加すると、ユーザーはシステム内のどこからでも、好きなときにそのアプリのコンテンツを検索できます。アプリがメイン アプリとして表示されている場合は、検索チャームから直接アプリのコンテンツを検索することができます。そうでない場合、検索チャームで検索ペインのアプリ一覧からアプリを選択することで、そのアプリの検索が可能になります。

アプリで検索アクティベーションをサポートすると、クエリに応じて検索結果を表示するためにいつでもそのアプリを起動することができます。検索ペインからの起動は、スタート画面からの起動と同様、メイン ビュー アクティベーションに分類されます。よって、アプリで複数のコントラクトをサポートすると、さまざまな異なるシナリオでアプリが起動される可能性があります。さらに、この種のアクティベーションは、アプリが既に実行中の場合も発生することがあります。ユーザーがそのアプリのメイン ビューを、特定のシナリオ (たとえば検索結果の表示) 向けに転用したいと考える場合があるためです。こういった使用方法に対応するため、次のようにすることをお勧めします。

  • アプリ起動の目的であるメイン ビュー コントラクトへの対応に必須でないコードは、読み込みを遅延させます。
  • すべてのコントラクトに使用する一般的な初期化ロジックと、特定のコントラクトに対応するためのロジックとを分離します。
  • 起動の際に 1 回だけ実行されることを想定したコードは、複数回実行される可能性があるような形でアクティベーションのハンドラーに組み込まないよう、注意します。
  • ユーザーにとってアプリが常時実行/常時接続されているように見えるよう、終了された状態からの起動時には、前回の状態や設定を再度読み込みます。

参考に、"ストア" アプリと "フォト" アプリをご覧ください。いずれも、これらの推奨事項に忠実な形で検索アクティベーションをサポートしています。

"ストア" アプリが実行されており、"calendar" (カレンダー) の検索結果が表示されている。検索ペインが開いており、ユーザーが新しい検索クエリの入力を始めている

"ストア" アプリでの検索

 

"フォト" アプリが実行されており、"Vancouver" (バンクーバー) の検索結果が表示されている。検索ペインが開いており、"vancouver" という検索クエリで検索が行われた状態になっている

"フォト" アプリでの検索

では、JavaScript アプリと XAML アプリについて、検索アクティベーションを正しくサポートする方法を見ていきましょう。

JavaScript アプリ

JavaScript による Metro スタイル アプリの場合、アクティベーションは WinJS.Application.onactivated イベント (英語) によってエクスポーズされます。アプリが既に実行中や中断状態でない場合は、このイベントは、DOMContentLoaded の完了後に実行されます。それ以外の場合、このイベントは Windows がアプリをアクティベートする必要が発生した時点で実行されます。JavaScript アプリ向けの Visual Studio のツーリングでは、このイベント登録のセットアップを default.js 内で処理するようになっており、通常起動によるアクティベーションが発生した場合 (つまりユーザーがスタート画面からアプリを起動した場合) に実行するコードを追加できる領域が提供されます。

アプリで検索アクティベーションのサポートを拡張する方法は次のとおりです。

  1. Visual Studio マニフェスト デザイナーを使用して、検索の宣言をマニフェストに追加します。
  2. アプリ起動のたびに理由を問わず実行が必要な、一般的な初期化コードがある場合は、JavaScript のグローバル スコープに配置します。その中に DOM へのアクセスが必要なコードが含まれる場合、そのコードは DOMContentLoaded イベント ハンドラー内に追加します。
  3. 検索のためのアクティベーションをハンドルするよう、登録を行います。
  4. 検索によってアプリがアクティベーションを受けた場合は、アプリの検索結果ページを表示し、アクティベーション イベントの引数から得られる QueryText (英語) をパスします。

この処理を手動で行うよりも楽な方法はないのかとお考えのことと思いますが、さいわい、Visual Studio のツーリングを利用すると、処理の多くを簡単に済ませることができます。プロジェクトを右クリックして [Add] (追加) > [New Item] (新しいアイテム) を選択し、ダイアログで [Search Contract] (検索コントラクト) を選ぶと、この記事で紹介しているコードの大部分と、Microsoft が定める検索 UX のガイドライン (英語) に準拠した方法で検索結果を表示する検索 UI が、自動的に作成されます。ただし、このツーリングでは、WinJS.Navigation フレームワークを使用する必要があります。

次に示すのは、私が作成したフォト アプリの default.js ファイルから抜粋したコード スニペットで、検索アクティベーションをサポートしているようすが確認できます。

// Register activated event handler
WinJS.Application.addEventListener("activated", function (eventObject) {
...
if (eventObject.detail.kind === appModel.Activation.ActivationKind.launch) {
...
} else if (eventObject.detail.kind === appModel.Activation.ActivationKind.search) {
uri = searchPageURI;
pageParameters = { queryText: eventObject.detail.queryText };
}
// Indicate to the system that the splash screen must not be torn down
// until after processAll and navigate complete asynchronously.
if (uri) {
eventObject.setPromise(ui.processAll().then(function () {
return nav.navigate(uri, pageParameters);
}));
}
});

XAML アプリ

XAML による Metro スタイル アプリの場合、アクティベーションをサポートするために必要な処理の多くは、Windows.UI.Xaml.Application クラス (英語) が行います。このクラスは、検索などの一般的なコントラクトをサポートするためにオーバーライドすることができる、厳密に型指定されたアクティベーション メソッド群をエクスポーズします。厳密に型指定されたメソッドのないコントラクト アクティベーションでは、OnActivated メソッド (英語) をオーバーライドしてアクティベーションの種類を検査し、アプリのアクティベーションにつながったコントラクトを特定します。

Visual Studio の新しい XAML アプリ プロジェクトには、Windows.UI.Xaml.Application クラス (英語) を使って通常起動によるアクティベーションにアプリを対応させるための、生成済みコードが付属しています。このアクティベーションをハンドルするためのコードは、App.xaml.cs/cpp/vb ファイルの、アプリのクラス表現内にあります。

アプリで検索アクティベーションのサポートを拡張する方法は次のとおりです。

  1. Visual Studio マニフェスト デザイナーを使用して、検索の宣言をマニフェストに追加します。
  2. アプリケーション起動のたびに理由を問わず実行が必要な、一般的な初期化コードがある場合は、App.xaml.cs/cpp/vb の App コンストラクター内に配置します。
  3. 検索アクティベーションをハンドルするよう、App.xaml.cs/cpp/vb で厳密に型指定された OnSearchActivated メソッド (英語) をオーバーライドします。
  4. アプリの検索 UI を読み込み、SearchActivatedEventArgs (英語) で受け取ったクエリに対する検索結果を表示します。

JavaScript アプリの場合と同様、手動よりも楽な方法が用意されており、Visual Studio のツーリングを利用して処理の多くをこなすことができます。プロジェクトを右クリックして、[Add] (追加) > [New Item] (新しいアイテム) を選択し、ダイアログで [Search Contract] (検索コントラクト) を選ぶと、この記事で紹介しているコードの大部分と、Microsoft が定める検索 UX のガイドライン (英語) に準拠した方法で検索結果を表示する検索 UI が、自動的に作成されます。

次に示すのは、私が作成したフォト アプリから抜粋した C# コードのスニペットで、検索アクティベーションをサポートしているようすが確認できます。

検索のためのアクティベーションをサポートするには、OnSearchActivated メソッド (英語) をオーバーライドする必要があります。

protected override void OnSearchActivated(SearchActivatedEventArgs args)
{
// Load Search UI
PhotoApp.SearchResultsPage.Activate(args.QueryText);
}

SearchResultsPageActivate メソッドによって、ユーザーの検索クエリに対する検索結果を表示する UI のセットアップが行われます。

// SearchResultsPage.xaml.cs code snippet 
public static void Activate(String queryText)
{
// If the window isn't already using Frame navigation, insert our own frame
var previousContent = Window.Current.Content;
var frame = previousContent as Frame;
if (frame == null)
{
frame = new Frame();
Window.Current.Content = frame;
}
// Use navigation to display the results, packing both the query text and the previous
// Window content into a single parameter object
frame.Navigate(typeof(SearchResultsPage1),
new Tuple<String, UIElement>(queryText, previousContent));
// The window must be activated in 15 seconds
Window.Current.Activate();
}

ここでご紹介したロジックや原則が適用できるのは、検索アクティベーションのサポートだけではありません。同じくメイン ビュー アクティベーション型のコントラクトに分類される Protocols (プロトコル) (英語)、File Associations (ファイルの関連付け) (英語)、Device AutoPlay (デバイス自動再生) (英語) のサポートを追加する際も、同じテクニックを使うことができます。

シナリオ 2: アプリに File Open Picker (ファイル オープン ピッカー) アクティベーションを組み込む

Metro スタイル アプリでは、ファイル選択ツール (ファイル ピッカー) を呼び出すことによって、システム内を参照してアプリで使用するファイルやフォルダーを選ぶ機能や、新しい名前、ファイルの種類、場所を指定してファイルを保存する機能 ("名前を付けて保存") をユーザーに提供することができます。また、ファイル選択ツールをインターフェイスとして使い、他のアプリにファイル、保存先、またはファイルの更新内容などを提供することもできます。File Open Picker (ファイル オープン ピッカー) コントラクトを組み込むことによって、アプリのファイルを別のアプリ内から直接選ぶことが容易になり、ユーザーは自由かつ柔軟に、アプリが保存および表示するファイルを選ぶことができます。

File Open Picker (ファイル オープン ピッカー) コントラクトによるアプリの起動は、ホステッド ビュー アクティベーションに分類されます。アプリの UI はファイル選択ツール内でホストされ、このアクティベーションによって実行するコードは、ユーザーにファイル選択機能を提供するタスクに絞った内容にする必要があります。この場合、ユーザーに優れたエクスペリエンスを提供するため、アプリの動作をできる限り高速にすることが重要です。指定されたホステッド ビュー アクティベーション タスクに必須でないコードやライブラリは読み込まないよう注意します。

SkyDrive アプリはこの点で非常に優れた例ですので、ぜひご覧ください。File Open Picker (ファイル オープン ピッカー) アクティベーションが適切にサポートされており、ユーザーにファイル選択機能を提供するタスクに絞った動作となっています。

ピッカーが実行されており、ユーザーが SkyDrive アプリからファイルを選べる状態になっている

SkyDrive アプリでの File Open Picker (ファイル オープン ピッカー) のサポート

では、JavaScript アプリと XAML アプリについて、File Open Picker (ファイル オープン ピッカー) アクティベーションを正しくサポートする方法を見ていきましょう。

JavaScript アプリ

JavaScript による Metro スタイル アプリの場合、ホステッド ビュー アクティベーションの動作はメイン ビュー アクティベーションと同様ですが、重要な違いが 1 つあり、ホステッド ビュー アクティベーションは、必ず新しいウィンドウとスクリプト コンテキストで実行されます。このため、この種類のアクティベーションをハンドルするコードでは、アプリ本体のライブラリ、グローバル変数、DOM を利用することができません。

File Open Picker (ファイル オープン ピッカー) アクティベーションをサポートするようアプリを拡張する方法は次のとおりです。

  1. File Open Picker (ファイル オープン ピッカー) コントラクトをハンドルするために設計された、専用の HTML ページを新たに作成します。
  2. Visual Studio マニフェスト デザイナーで File Open Picker (ファイル オープン ピッカー) の宣言を追加し、新たに作成した HTML ページをスタート ページに指定します。
  3. パフォーマンス向上のため、このページで読み込む JavaScript 等のリソースは、File Open Picker (ファイル オープン ピッカー) コントラクトのサポートに必要なものだけに絞ります。
  4. File Open Picker (ファイル オープン ピッカー) コントラクトのためのアクティベーションだけをハンドルするよう、アクティベーション イベント ハンドラーを構築します。このハンドラーは、ファイル選択タスク全体の中で、1 回だけ呼び出されます。
  5. ファイル選択ツールとのやり取りは、アクティベーション イベントの引数を使用して行います。

Visual Studio のツーリングを利用すると、この処理にかかる時間を短縮することができます。プロジェクトを右クリックして、[Add] (追加) > [New Item] (新しいアイテム) を選択し、ダイアログで [File Picker Contract] (ファイル選択ツール コントラクト) を選ぶと、次に示すコードの大部分が、プロジェクト内に自動作成されます。

次に示すのは、私が作成したフォト アプリの fileOpenPicker.js ファイルから抜粋した、File Open Picker (ファイル オープン ピッカー) アクティベーションをハンドルする部分のコード スニペットです。

// Register activated event handler for handling File Open Picker activation
WinJS.Application.addEventListener("activated", function (eventObject) {
if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.fileOpenPicker) {
pickerUI = eventObject.detail.fileOpenPickerUI;
pickerUI.onfileremoved = fileRemovedFromPickerUI;
...
}
});

WinJS.Application.start();

XAML アプリ

XAML による Metro スタイル アプリの場合、ホステッド ビュー アクティベーションをサポートする方法は、メイン ビュー アクティベーションの場合と似ています。最も大きな違いは、アクティベーションをハンドルするために、アプリで新しいスレッドと新しいウィンドウを作成する必要がある点です。ホステッド ビュー アクティベーションに必要な新しいスレッドと新しいウィンドウの作成は、Visual Studio のテンプレート コードがすべて代行してくれます。

XAML アプリで File Open Picker (ファイル オープン ピッカー) アクティベーションをハンドルするには、次のようにする必要があります。

  1. Visual Studio マニフェスト デザイナーを使用して、File Open Picker (ファイル オープン ピッカー) の宣言をマニフェストに追加します。
  2. App.Xaml.cs/cpp/vb で OnFileOpenPickerActivated メソッド (英語) をオーバーライドし、コントラクトをハンドルするページを読み込みます。
  3. ファイル選択ツールとやり取りできるよう、コントラクトをハンドルするページに FileOpenPickerActivatedEventArgs (英語) をパスします。

Visual Studio のツーリングを利用すると、この処理にかかる時間を短縮することができます。プロジェクトを右クリックして、[Add] (追加) > [New Item] (新しいアイテム) を選択し、ダイアログで [File Picker Contract] (ファイル選択ツール コントラクト) を選ぶと、次に示すコードの大部分が、プロジェクト内に自動作成されます。

次に示すのは、私が作成したフォト アプリから抜粋した、File Open Picker (ファイル オープン ピッカー) アクティベーションをハンドルする部分の C# コードのスニペットです。

// App.xaml.cs code snippet
protected override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args)
{
var fileOpenPickerPage = new PhotoApp.FileOpenPickerPage();
fileOpenPickerPage.Activate(args);
}

// FileOpenPickerPage.xaml.cs code snippet
public void Activate(FileOpenPickerActivatedEventArgs args)
{
this._fileOpenPickerUI = args.FileOpenPickerUI;
this._fileOpenPickerUI.FileRemoved += FileOpenPickerUI_FileRemoved;

// Show the user’s photos in the Picker UI
...

Window.Current.Content = this;
// The window must be activated in 15 seconds
Window.Current.Activate();
}

ここでご紹介したロジックや原則が適用できるのは、File Open Picker (ファイル オープン ピッカー) アクティベーションのサポートだけではありません。同じくホステッド ビュー アクティベーション型のコントラクトに分類される共有ターゲット (英語)、File Save Picker (ファイル保存ピッカー) (英語)、Contact Picker (連絡先ピッカー) (英語)、Camera Settings (カメラ設定) (英語)、Print Task Settings (印刷タスク設定) (英語) のサポートを追加する際も、同じテクニックを使うことができます。

終わりに

今回の記事では、検索、ファイル選択ツールなどの Windows 8 のコントラクトのしくみについてご紹介しました。コントラクトでは、特定のタスクを行おうとしているユーザーを、システム内の他の部分や、シナリオによっては別のアプリからでも、あなたのアプリへと誘導することができます。ユーザーがアプリに期待するすばやく滑らかなエクスペリエンスを提供するには、Windows とアプリがともに、ユーザーの意図と目的のタスクを正しく認識する必要があります。コントラクトで優れたエクスペリエンスを作り出すためには、アプリのアクティベーションを正しく実装することが肝要です。コントラクトを使用せず、アプリのコア部分の開発だけを行っている場合でも、通常起動によるアクティベーションをセットアップする際には、今回ご紹介したヒントを覚えておくと効果的です。将来的にコントラクトをサポートするようアプリを拡張することになった場合も、コードを組み直すことなく、簡単に対応することができます。

覚えておくべきポイント

  1. 一般的なアプリ初期化ロジックがある場合は、アプリのアクティベーション方法と関係なく確実に実行される場所に配置します。
  2. アクティベーション ハンドラーは、アプリが既に起動している場合や中断状態の場合にも、実行される可能性があります。これによって意図しない影響が生じないよう注意してください。
  3. 検索、共有ターゲット、File Open Picker (ファイル オープン ピッカー) などのコントラクトをサポートする際は、Visual Studio のツーリングが便利です。プロジェクトを右クリックして、[Add] (追加) > [New Item] (新しいアイテム) を選択するだけで、必要な処理の多くが自動的に完了します。
  4. ホステッド ビュー アクティベーションを受けた場合は、アクティベーションの目的となっているタスクに必要なコードのみを読み込むようにします。

Windows 8 でのアクティベーションやコントラクトの詳細については、以下のリンクをご覧ください。また、Microsoft のフォーラム (英語) でご質問いただくこともできます。

ドキュメント

サンプル

お読みいただき、ありがとうございました。

Derek Gebhard
Windows User Experience (Windows ユーザー エクスペリエンス) 担当プログラム マネージャー

協力: Jake Sabulsky、Marco Matos、Daniel Oliver