8.1ストアアプリ向けに共有ターゲットを実装する方法を説明。ファイルを受け取る場合の問題点とその解決策を紹介する。共有ターゲットとしてWindowsストアアプリを作ると、共有コントラクトによって他のアプリからさまざまなデータを受け取れるようになる。共有ターゲットを実装する方法は、基本的にはMSDNのドキュメント「共有コンテンツの受信」に従えばよい。8.1)ではちょっとしたコツが必要だ。8.1でファイルを受け取る場合の問題点とその解決策を紹介する。8.1版)」からダウンロードできる。2012)が必要である。8(日本語版)*1を使用している。2013)が必要である。Windows(日本語版)*2を使用している。8」から無償で入手できる。Windows」から無償で入手できる。共有コントラクトとは?共有コントラクトとは、Windowsストアアプリ間のデータ交換をサポートする仕組みである。詳しくは次の記事を参照してほしい。Directによる近接通信(proximity)を使って2台のコンピューターを接続してデータを交換すること。本稿で扱う共有コントラクトとは別の仕組みである。tapping)を参照。エンドユーザーが共有チャームでデータを受け取るアプリ(=共有ターゲット)を指定すると、共有ターゲットがフライアウトとして右端から出てくる。これらの例のフライアウトの右上にある[送信]ボタン(「メール」アプリではアイコンになっている)をタップすると、共有ターゲットで実際にデータが処理される。Collection」から「メール」へ渡されるデータはTextとBitmap(データの種類については後述)。Solitaire側の[シェアする]ボタンに注目。MSDNのガイドラインでは「共有チャームを開くUIを設置するのは望ましくない」とされているが、この[シェアする]ボタンで共有チャームが開く。Explorer」から「リーディングリスト」へ渡されるデータはWebLink(Uri)とHTML。HTMLといってもページ全体ではなく、フライアウトの上部に表示されている記事タイトル/ロゴ/要約を記述したものである。「フード&レシピ」から「OneNote」へ渡されるデータはApplicationLink(Uri)/HTML/Text。フライアウトにはHTMLフォーマットで渡されたレシピが表示されている。「フォト」から「メール」へ渡されるデータはStorageItems(複数のファイル)。フライアウトには、4つの画像ファイルが表示されている。本稿では、この「メール」のように複数のファイルを受け取れる共有ターゲットの実装を説明する。本稿で扱うのは、共有ターゲット(=データを受け取る側)である。ほかのアプリにデータを送る」をご覧いただきたい。コントラクト]テンプレートを追加すればよい。Commonフォルダーにファイルが自動的に追加される共有ターゲットの実装に必要なファイルがプロジェクトのCommonフォルダーに不足している場合は、[追加]ボタンをクリックするとこの画像のようにメッセージボックスが表示される。[はい]ボタンをクリック。変更されたマニフェストテンプレートが追加されたら、マニフェスト(「Package.appxmanifesst」ファイル)を確認してほしい。[宣言]タブに[共有ターゲット]の宣言が追加されており、そのプロパティのデータ形式のところには[text]と[uri]が設定されている。この[データ形式]とその下の[サポートされるファイルの種類]は、必要に応じて修正することになる。以上で、このアプリは共有ターゲットとなり、「text」形式と「uri」形式の共有データを受け取れるようになった。textやuriを共有データとして送り出すアプリ(前述の例では「フォト」を除く3アプリ)を使用中にエンドユーザーが共有チャームを開くと、このアプリも共有ターゲットの1つとして列挙される。そこでエンドユーザーがこのアプリを選ぶと、テンプレートで追加された「ShareTargetPage1.xaml」ファイルがフライアウトとして表示され、そのコードビハインドのActivateメソッドが呼び出される。エンドユーザーがフライアウトの[Share]ボタン(前述の例では[送信]ボタンに相当)をタップすると、コードビハインドのShareButton_Clickメソッドが呼び出される。これら2つのメソッドは仮のものなので、必要な実装に修正すればよい。実装の指針としては、次のようにするとよいだろう。Activateメソッドではデータを全て受け取って、必要ならば自分が扱えるデータかチェックをし、フライアウト上にプレビューを表示するとともに、データをメンバー変数に格納する。ShareButton_Clickメソッドでは、受け取ったデータ(すでにメンバー変数に格納されている)を処理するだけにする。ShareButton_Clickメソッドでデータのチェックを行ってしまうと、エンドユーザーが[Share]ボタンをタップした後でエラーが出ることになってしまい、エンドユーザーをがっかりさせることになる。共有ターゲットが受け取るデータは、DataPackageViewクラス(Windows.ApplicationModel.DataTransfer名前空間)のオブジェクトである。DataPackageViewオブジェクトには、次の図のようにプロパティ(=Propertiesプロパティ)と実データが格納されている。共有する実際のデータ(=実データ)は、直接アクセスできない形で格納されている。DataPackageViewクラスには、フォーマットごとに実データを取り出すためのメソッドが用意されている。Propertiesプロパティには、実データに付随するプロパティ(データのタイトルや説明など)がセットされている。ここで、実データの種類としては、次の表に示すようなものが用意されている。IReadOnlyList>Windows.Storage.IStorageItem<型ファイルとフォルダーのリスト。Uri型WebLinkプロパティはWebで使われるhttpやhttpsプロトコルなど。ApplicationLinkプロパティは、アプリを起動するためのプロトコル(ms-windows-storeプロトコルなど)。8.1では警告は出るがUriプロパティも利用できる)実データの主な種類StandardDataFormatsクラス(Windows.ApplicationModel.DataTransfer名前空間)に定義されているものだけを示す。StorageItemsプロパティだけが複雑な型をしている。テキストやUriなどを受け取るには?実データが入っていることを確かめ、それぞれのフォーマットに応じたメソッドを使って取り出せばよい。コントラクト]テンプレートの追加により、マニフェストにはTextとUriが自動的に追加されている。あとは、Activateメソッドに次に示すコードを記述するだけである。ファイルを受け取るには?主な実データのうちでStorageItemsだけが複雑な型をしている。複数のファイルやフォルダーを受け渡しできる汎用的なものなのだが、その代わりに扱いがちょっと厄介だ。ここでは、「.png」と「.jpg」の2種類の画像ファイルだけを受け取れるようにする方法を解説する。共有ターゲットとして「.png」と「.jpg」のファイルを受け取ることを、マニフェストに追記する(次の画像)。マニフェストに「.png」と「.jpg」のファイルを受け取ることを追記するマニフェストの[宣言]タブの[共有ターゲット]の宣言を選び、[サポートされるファイルの種類]の下にある[新規追加]ボタンをクリックすると現れる[ファイルの種類]欄に「.jpg」と入力。その後、もう一度[新規追加]ボタンをクリックして、今度は「.png」と入力。次に、Activateメソッドの中でファイルを取り出す。GetStorageItemsAsyncメソッドでIStorageItemのオブジェクト(Windows.Storage名前空間)のリストが得られるので、IStorageItemのオブジェクトをStorageFileクラス(Windows.Storage名前空間)にキャストすればよい。ここでは、渡されたリストに含まれている最初のファイルの画像を自動生成されたコードのthumbnailImage変数(=BitmapImageオブジェクト)にセットしてみよう(次のコード)。8用)(上:C#、下:VB)太字の部分を追加する。Containsメソッドで目的のデータが入っていることを確かめるのは同じだが、GetStorageItemsAsyncメソッドで得られるものはIStorageItemオブジェクトのリストである。StorageFileクラスにキャストした上で、OpenReadAsyncメソッドでストリームを開き、それをthumbnailImage変数(=BitmapImageオブジェクト)に渡す。8.1上で実行しても問題無い)。8.1用のWindowsストアアプリではうまくいかない(次で説明する)。2013で作る)と、OpenReadAsyncメソッドを呼び出しているところで例外が発生する。8.1用のWindowsストアアプリの実行環境では、次のコードのようにして、OpenReadAsyncメソッドを呼び出してストリームを取得する処理の全体を別スレッドで動かす必要があるようだ。8.1用)(上:C#、下:VB)変更箇所のみを示す。上で説明したコードを応用して、共有フライアウトにTextとUri、および受け取った画像ファイルの全てを表示するようにしてみた(次の画像)。このソースコードを別途サンプルコードとして公開しているので、興味のある方はぜひそちらもご覧いただきたい。別途公開しているサンプルコードの実行例ただし、[Share]ボタンの実装はしていないので、共有データを受け取ってフライアウトに表示する以外は何もしない。2012用のC#のみ)。まとめ共有ターゲット側でファイルやフォルダーを受け取るには、DataPackageViewクラスのContainsメソッドを使って実データにStoregeItemsデータが入っていることを確かめ、同クラスのGetStorageItemsAsyncメソッドでIStorageItemオブジェクトのリストを取り出し、必要に応じてStorageFileクラスやStorageFolderクラスにキャストする。2013で作成するWindowsストアアプリ)では、ストリームを取り出す処理の全体を別スレッドで行わなければならない。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。