<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Windows 8 アプリ開発者ブログ</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/windowsappdev_ja/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/feed.xml</link>
    <description>Windows 8 エンジニアリング チームが語る Windows 8 向け Metro スタイル アプリの開発</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:28:49 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>promise の概要 (JavaScript による Windows ストア アプリ向け)</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/promise-javascript-windows</link>
      <pubDate>Wed, 26 Jun 2013 15:53:52 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/06/26/promise-javascript-windows/</guid>
      <description><![CDATA[Windows ストア アプリを JavaScript で記述する場合、非同期 API を含む処理を記述しようとすると、その種類にかかわらずすぐに promise (英語)...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>Windows ストア アプリを JavaScript で記述する場合、非同期 API を含む処理を記述しようとすると、その種類にかかわらずすぐに <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/Hh700339.aspx">promise</a> (英語) と呼ばれるコンストラクターに遭遇します。<i></i>間もなく、連続する非同期操作で自然にプロミスのチェーンを使うようになります。</p>  <p>また開発作業の中では、実際にどのような処理が行われているか完全には理解できないような promise の使用方法に出会うことも珍しくありません。そうした例が、<a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0">HTML ListView のパフォーマンス最適化のサンプル</a> (英語) にある、ListView コントロールのアイテム レンダリング関数の最適化です。これに関する記事も今後公開する予定ですが、//build 2012 で Josh Williams 氏が説明した <a href="https://channel9.msdn.com/Events/Build/2012/4-101">WinJS の Deep Dive</a> (英語) も参考になります (多少変更されています)。</p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">list.reduce(<span style="color: rgb(0, 0, 255);">function</span> callback (prev, item, i) {<br />    <span style="color: rgb(0, 0, 255);">var</span> result = doOperationAsync(item);<br />    <span style="color: rgb(0, 0, 255);">return</span> WinJS.Promise.join({ prev: prev, result: result}).then(<span style="color: rgb(0, 0, 255);">function</span> (v) {<br />        console.log(i + <span style="color: rgb(0, 96, 128);">&quot;, item: &quot;</span> + item+ <span style="color: rgb(0, 96, 128);">&quot;, &quot;</span> + v.result);<br />    });<br />})<br /></pre>
  </div>
</blockquote>

<p>このスニペットでは、プロミスを結合して非同期並行操作を実行し、その結果を list の順序に従って連続的に提供しています。<i></i>このコードを見て何をしているかがすぐに理解できる方は、この記事全体を飛ばしていただいて結構です。そうでない方は、promise の実際の動作と JavaScript 用 Windows ライブラリ (WinJS) での表記方法を詳しく見ていき、これらのパターンを理解できるようになりましょう。</p>

<h2>promise とは、"約束" によって関係が構築されること</h2>

<p>まずは、promise はコード コンストラクターまたは呼び出し規約に過ぎないという根本的な真実を押さえましょう。つまり promise は非同期操作に対する継承関係を持たないため、この点ではとても便利です。<i></i>promise は、将来のある時点で利用できる値、または既に利用できる値を表したオブジェクトに過ぎません。そのため、promise (約束) の使われ方は、私たちがこの言葉を日常生活で使う方法とまったく同じになります。"12 個のドーナッツを渡す約束" と言えば、私が今すぐドーナッツを 12 個持っている必要はありません。これは、将来のいつかの時点でドーナッツを入手するという意志があるという意味になります。<i></i>入手したら、それらを届けます。</p>

<p>2 つのエージェント間に関係があることを示しています。2 つのエージェントとは、品物を届けることを約束したオリジネーターと、約束の対象者であり品物の受領者であるコンシューマーです。<i><i></i></i>オリジネーターが品物を入手する方法は、オリジネーターに任されます。同様に、コンシューマーは、promise 自体と届いた品物を好きなように活用できます。たとえば、他のコンシューマーと promise を共有することもできます。</p>

<p>オリジネーターとコンシューマーの間の関係には "作成 (creation)" と "履行 (fulfillment)" という 2 つの段階があります。<i><i></i></i>このすべてのしくみは以下の図で説明できます。</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0844.promise_diagram_577C7B9B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0844.promise_5F00_diagram_5F00_577C7B9B.png"><img title="promise_diagram" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="promise_diagram" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0458.promise_diagram_thumb_0FBAF2B4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0458.promise_5F00_diagram_5F00_thumb_5F00_0FBAF2B4.png" width="700" height="341" /></a></p>

<p>図のフローを追っていくと、2 つの段階を持つ promise が非同期操作の提供と適切に連携できる理由を理解できます。重要な部分は、要求の確約 (promise) を受け取ったコンシューマーは、待機 (同期) せずにそれまでの処理を続行 (非同期) できるという点です。これは、コンシューマーが promise の履行を待ちながら、別の要求への応答など別の処理を実行できることを意味します。これは非同期 API の根本的な目的そのものです。既に品物を入手できる場合は promise がすぐに履行されるので、全体が同期呼び出し規約の一種に相当することになります。</p>

<p>もちろん、この関係の場合、考慮が必要なことは多少増えます。日常生活では、いくつかの約束を引き受け、自分に対してもいくつかの約束をしてもらいます。これらの約束の多くは果たされますが、多くの約束が果たされないこともまた現実です。注文したピザは、なんらかのアクシデントがあれば届けられません。日常生活でも非同期プログラミングにおいても、破られた約束は破られたものとして受け入れなければなりません。</p>

<p>これについて promise の関係で考慮すべきことは、1 つは、"ごめんなさい。この promise を履行できませんでした" というメッセージをオリジネーターがなんらかの方法で伝える必要があり、また、約束が破られたことをコンシューマーが何らかの方法で知る必要があること、2 つ目は、コンシューマーが promise の履行をいつでも気長に待てるとは限らないこと (このため、promise の履行の進行をオリジネーターが追跡できる場合、その情報を受け取る方法がコンシューマーにも必要です)、3 つ目は、コンシューマーは注文をキャンセルして、品物が不要になったことをオリジネーターに伝えてもかまわないことです。</p>

<p>これらの要件を追加すると、完全な関係図ができあがります。</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/4251.promise_diagram_2_23D40F3D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/4251.promise_5F00_diagram_5F00_2_5F00_23D40F3D.png"><img title="promise_diagram_2" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="promise_diagram_2" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0550.promise_diagram_2_thumb_1CB4D2C5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0550.promise_5F00_diagram_5F00_2_5F00_thumb_5F00_1CB4D2C5.png" width="700" height="432" /></a></p>

<p>では、この関係がコードではどのように表現されるかを見ていきましょう。</p>

<h2>promise コンストラクターと promise のチェーン</h2>

<p>promise については非常に多くの異なる提案がなされ、仕様が発表されています。Windows と WinJS が採用している <a href="http://wiki.commonjs.org/wiki/Promises/A">Common JS/Promises A</a> (英語) と呼ばれる仕様では、promise とは、将来提供する値を表現するためにオリジネーターが返すものであり、<b>then</b> と呼ばれる関数を持つオブジェクトであるとしています。コンシューマーは、<b>then</b> を呼び出すことによって promise の履行にサブスクライブします (Windows の promise は、同様の関数として <b>done</b> もサポートしています。promise のチェーンで使用されるこの関数については、後ほど簡単に説明します)。</p>

<p>この関数に対して、コンシューマーは最大 3 つのオプションの関数を以下の順序で渡すことができます。</p>

<ol>
  <li>completed ハンドラー: オリジネーターは promise された値が利用可能になった場合にこの関数を呼び出します。また、この値が既に利用可能な場合、<b>then</b> からすぐに (同期的に) completed ハンドラーが呼び出されます。<i></i><i></i></li>

  <li>error ハンドラー (オプション): promise された値を取得できなかった場合に呼び出されます。<i></i>あらゆる promise では、error ハンドラーが呼び出された場合 completed ハンドラーはいかなる場合も呼び出されません。</li>

  <li>progress ハンドラー (オプション): 中間結果と共に定期的に呼び出されます (操作がサポートしている場合。WinRT では、この API に <b>IAsync[Action | Operation]WithProgress</b> の戻り値がある場合はサポートしており、<b>IAsync[Action | Operation]</b> の場合はサポートしていません)。<i></i></li>
</ol>

<p>error ハンドラーだけをアタッチし completed ハンドラーをアタッチしない場合は、これらの引数に null を渡すことができます。<i></i></p>

<p>この関係では、コンシューマーは <b>then</b> を複数呼び出すことによって、同じ promise に任意の数の promise をサグスクライブすることができます。さらに promise を、重要コンテンツに対して <b>then</b> を呼び出す別のコンシューマーと共有することもできます。この処理は完全にサポートされています。</p>

<p>これは、promise が、受け取るすべてのハンドラーのリストを管理し、適切なタイミングで呼び出す必要があるということです。さらに promise は、完全な関係の図で説明したキャンセルにも対応する必要があります。</p>

<p>その他 Promises A 仕様には、<b>then</b> メソッド自身が promise を返すという要件も規定しています。<i></i>この 2 つ目の promise は、最初の <b>promise.then</b> に付与された completed ハンドラーが返され、この 2 つ目の promise の結果として戻り値が提供された時点で履行されます。以下のコード スニペットをご確認ください。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> promise1 = someOperationAsync();<br /><span style="color: rgb(0, 0, 255);">var</span> promise2 = promise1.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler1 (result1) { <span style="color: rgb(0, 0, 255);">return</span> 7103; } );<br />promise2.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler2 (result2) { });<br /></pre>
  </div>
</blockquote>

<p>ここでは、<b>someOperationAsync</b> が開始され promise1 が返されることで実行が連結されます。<i></i>操作の実行中に <b>promise1.then</b> を呼び出すと、その直後に promise2 が返されます。<i></i>非同期操作の結果が既に利用可能な場合を除き、<b>completedHandler1</b> は呼び出されないことに注意してください。ここでは引き続き待機している状態と仮定します。すぐに <b>promise2.then</b> の呼び出しに移りますが、この時点でも completedHandler2 は呼び出されません。<i></i></p>

<p>しばらくして <b>someOperationAsync</b> がたとえば値 14618 にて完了します。これで promise1 が履行されるため、この値で <b>completedHandler1</b> を呼び出し、result1 が 14618 になります。今度は <b>completedHandler1</b> が実行され、値 7103 を返します。この時点で promise2 が履行され、<b>completedHandler2</b> が (7103 に等しい) result2 で呼び出されます。<i></i><i></i><i></i><i></i></p>

<p>では、completed ハンドラーが別の promise を返した場合について説明します。この場合は処理が多少変わります。上記のコードの <b>completedHandler1</b> が以下のような promise を返した場合を考えてみます。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> promise2 = promise1.then(<span style="color: rgb(0, 0, 255);">function</span> completedHandler1 (result1) {<br />    <span style="color: rgb(0, 0, 255);">var</span> promise2a = anotherOperationAsync();<br />    <span style="color: rgb(0, 0, 255);">return</span> promise2a;<br />});<br /></pre>
  </div>
</blockquote>

<p>この場合、<b>completedHandler2</b> の result2 は promise2a そのものではなく、promise2a が<u>履行</u>された値です。<i></i><i></i><i></i>つまり、completed ハンドラーが promise を返すため、<b>promise1.then</b> から返される promise2 は、promise2a の結果によって履行されます。<i></i><i></i></p>

<p>連続する非同期操作の連結を可能にしているのは、チェーンに含まれる各操作の結果が次の操作に適用されるという、まさにこの特性です。中間変数や名前付きハンドラーがない場合に多く見られるのは、以下のようなパターンの promise チェーンです。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">operation1().then(<span style="color: rgb(0, 0, 255);">function</span> (result1) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation2(result1)<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result2) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation3(result2);<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result3) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation4(result3);<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result4) {<br />    <span style="color: rgb(0, 0, 255);">return</span> operation5(result4)<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (result5) {<br />    <span style="color: rgb(0, 128, 0);">//And so on</span><br />});<br /></pre>
  </div>
</blockquote>

<p>各 completed ハンドラーは、それぞれが受け取る結果を使用してさらに何かを実行する場合がほとんどですが、あらゆるチェーンの基本的な構造はこのようになります。また、ここにあるすべての <b>then</b> メソッドは、順番に実行され、特定の completed ハンドラーの保存と別の promise を返すという処理を行っています。このため、このコードの末尾に到達するまでに開始されているのは operation1 だけで、completed ハンドラーは 1 つも呼び出されていません。<i></i>しかし、すべての <b>then</b> 呼び出しからの中間 promise が多数作成され、相互に関連付けられることによって、チェーンが管理され連続的な操作が進行しています。</p>

<p>後続の操作を直前の completed ハンドラー内に入れ子にすることで、同様のシーケンスを実現できる点に注目してください。この場合はすべての return ステートメントを使いません。<i></i>ただし、このような入れ子処理は、特に <b>then</b> への呼び出しの 1 つひとつに progress ハンドラーと error ハンドラーを追加するような場合、インデントが非常に複雑になります。</p>

<p>また、WinJS の promise の機能では、チェーンのあらゆる部分で発生したエラーは、チェーンの末尾まで自動で伝播します。これは、<b>then</b> の最後の呼び出しに error ハンドラーを 1 つアタッチするだけで、すべてのレベルにハンドラーを設定する必要がなくなるということです。ただし、チェーンの最後のリンクが <b>then</b> への呼び出しである場合、このような要求は、さまざまな理由によって消去されてしまいます。このため WinJS では promise に <b>done</b> メソッドを用意しています。このメソッドは <b>then</b> と同じ引数を受け入れますが、示すのはチェーンの完了です (別の promise ではなく undefined を返します)。<i></i>その後、チェーン全体のあらゆるエラーに対して、<b>done</b> にアタッチされたすべての error ハンドラーが呼び出されます。さらに、error ハンドラーが足りないことで、<b>done</b> はアプリケーション レベルで例外をスローし、この例外は <b>WinJS.Application.onerror</b> イベントの <b>window.onerror</b> によって処理されます。つまり、例外が特定され適切に処理されるためには、すべてのチェーンが <b>done</b> で終わることが理想的です。</p>

<p>もちろん、長い <b>then</b> 呼び出しチェーンから最後の promise を返すことを目的とする関数を記述する場合、末尾に <b>then</b> を使用します。この場合のエラー処理は、その promise を別のチェーンで使用する呼び出し元が引き受けます。<i></i></p>

<h2>promise の作成: WinJS.Promise クラス</h2>

<p>Promises A 仕様に基づき独自の promise クラスはいつでも作成できますが、非常に煩雑な作業になるため、ライブラリがあれば便利です。<i></i>WinJS には堅牢かつ入念にテストされた、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211867.aspx"><b>WinJS.Promise</b></a> (英語) と呼ばれる柔軟な promise クラスがあります。これを活用することで、オリジネーター/コンシューマーの関係や <b>then</b> の動作を詳細に管理せずに、さまざまな値と操作の promise を簡単に作成できるようになります。</p>

<p>非同期操作と既存の (同期的な) 値の両方について promise を作成する際には、必要に応じて <b>new WinJS.Promise</b> またはヘルパー関数 (次のセクションで説明) を使用できます (使用する必要があります)。改めて、promise はコード コンストラクターに過ぎません。promise が非同期操作を含むあらゆる非同期的な処理をラップしなければならないという要件はありません。<i></i>同様に、まれなケースとして promise のコードの一部をラップしても、それらが自動的に非同期で実行されることはなく、個別に対応する必要があります。<i></i><i></i></p>

<p><b>WinJS.Promise</b> を直接使用する簡単な例として、処理の長い計算を考えてみます。ここでは 1 から順に特定の最大値まで数字を追加していく計算を、非同期で実行します。このような定形処理には独自のコールバック メカニズムを作成することもできますが、promise にラップすることで、この promise をその他の API からの別の promise と連結または結合できます (ここでは、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229787.aspx"><b>WinJS.xhr</b></a> (英語) 関数が JavaScript の非同期の <b>XmlHttpRequest</b> をラップするため、別の promise の特定のイベント構造は無視できます)。</p>

<p>処理の長い計算にはもちろん JavaScript ワーカーを使用できますが、説明上の都合から、JavaScript ワーカーは UI スレッド上に保持し、<b>setImmediate</b> を使用して操作を複数のステップに分割します。<b>WinJS.Promise</b> を使用して promise の構造内に実装する方法を以下に示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> calculateIntegerSum(max, step) {<br />    <span style="color: rgb(0, 128, 0);">//The WinJS.Promise constructor's argument is an initializer function that receives </span><br />    <span style="color: rgb(0, 128, 0);">//dispatchers for completed, error, and progress cases.</span><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />        <span style="color: rgb(0, 0, 255);">var</span> sum = 0;<br /><br />        <span style="color: rgb(0, 0, 255);">function</span> iterate(args) {<br />            <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = args.start; i &lt; args.end; i++) {<br />                sum += i;<br />            };<br /><br />            <span style="color: rgb(0, 0, 255);">if</span> (i &gt;= max) {<br />                <span style="color: rgb(0, 128, 0);">//Complete--dispatch results to completed handlers</span><br />                completeDispatch(sum);<br />            } <span style="color: rgb(0, 0, 255);">else</span> {<br />                <span style="color: rgb(0, 128, 0);">//Dispatch intermediate results to progress handlers</span><br />                progressDispatch(sum);<br />                setImmediate(iterate, { start: args.end, end: Math.min(args.end + step, max) });<br />            }<br />        }<br />            <br />        setImmediate(iterate, { start: 0, end: Math.min(step, max) });<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p><b>new WinJS.Promise</b> を呼び出す際のコンストラクターは initializer 関数 (この場合は非同期) です。<i></i>実行する操作は initializer によってカプセル化されますが、この関数自体は UI スレッド上で同期的に実行されます。<i></i>このため、ここで <b>setImmediate</b> を使用せずに長い時間の計算を実行する場合は、UI スレッドを常にブロックします。繰り返しになりますが、promise 内にコードを配置しても自動的に非同期で実行されるようにはなりません。initializer 関数で個別に設定する必要があります。<i></i></p>

<p>引数については、initializer 関数は、promise がサポートする、完了 (completed)、エラー (error)、進行中 (progress) に対応した 3 種類のディスパッチャーを受け取ります。<i></i>コードを見るとわかるように、これらのディスパッチャーが、操作の適切なタイミングで適切な引数によって呼び出されています。</p>

<p>これらの関数を "ディスパッチャー" と呼ぶ理由は、コンシューマーが promise の <b>then</b> メソッド (<b>done</b> もですが、以降は省略します) にサブスクライブするハンドラーとは異なるためです。内部的には、これらのハンドラーを WinJS が複数管理することで、任意の数のコンシューマーによる任意の数のハンドラーのサブスクライブが可能になっています。これらのディスパッチャーのいずれかを呼び出すと、WinJS は内部リストを反復処理し、これらのハンドラーすべてをユーザーに代わって呼び出します。また、連結を実現するために必要な別の promise を <b>then</b> が確実に返すようになるのも、<b>WinJS.Promise</b> があるためです。</p>

<p>まとめると、<b>WinJS.Promise</b> は、promise に伴う細かな処理をすべて提供しています。これによってユーザーは、initializer 関数に埋め込まれた、promise が示す重要な操作だけに集中できるようになります。</p>

<h2>promise 作成用のヘルパー</h2>

<p>promise を作成する主なヘルパー関数は、promise 内のすべての値をラップする静的メソッド <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211664.aspx"><b>WinJS.Promise.as</b></a> (英語) です。<i></i>既存の値に適用されたラッパーは、挙動を変え、<b>then</b> に渡されたすべての completed ハンドラーを呼び出します。これによって、既知の任意の値を promise として扱い、これらをその他の promise と (結合または連結を通して) 混合および組み合わせられるようになります。既存の promise に <b>as</b> を使用すると、その promise だけが返されます。</p>

<p>もう 1 つの静的ヘルパー関数は、<b>setTimeout</b> と <b>setImmediate</b> に関する便利なラッパーを提供する <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229729.aspx"><b>WinJS.Promise.timeout</b></a> (英語) です。特定のミリ秒以内に履行されない場合に 2 つ目の promise をキャンセルする promise を作成することも可能です。</p>

<p><b>setTimeout</b> および <b>setImmediate</b> に関する <b>timeout</b> promise は、undefined によって履行される点に注意してください。<i></i>このとき、これらを使用して、タイムアウト後に別の結果を提供するためにはどうすればよいかという疑問が浮かびます。この疑問に対する回答には、<b>then</b> が、completed ハンドラーの戻り値で履行される別の promise を返すという事実が使用されます。このコード行の例を以下に示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> p = WinJS.Promise.timeout(1000).then(<span style="color: rgb(0, 0, 255);">function</span> () { <span style="color: rgb(0, 0, 255);">return</span> 12345; });</pre>
  </div>
</blockquote>

<p>ここでは promise "p" が 1 秒後に値 12345 によって履行されます。<i></i>言い換えると、<b>WinJS.Promise.timeout(…).then(function () { return &lt;value>} )</b> のパターンによって、規定されたタイムアウトの後に &lt;value> が提供されます。<i></i>&lt;value> 自身が別の promise の場合は、タイムアウト後の特定時点における、その promise の履行値が提供されることになります。<i></i></p>

<h2>キャンセルと promise エラーの生成</h2>

<p>これまで見てきたコードでは、足りない点が 2 つあることにお気付きかもしれません。1 つ目は開始された操作をキャンセルする方法がないこと、2 つ目はエラーの処理が洗練されているとは言えないことです。</p>

<p>これら両方の原因は、promise を生成する <b>calculateIntegerSum</b> などの関数が常に promise を返す必要があるということです。操作が完了できない、または操作が最初に開始されない場合、その promise はエラー状態にあります。<i></i>これは、呼ばれるのは error ハンドラーだけで、任意の completed ハンドラーに渡すことができる結果を promise が得られず、これからも得られないということを意味します。<i></i>実際、コンシューマーが既にエラー状態にある promise で <b>then</b> を呼び出すと、promise はすぐに (同期的に) <b>then</b> に付与された error ハンドラーを呼び出します。</p>

<p><b>WinJS.Promise</b> は、コンシューマーが <b>cancel</b> メソッドを呼び出すか、initializer 関数内のコードが error ディスパッチャーを呼び出すという 2 つの理由でエラー状態になります。エラーが発生すると、promise でどのようなエラー値が取得または伝播されたかに関係なく、error ハンドラーが付与されます。<b>WinJS.Promise</b> 内で操作を作成している場合、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211689.aspx"><b>WinJS.ErrorFromName</b></a> (英語) のインスタンスを使用することも可能です。これは、エラーを特定する name プロパティと詳細情報を格納する message プロパティを含む単なる JavaScript オブジェクトです。<i></i><i></i>たとえば promise がキャンセルされると、error ハンドラーは、name と message の名前の両方が "Canceled" に設定されたエラー オブジェクトを受け取ります。<i></i><i></i></p>

<p>では、操作を最初に開始できない場合はどうすればよいのでしょうか。たとえば <b>calculateIntegerSum</b> を無効な引数 (0, 0 など) で呼び出した場合、カウントの開始さえ試行されずに、エラー状態の promise が返されます。静的メソッド <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229784.aspx"><b>WinJS.Promise.wrapError</b></a> (英語) はこのような場合に使用します。ここでは、<b>WinJS.ErrorFromName</b> のインスタンスを使用して、この場合は新しい <b>WinJS.Promise</b> インスタンスの代わりに、エラー状態の promise を返します。</p>

<p>これについてもう 1 つ重要なのが、promise の <b>cancel</b> メソッドへの呼び出しによって promise 自身がエラー状態になる一方で、進行している非同期操作はどのように停止できるのかという疑問です。前述の <b>calculateIntegerSum</b> の実装では、作成した promise の状態に関係なく、操作が完了するまで <b>setImmediate</b> の呼び出しが継続されます。実際、promise のキャンセル後に操作によって complete ディスパッチャーが呼び出された場合、promise はその完了を無視します。</p>

<p>ここで求められるのは、処理を続行する必要がなくなったことを promise から操作に伝える方法です。このために <b>WinJS.Promise</b> コンストラクターは、promise がキャンセルされると呼び出される、関数の 2 つ目の引数を使用します。今回の例では、この関数への呼び出しによって <b>setImmediate</b> に対する次の呼び出しを防止し、計算を停止する必要があります。この処理を、適切なエラー処理と共に以下に示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> calculateIntegerSum(max, step) {<br />    <span style="color: rgb(0, 128, 0);">//Return a promise in the error state for bad arguments</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (max &lt; 1 || step &lt; 1) {<br />        <span style="color: rgb(0, 0, 255);">var</span> err = <span style="color: rgb(0, 0, 255);">new</span> WinJS.ErrorFromName(<span style="color: rgb(0, 96, 128);">&quot;calculateIntegerSum&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;max and step must be 1 or greater&quot;</span>);<br />        <span style="color: rgb(0, 0, 255);">return</span> WinJS.Promise.wrapError(err);<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">var</span> _cancel = <span style="color: rgb(0, 0, 255);">false</span>;<br /><br />    <span style="color: rgb(0, 128, 0);">//The WinJS.Promise constructor's argument is an initializer function that receives </span><br />    <span style="color: rgb(0, 128, 0);">//dispatchers for completed, error, and progress cases.</span><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />        <span style="color: rgb(0, 0, 255);">var</span> sum = 0;<br /><br />        <span style="color: rgb(0, 0, 255);">function</span> iterate(args) {<br />            <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = args.start; i &lt; args.end; i++) {<br />                sum += i;<br />            };<br /><br />            <span style="color: rgb(0, 128, 0);">//If for some reason there was an error, create the error with WinJS.ErrorFromName</span><br />            <span style="color: rgb(0, 128, 0);">//and pass to errorDispatch</span><br />            <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">false</span> <span style="color: rgb(0, 128, 0);">/* replace with any necessary error check -- we don’t have any here */</span>) {<br />                errorDispatch(<span style="color: rgb(0, 0, 255);">new</span> WinJS.ErrorFromName(<span style="color: rgb(0, 96, 128);">&quot;calculateIntegerSum (scenario 7)&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;error occurred&quot;</span>));<br />            }<br /><br />            <span style="color: rgb(0, 0, 255);">if</span> (i &gt;= max) {<br />                <span style="color: rgb(0, 128, 0);">//Complete--dispatch results to completed handlers</span><br />                completeDispatch(sum); <br />            } <span style="color: rgb(0, 0, 255);">else</span> {<br />                <span style="color: rgb(0, 128, 0);">//Dispatch intermediate results to progress handlers</span><br />                progressDispatch(sum);<br /><br />                <span style="color: rgb(0, 128, 0);">//Interrupt the operation if canceled</span><br />                <span style="color: rgb(0, 0, 255);">if</span> (!_cancel) {<br />                    setImmediate(iterate, { start: args.end, end: Math.min(args.end + step, max) });<br />                }<br />            }<br />        }<br />            <br />        setImmediate(iterate, { start: 0, end: Math.min(step, max) });<br />    },<br />    <span style="color: rgb(0, 128, 0);">//Cancellation function for the WinJS.Promise constructor</span><br />    <span style="color: rgb(0, 0, 255);">function</span> () {<br />        _cancel = <span style="color: rgb(0, 0, 255);">true</span>;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>総括すると、<b>WinJS.Promise</b> のインスタンスを作成することで、さまざまな使用方法が提供されます。たとえば、その他の非同期的手法で Web サービスを利用するライブラリがある場合、これらの操作を promise にラップすることができます。また、新しい promise を使用して、ソースの異なる複数の非同期操作 (または別の promise) を 1 つの promise に結合し、すべての関係を管理することができます。<b>WinJS.Promise</b> の initializer のコード内では、その他の非同期操作とその promise のハンドラーを独自に設定できます。これらを使用することで、ネットワーク タイムアウトなどを自動で再試行するメカニズムのカプセル化や、進行状況を示す汎用の UI の呼び出し、内部的なログ記録や分析の追加が可能になります。これらのすべてでは、処理の詳細をコードの残りの部分が認識する必要はなく、コンシューマーの立場で promise に対応するだけで問題ありません。</p>

<p>また、JavaScript ワーカーを promise にラップして、WinRT のその他の非同期操作と同様の外観と動作を与えることも簡単です。ご存知のように、ワーカーでは、<b>postMessage</b> 呼び出しによってアプリのワーカー オブジェクトに <b>message</b> イベントを発生させることで結果を提供します。以下のコードでは、このメッセージで提供される結果にかかわらず履行される promise に、このイベントをリンクさせています。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// This is the function variable we're wiring up.</span><br /><span style="color: rgb(0, 0, 255);">var</span> workerCompleteDispatch = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br /><span style="color: rgb(0, 0, 255);">var</span> promiseJS = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (completeDispatch, errorDispatch, progressDispatch) {<br />    workerCompleteDispatch = completeDispatch;<br />});<br /><br /><span style="color: rgb(0, 128, 0);">// Worker is created here and stored in the 'worker' variable</span><br /><br /><span style="color: rgb(0, 128, 0);">// Listen for worker events</span><br />worker.onmessage = <span style="color: rgb(0, 0, 255);">function</span> (e) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (workerCompleteDispatch != <span style="color: rgb(0, 0, 255);">null</span>) {<br />        workerCompleteDispatch(e.data.results); <span style="color: rgb(0, 128, 0);">/* event args depends on the worker */</span><br />    }<br />}<br /><br />promiseJS.done(<span style="color: rgb(0, 0, 255);">function</span> (result) {<br />    <span style="color: rgb(0, 128, 0);">// Output for JS worker</span><br />});<br /></pre>
  </div>
</blockquote>

<p>このコードを拡張してワーカーのエラー処理を含めることで、その他の変数における error ディスパッチャーを省略し、<b>message</b> イベント ハンドラーによるイベント引数のエラー情報のチェックを実行し、complete ディスパッチャーの代わりに必要に応じて error ディスパッチャーを呼び出せるようになります。</p>

<h2>並列した promise の結合</h2>

<p>promise は多くの場合非同期操作のラップに使用されるため、複数の操作を並行して実行することが可能です。この場合に知る必要があるのは、グループ内のいずれか 1 つの promise が履行されるタイミング、またはグループ内のすべての promise が履行されるタイミングです。これを可能にするのが、静的関数 <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229660.aspx"><b>WinJS.Promise.any</b></a> (英語) および <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211774.aspx"><b>WinJS.Promise.join</b></a> (英語) です。</p>

<p>これらの関数は値の配列または値のプロパティが設定されたオブジェクトを受け入れます。これらの値は promise にすることができ、promise 以外の値は <b>WinJS.Promise.any</b> によってラップされ、配列またはオブジェクト全体が promise による構成になります。</p>

<p><b>any</b> の特性を以下に示します。</p>

<ul>
  <li><b>any</b> によって 1 つの promise が作成されます。この promise は、その他の promise の 1 つが履行された場合またはエラーによって失敗した場合に履行されます (論理 OR)。基本的には、<b>any</b> は、これらすべての promise に completed ハンドラーをアタッチし、1 つの completed ハンドラーが呼び出された直後に、<b>any</b> の promise 自身が受け取ったすべての completed ハンドラーを呼び出します。<i></i><i></i></li>

  <li><b>any</b> の promise が履行された後 (リスト内の最初の promise が履行された後)、リスト内のその他の操作は実行を継続し、これらの promise に個別に割り当てられている completed、error、または progress の各ハンドラーを呼び出します。<i></i></li>

  <li><b>any</b> からの promise をキャンセルした場合は、リスト内のすべての promise がキャンセルされます。</li>
</ul>

<p><b>join</b> の特性を以下に示します。</p>

<ul>
  <li><b>join</b> によって 1 つの promise が作成されます。この promise は、その他のすべての promise が履行された場合またはエラーによって失敗した場合に履行されます (論理 AND)。<i></i>基本的には、<b>join</b> は、これらすべての promise に completed ハンドラーと error ハンドラーをアタッチし、これらすべてのハンドラーが呼び出されるのを待機し、その後、自身が受け取るすべての completed ハンドラーを呼び出します。<i></i></li>

  <li><b>join</b> の promise は提供されたすべての progress ハンドラーに進行状況をレポートします。この場合の中間結果は、これまで履行された個々の promise の結果の配列となります。</li>

  <li><b>join</b> からの promise をキャンセルした場合は、保留中のその他すべての promise がキャンセルされます。</li>
</ul>

<p><b>any</b> と <b>join</b> に加えて、簡単に使用できる以下 2 つの静的 <b>WinJS.Promise</b> メソッドを覚えておくと便利です。</p>

<ul>
  <li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211765.aspx"><b>is</b></a> (英語): 任意の値が promise かどうかを、ブール値を返すことで判定します。基本的には、"then" の名前を持つ関数が設定されたオブジェクトかどうかを確認し、"done" の場合のテストは実行しません。</li>

  <li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229727.aspx"><b>theneach</b></a><i> </i> (英語): completed、error、および progress の各ハンドラーを (<b>then</b> を使用して) promise のグループに適用し、promise 内の別の値のグループとして結果を返します。いずれのハンドラーでも null が許可されます。<i></i></li>
</ul>

<h2>並列した promise の連続的な結果</h2>

<p><b>WinJS.Promise.join</b> および <b>WinJS.Promise.any</b> によって、並列した promise による作業、つまり非同期並行操作が可能になります。<b>join</b> によって返される promise が履行されるのは、配列内のすべての promise が履行されたときです。ただし、これらの promise は多くの場合ランダムな順序で履行されます。ここで、このように実行できる一連の操作があるものの、その結果を処理する順序は詳細に定義したい (配列内に promise が表示される順序にしたい) 場合はどうすればよいでしょうか。 </p>

<p>これを実行するには、後続の promise を、直前のすべての promise の <b>join</b> に結合する必要があります。これは、この記事の最初に示したコードの一部を使用することで実現します。そのコードを改めて以下に示します。このコードは、promise を明示的にするための変更が行われています (list は、promise を生成する架空の非同期呼び出し <b>doOperationAsync</b> の引数として使用される値の配列とします)。<i></i><b></b></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">list.reduce(<span style="color: rgb(0, 0, 255);">function</span> callback (prev, item, i) {<br />    <span style="color: rgb(0, 0, 255);">var</span> opPromise = doOperationAsync(item);<br />    <span style="color: rgb(0, 0, 255);">var</span> join = WinJS.Promise.join({ prev: prev, result: opPromise});<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> join.then(<span style="color: rgb(0, 0, 255);">function</span> completed (v) {<br />        console.log(i + <span style="color: rgb(0, 96, 128);">&quot;, item: &quot;</span> + item+ <span style="color: rgb(0, 96, 128);">&quot;, &quot;</span> + v.result);<br />    });<br />})<br /></pre>
  </div>
</blockquote>

<p>このコードを理解するためには、配列の <a href="http://msdn.microsoft.com/ja-jp/library/ie/ff679975(v=vs.94).aspx"><b>reduce</b></a> (英語) メソッドがどのように動作するかを理解する必要があります。配列の各項目について、<b>reduce</b> は <b>callback</b> という関数の引数を呼び出し、4 つの引数を受け取ります (このコードでは 3 つのみ使用されています)。</p>

<ul>
  <li>prev: <b>callback</b> への以前の呼び出しから返された値です (最初の項目では null です)。<i></i><i></i><i></i></li>

  <li>item: 配列からの最新の値です。<i></i></li>

  <li>i: リスト内の項目のインデックスです。<i></i></li>

  <li>source: 元の配列です。<i></i></li>
</ul>

<p>リスト内の最初の項目では、<b>opPromise<sub>1</sub></b> と呼ばれる promise が取得されます。<b>prev</b> は null のため、<b>[WinJS.Promise.as(null), opPromise<sub>1</sub>]</b> を連結します。<i></i>ただし、<b>join</b> 自体が返されているわけではなく、completed ハンドラー (この場合 <b>completed</b>) を join にアタッチし、その <b>then</b> から promise を返しています。</p>

<p><b>then</b> から返される promise は completed ハンドラーが返されたときに履行されることを思い出してください。つまり、<b>callback</b> から返される promise は、<b>opPromise<sub>1</sub></b> の結果を最初の項目の <b>completed</b> ハンドラーが処理するまで完了しません。また、join の結果は、元のリストの promise 空の結果を含むオブジェクトによって履行されます。これは、履行値 v には prev プロパティと result プロパティの両方が格納され、result プロパティが <b>opPromise<sub>1</sub></b> の結果であるという意味です。<i></i><i></i><i></i></p>

<p>list の次の項目により、以前の <b>join.then</b> からの promise を含む prev を <b>callback</b> が受け取ります。<i></i><i></i>その後 <b>opPromise<sub>1</sub>.then</b> と <b>opPromise<sub>2</sub></b> の新しい結合が作成されます。その結果、この join は、<b>opPromise<sub>2</sub></b> が履行され、<b>opPromise<sub>1</sub></b> の completed ハンドラーが返された後に完了します。<i></i>これによって、この <b>join</b> にアタッチする <b>completed<sub>2</sub></b> ハンドラーが、<b>completed<sub>1</sub></b> が返されるまで呼び出されなくなります。</p>

<p>項目 n の <b>join.then</b> からの promise は <b>completed<sub>n</sub><i></i></b> が返るまで履行されないという依存関係を、リスト内の各アイテムに構築します。<i></i>これによって completed ハンドラーが、リストと同じ順序で呼び出されるようになります。<i></i></p>

<h2>終わりに</h2>

<p>この記事では、promise 自体は、多少強力ではあるものの、将来の任意の時点で値を提供するオリジネーターと、これらの値がいつ利用可能になるかを知りたいコンシューマーの間の固有の関係を示す、単なるコード コンストラクターまたは呼び出し規約に過ぎないということを確認しました。このような理由から、非同期操作の結果を示す場合に非常に便利な promise は、JavaScript で記述された Windows ストア アプリで幅広く活用されています。さらに promise の仕様では、連続する非同期操作を連結し、中間結果をリンク間で遷移させることも可能です。</p>

<p>JavaScript 用 Windows ライブラリ (WinJS) が提供する promise の強力な実装を活用することで、あらゆる操作を独自にラップすることができます。さらに WinJS は、並行操作を実現するための promise の結合などの共通シナリオのサポートにも対応しています。これらを活用することで、効率的かつ効果的な非同期操作を WinJS に基づき実行できるようになります。</p>

<p>Kraig Brockschmidt
  <br />- Windows エコシステム担当チーム、プログラム マネージャー

  <br />著書『<a href="http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx">HTML、CSS、JavaScript を使った Windows 8 アプリ開発<i></i></a>』(英語)</p>

<!-- Title: “promise の概要 (JavaScript による Windows ストア アプリ向け)” Tags: “JavaScript, Windows ストア アプリ, promise” --></div>]]></content:encoded>
    </item>
    <item>
      <title>ListView の項目レンダリングの最適化</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/listview</link>
      <pubDate>Tue, 25 Jun 2013 14:29:45 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/06/25/listview/</guid>
      <description><![CDATA[コレクションを利用する JavaScript を使って作成された Windows ストア アプリの場合、アプリのすばらしいパフォーマンスを実現するには、通常、WinJS ListView...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>コレクションを利用する <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211385.aspx" target="_blank">JavaScript を使って作成された Windows ストア アプリ</a>の場合、アプリのすばらしいパフォーマンスを実現するには、通常、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211837.aspx" target="_blank">WinJS ListView コントロール</a> (英語) とのスムーズな連携がきわめて重要です。これは意外なことではなく、数千個にもなり得る項目の管理と表示を処理する場合、項目に対するすべての最適化がものを言います。最も重要なことは、各項目がどのように表示されるか、つまり、ListView コントロール内の各項目がどのように、また、どのタイミングで、DOM によって組み立てられ、アプリの一部として表示されるかです。実際、このプロセスの "タイミング" の部分は、リスト内ですばやくパン操作を行った場合に、そのスピードに遅れずにリストの表示が変わることが期待されている場合は、特に重要な要素になります。<i></i></p>  <p>ListView 内でレンダリングされる項目は、HTML で定義された宣言型テンプレートか、リスト内の項目ごとに呼び出されるカスタムの JavaScript "レンダリング関数" によって処理されます。<i></i>宣言テンプレートを使う方法が最も簡単ですが、このプロセスに対して特定の制御を行う場合の自由度は限られます。一方、レンダリング関数を使うと、項目ごとにレンダリングをカスタマイズでき、<a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0" target="_blank">HTML ListView パフォーマンス最適化のサンプル</a> (英語) に実装されているように、複数の最適化が可能です。この関数では、次のような最適化を実現できます。</p>  <ul>   <li>項目データと表示要素の非同期配信の実現。これには、基本のレンダリング関数を使用します。</li>    <li>ListView の全体的なレイアウトを決めるために必要な、項目の形状の作成と、内部の要素との分離。これには、プレースホルダー レンダラーを使用します。</li>    <li>以前作成した項目要素 (とその子) のデータを置き換えて再利用。要素作成の大半のステップを省略できます。これには、プレースホルダー再利用レンダラーを使用します。</li>    <li>項目が表示され、ListView のパン操作のスピードが落ち着くまで、イメージの読み込みやアニメーションなど、負荷の高いビジュアル操作の遅延。これには、多段階レンダラーを使用します。</li>    <li>同じビジュアル操作をまとめて、DOM の再レンダリングを最小限に抑制。これには、多段階レンダラーを使用します。</li> </ul>  <p>この記事では、上記の全ステージを取り上げ、各ステージが ListView の項目レンダリング プロセスとどのように連携するかを説明します。お察しのとおり、項目をレンダリングするタイミングの最適化には、非同期操作、ひいては promise を多用します。<i></i>したがって、この記事を読み進むにつれて、promise 自体の理解も、このブログの前回の記事「<a href="http://blogs.msdn.com/b/windowsappdev/archive/2013/06/10/all-about-promises-for-windows-store-apps-written-in-javascript.aspx" target="_blank">promise の詳細</a>」(英語) の知識からさらに深めることができます。</p>  <p>すべてのレンダラーに言えることですが、常に、中心となる項目のレンダリング時間 (遅延操作を除く) を最小限に抑えることが重要です。ListView の最終的なパフォーマンスは、ListView の更新と画面の更新間隔がどの程度同期するかに大きく左右されるため、1 つの項目レンダラーで数ミリ秒余分にかかると、次の画面の更新までの間の ListView 全体のレンダリング時間が増大し、結果としてフレーム落ちや画面の乱れが発生します。つまり、項目レンダラーは、JavaScript コードの最適化を図る場合、本当に有効な領域です。</p>  <h2>基本レンダラー</h2>  <p>まず、項目レンダリング機能 (以降は、シンプルに "レンダラー" と呼びます) とはどのようなものかを簡単に確認しましょう。<i></i>レンダラーは、テンプレート名の代わりに、ListView の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh700705.aspx" target="_blank">itemTemplate</a> (英語) プロパティに割り当てられる関数で、この関数は ListView から DOM に追加される項目に対して、必要に応じて呼び出されます (レンダラーの基本的な情報については、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh700705.aspx" target="_blank">itemTemplate</a> を参照してください。ただし、この最適化が本当によくわかるのはサンプルの方です)。</p>  <p>項目レンダリング関数は、単純に ListView のデータ ソースから項目が渡されたら、その特定の項目に必要な HTML 要素を作成し、ListView が DOM に追加できるルート要素を返すと思われるでしょうか。基本的にはそうですが、さらに 2 点、考慮することがあります。まず、項目データ自体が非同期に読み込まれる可能性があるため、要素の作成をそのデータが提供されるタイミングに合わせる方がよいでしょう。また、項目自体のレンダリング プロセスには、リモート URI からのイメージの読み込みや、項目データで指定されている他のファイルのデータの読み取りなど、他の非同期作業も含まれる場合があります。この記事で説明するさまざまなレベルの最適化では、実際、項目の要素が要求されてから、要求された項目が実際に提供されるまでの非同期の度合いを自由に決定できます。</p>  <p>したがって、やはり、promise が使われると予測できます。まず、ListView では項目データを直接レンダラーに渡さず、そのデータの promise を提供します。また、項目のルート要素を直接返す関数の代わりに、その要素の promise を返します。この方法により、ListView ではさまざまな項目レンダリング promise を組み合わせて、ページ全体の項目がレンダリングされるまで、(非同期に) 待機できます。実際、このように処理することで、ListView では複数のページの作成方法を管理しています。まず、表示される項目のページを作成したら、ユーザーのパン操作の結果、この次に表示されると思われる前後の 2 種類のページを非表示で作成します。また、このような promise をすべて用意しておけば、ユーザーのパン操作によって画面が変わった場合、表示が完了していない項目のレンダリングを ListView によって簡単にキャンセルでき、無駄な要素作成を行わずに済みます。</p>  <p>これらの promise の使用方法は、サンプルの <b>simpleRenderer</b> 関数を見るとわかります。</p>  <p> </p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> simpleRenderer(itemPromise) {<br />    <span style="color: rgb(0, 0, 255);">return</span> itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />        <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />        element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;img src='&quot;</span> + item.data.thumbnail +<br />            <span style="color: rgb(0, 96, 128);">&quot;' alt='Databound image' /&gt;&lt;div class='content'&gt;&quot;</span> + item.data.title + <span style="color: rgb(0, 96, 128);">&quot;&lt;/div&gt;&quot;</span>;<br />        <span style="color: rgb(0, 0, 255);">return</span> element;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>このコードでは、最初に、completed ハンドラーを <b>itemPromise</b> にアタッチしています。ハンドラーは、項目データが提供され、それを受けて要素が実際に作成された時点で呼び出されます。ただし、実は要素を直接返さず、その要素がフルフィルメント (提供) される promise を返していることに、改めて注意してください。つまり、<b>itemPromise.then()</b> からの戻り値は、ListView によって要素が必要になった場合に必要なタイミングで、"element"<i></i> がフルフィルメントされる promise です。</p>

<p>promise を返すことで、必要に応じて他の非同期作業を実行できます。この場合は、レンダラーは単に中間の promise をチェーンにまとめ、チェーン内の最後の <b>then</b> から promise を返しています。以下に例を示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> someRenderer(itemPromise) {<br />    <span style="color: rgb(0, 0, 255);">return</span> itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />        <span style="color: rgb(0, 0, 255);">return</span> doSomeWorkAsync(item.data);<br />    }).then(<span style="color: rgb(0, 0, 255);">function</span> (results) {<br />        <span style="color: rgb(0, 0, 255);">return</span> doMoreWorkAsync(results1);<br />    }).then(<span style="color: rgb(0, 0, 255);">function</span> (results2) {<br />        <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        <span style="color: rgb(0, 128, 0);">// use results2 to configure the element</span><br />        <span style="color: rgb(0, 0, 255);">return</span> element;<br />    });<br />}<br /></pre>
  </div>
</blockquote>

<p>これは、最後の <b>then</b> 呼び出しから promise を返しているので、チェーンの最後に <b>done</b> を使わないケースになります。<i></i>エラーが発生した場合は、ListView によってエラーは処理されます。</p>

<h2>プレースホルダー レンダラー</h2>

<p>ListView の最適化の次の段階では、要素の作成を 2 段階に分ける "プレースホルダー レンダラー" を使います。<i></i>このレンダラーを使うことで、ListView から、リスト全体のレイアウトの定義に必要な要素の部分のみを要求でき、各項目内の要素すべてを作成する必要がありません。その結果、ListView はレイアウト パスを短時間で完成して、この後の入力でも高い応答性を保つことができます。パスが完成したら、後で、要素の残りの部分を要求できます。</p>

<p>プレースホルダー レンダラーでは、promise を 1 つだけ返すのではなく、以下の 2 つのプロパティを持つオブジェクトが 1 つ返されます。</p>

<ul>
  <li>"element"<i></i>: 項目の構造内の最上位の要素で、項目のサイズと形状を定義できる必要最低限の、項目データに依存しない要素を示します。</li>

  <li>"renderComplete"<i></i>: 要素のコンテンツの残りが作成された時点で、フルフィルメントされる promise を示します。つまり、前と同様に <b>itemPromise.then</b> で始まるチェーンから promise を返します。</li>
</ul>

<p>ListView では、レンダラーが promise を返す (前と同様に基本のケース) か、element<i></i> および renderComplete<i></i> プロパティを返す (より高度なケース) かどうかを確認できます。したがって、前回の <b>simpleRenderer</b> と同等のプレースホルダー レンダラー (サンプル内) は次のようになります。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> placeholderRenderer(itemPromise) {<br />    <span style="color: rgb(0, 128, 0);">// create a basic template for the item that doesn't depend on the data</span><br />    <span style="color: rgb(0, 0, 255);">var</span> element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />    element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />    element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;div class='content'&gt;...&lt;/div&gt;&quot;</span>;<br /><br />    <span style="color: rgb(0, 128, 0);">// return the element as the placeholder, and a callback to update it when data is available</span><br />    <span style="color: rgb(0, 0, 255);">return</span> {<br />        element: element,<br /><br />        <span style="color: rgb(0, 128, 0);">// specifies a promise that will be completed when rendering is complete</span><br />        <span style="color: rgb(0, 128, 0);">// itemPromise will complete when the data is available</span><br />        renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />            <span style="color: rgb(0, 128, 0);">// mutate the element to include the data</span><br />            element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>).innerText = item.data.title;<br />            element.insertAdjacentHTML(<span style="color: rgb(0, 96, 128);">&quot;afterBegin&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;&lt;img src='&quot;</span> +<br />                item.data.thumbnail + <span style="color: rgb(0, 96, 128);">&quot;' alt='Databound image' /&gt;&quot;</span>);<br />        })<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>element.innerHTML<i></i> の割り当ては、<b>renderComplete</b> 内に移動することもできます。これは、サンプルの css/scenario1.css ファイルの itemTempl<i></i> クラスで、項目の幅と高さを直接指定しているためです。element<i></i> プロパティに含まれている理由は、プレースホルダーに既定の "…" テキストを提供するためです。方法は簡単で、すべての項目で共有される、小さいパッケージ内リソースを参照する (したがって短時間でレンダリングされる) img<i></i> 要素を使用するだけです。</p>

<h2>プレースホルダーの再利用レンダラー</h2>

<p>次の最適化の "プレースホルダーの再利用"<i></i> レンダラーでは、promise に関しては、新しいものは何もありません。recycled<i></i> というレンダラーにある 2 つ目のパラメーターに注目してください。これは、前にレンダリングされていて、現在は非表示になっている項目のルート要素です。つまり、再利用された要素には既に子要素が作成されているので、データを置き換えて、おそらく子要素のいくつかを調整するだけです。これにより、再利用をせず、まったく新しい項目をレンダリングする際に必要になる、不可の高い要素作成呼び出しのほとんどを回避し、レンダリング プロセスの時間を大幅に節約できます。</p>

<p>ListView は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211835.aspx" target="_blank">loadingBehavior</a><b></b> (英語) を "randomaccess" に設定すると、再利用した要素を提供できます。"recycled"<i></i> が指定された場合、要素 (とその子要素) からデータを消去し、プレースホルダーとしてこれを返します。その後、データを設定し、(必要に応じて) renderComplete<i></i> 内に追加の子を作成します。再利用された要素が提供されない場合 (ListView が初めて作成されたか、<b>loadingBehavior</b> が "incremental" の場合)、要素を新たに作成します。以下は、その動作のコードをサンプルから抜粋したものです。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> recyclingPlaceholderRenderer(itemPromise, recycled) {<br />    <span style="color: rgb(0, 0, 255);">var</span> element, img, label;<br />    <span style="color: rgb(0, 0, 255);">if</span> (!recycled) {<br />        <span style="color: rgb(0, 128, 0);">// create a basic template for the item that doesn't depend on the data</span><br />        element = document.createElement(<span style="color: rgb(0, 96, 128);">&quot;div&quot;</span>);<br />        element.className = <span style="color: rgb(0, 96, 128);">&quot;itemTempl&quot;</span>;<br />        element.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;&lt;img alt='Databound image' style='visibility:hidden;'/&gt;&quot;</span> +<br />            <span style="color: rgb(0, 96, 128);">&quot;&lt;div class='content'&gt;...&lt;/div&gt;&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// clean up the recycled element so that we can reuse it </span><br />        element = recycled;<br />        label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>);<br />        label.innerHTML = <span style="color: rgb(0, 96, 128);">&quot;...&quot;</span>;<br />        img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>);<br />        img.style.visibility = <span style="color: rgb(0, 96, 128);">&quot;hidden&quot;</span>;<br />    }<br />    <span style="color: rgb(0, 0, 255);">return</span> {<br />        element: element,<br />        renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />            <span style="color: rgb(0, 128, 0);">// mutate the element to include the data</span><br />            <span style="color: rgb(0, 0, 255);">if</span> (!label) {<br />                label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>);<br />                img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>);<br />            }<br />            label.innerText = item.data.title;<br />            img.src = item.data.thumbnail;<br />            img.style.visibility = <span style="color: rgb(0, 96, 128);">&quot;visible&quot;</span>;<br />        })<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>"renderComplete"<i></i> では、"label"<i></i> など、新しいプレースホルダーに作成しない要素があるかを必ず確認し、必要に応じてここで作成してください。</p>

<p>より一般的に再利用された項目からデータを消去する場合は、ListView の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211846.aspx" target="_blank">resetItem</a><b></b> (英語) プロパティに関数を設定できます。この関数には、上記と同様のコードが含まれます。項目だけでなくグループ ヘッダーにもテンプレート関数を使用できるので、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh700726.aspx" target="_blank">resetGroupHeader</a><b></b> (プロパティ) についても同じことが言えます。グループ ヘッダーははるかに少なく、通常、予想されるパフォーマンスは同じになるので、これまでそれほど詳しくは説明していませんが、この機能は存在しています。</p>

<h2>多段階レンダラー</h2>

<p>次は、最後から 2 番目の最適化、"多段階レンダラー"<i></i> です。このレンダラーは、プレースホルダー再利用レンダラーを拡張して、DOM に項目の残りの要素が完全に追加されるまで、イメージや他のメディアの読み込みを遅延します。また、項目が実際に画面に表示されるまで、アニメーションなどの効果も遅延します。これは、ユーザーが ListView 内ではかなりすばやくパンを行うことが多いので、ListView の動きが落ち着くまで、負荷の高い操作を非同期に遅延することが有効なためです。</p>

<p>ListView は、<b>itemPromise</b> から生成された <b>item</b> のメンバーとして必要なフックを提供します。これらは、<b>ready</b> というプロパティ (promise) と、(さらに) promise を返す <b>loadImage</b> および <b>isOnScreen</b> の 2 つのメソッドです。以下が、そのコードです。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// item.ready, item.loadImage, and item.isOnScreen available</span><br />})<br /></pre>
  </div>
</blockquote>

<p>これらの使い方を説明します。</p>

<ul>
  <li><b>ready</b> チェーン内で最初に completed ハンドラーからこの promise を返します。この promise は、要素の構造全体がレンダリングされ、表示できるようになった時点で、フルフィルメントされます。つまり、completed ハンドラーを使って別の <b>then</b> をチェーンし、そのチェーン内で、イメージの読み込みなど、他の表示後の作業を実行できます。</li>

  <li><b>loadImage</b> URI からイメージをダウンロードして、指定されている "img"<i></i> 要素内に URI 表示し、この要素によってフルフィルメントされる promise を返します。この promise に completed ハンドラーをアタッチします。このハンドラー自体は、<b>isOnScreen</b> から promise を返します。"img" 要素が提供されていない場合は、<b>loadImage</b> によって作成され、completed ハンドラーに渡されます。<i></i></li>

  <li><b>isOnScreen</b> 項目が表示されるかどうかを示すブール値をフルフィルメント値として取る promise を返します。現在の実装では、これは既知の値になるため、promise は同期的にフルフィルメントされます。ただし、これを promise を使ってラップすることで、より長いチェーンで使用できます。</li>
</ul>

<p>これらはすべてサンプルの <b>multistageRenderer</b> 関数内で使われています。この関数では、イメージの読み込みの完了を合図に、フェード イン アニメーションを開始します。以下に、"renderComplete"<i></i> promise から返される内容のみを示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// mutate the element to update only the title</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!label) { label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>); }<br />    label.innerText = item.data.title;<br /><br />    <span style="color: rgb(0, 128, 0);">// use the item.ready promise to delay the more expensive work</span><br />    <span style="color: rgb(0, 0, 255);">return</span> item.ready;<br />    <span style="color: rgb(0, 128, 0);">// use the ability to chain promises, to enable work to be cancelled</span><br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// use the image loader to queue the loading of the image</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!img) { img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>); }<br />    <span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail, img).then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />        <span style="color: rgb(0, 128, 0);">// once loaded check if the item is visible</span><br />        <span style="color: rgb(0, 0, 255);">return</span> item.isOnScreen();<br />    });<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (onscreen) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (!onscreen) {<br />        <span style="color: rgb(0, 128, 0);">// if the item is not visible, don't animate its opacity</span><br />        img.style.opacity = 1;<br />    } <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// if the item is visible, animate the opacity of the image</span><br />        WinJS.UI.Animation.fadeIn(img);<br />    }<br />})<br /></pre>
  </div>
</blockquote>

<p>ここではさまざまな処理をしていますが、基本の promise チェーンしかないことに変わりありません。レンダラー内の最初の同期操作によって、テキストなど、項目の要素構造でシンプルな要素のみが更新されます。次に、<b>item.ready</b> で promise を返しています。promise がフルフィルメントされるとき (より正確には、その promise が実行される場合) に、項目の非同期の <b>loadImage</b> メソッドを使ってイメージのダウンロードを開始し、<b>item.isOnScreen</b> promise をその completed ハンドラーから返します。つまり、可視性を示す "onscreen"<i></i> フラグがチェーン内で最後に completed ハンドラーに渡されます。その <b>isOnScreen</b> promise がフルフィルメントされる場合、つまり、項目が実際に表示される時点で、アニメーションなどの関連操作を実行できます。</p>

<p>"場合" を強調するのは、これらの処理が行われている最中に、ユーザーが ListView 内でパン操作を行う可能性があるためです。この場合も、これらの promise すべてをチェーンにまとめることで、これらの項目がパン操作によってビューやバッファー済みのページから外れた場合に、ListView では非同期操作をキャンセルできます。ListView コントロールに対して、ここまでで "さまざまな" パフォーマンス テストが実行されたと言えるでしょう。<i></i></p>

<p>また、やはり "renderComplete" プロパティ内のレンダリング関数から promise を返しているため、これらのどのチェーンでも全体で <b>then</b> を使用していることに改めて注意してください。<i></i>これらのレンダラー内でチェーンの最後に到達することはないため、<b>done</b> をレンダラーの最後に使うことはありません。</p>

<h2>縮小表示のバッチ処理</h2>

<p>最後の最適化は、まさに ListView コントロールにとって "最後の一撃" です。<i></i>以下のコードの <b>batchRenderer</b> という関数内に、"renderComplete" を対象とするこの構造があります (ほとんどのコードは省略)。<i></i></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">renderComplete: itemPromise.then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// mutate the element to update only the title</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!label) { label = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;.content&quot;</span>); }<br />    label.innerText = item.data.title;<br /><br />    <span style="color: rgb(0, 128, 0);">// use the item.ready promise to delay the more expensive work</span><br />    <span style="color: rgb(0, 0, 255);">return</span> item.ready;<br />    <span style="color: rgb(0, 128, 0);">// use the ability to chain promises, to enable work to be cancelled</span><br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (item) {<br />    <span style="color: rgb(0, 128, 0);">// use the image loader to queue the loading of the image</span><br />    <span style="color: rgb(0, 0, 255);">if</span> (!img) { img = element.querySelector(<span style="color: rgb(0, 96, 128);">&quot;img&quot;</span>); }<br />    <span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail, img).then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />        <span style="color: rgb(0, 128, 0);">// once loaded check if the item is visible</span><br />        <span style="color: rgb(0, 0, 255);">return</span> item.isOnScreen();<br />    });<br />}).then(<span style="color: rgb(0, 0, 255);">function</span> (onscreen) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (!onscreen) {<br />        <span style="color: rgb(0, 128, 0);">// if the item is not visible, don't animate its opacity</span><br />        img.style.opacity = 1;<br />    } <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// if the item is visible, animate the opacity of the image</span><br />        WinJS.UI.Animation.fadeIn(img);<br />    }<br />})<br /></pre>
  </div>
</blockquote>

<p>これは、<b>multistageRenderer</b> とほぼ同じですが、<b>item.loadImage</b> 呼び出しと <b>item.isOnScreen</b> チェックの間にある、この不思議な <b>thumbnailBatch</b> という関数への呼び出しが挿入されている点が異なります。チェーン内に <b>thumbnailBatch</b> がある場合、これは、その戻り値が、別の promise を返す completed ハンドラーになる必要があることを示しています。</p>

<p>わかりにくいでしょうか? これについては、詳しく説明しますが、最初に、ここで何をしようとしているか、少し背景を説明する必要があります。</p>

<p>項目が 1 つしかない ListView だけなら、さまざまな読み込みの最適化の効果はわからないでしょう。しかし、通常、ListViews には多数の項目があり、レンダリング関数は項目ごとに呼び出されます。前のセクションの <b>multistageRenderer</b> 内で、各項目のレンダリングによって、非同期の <b>item.loadImage</b> 操作が開始され、任意の URI から縮小表示がダウンロードされます。この操作のそれぞれに、時間がかかります。したがって、リスト全体では、多数の <b>loadImage</b> 呼び出しが同時に実行され、特定の縮小表示が完成するのを各項目のレンダリングが待機することになる可能性があります。ここまではよいでしょう。</p>

<p>ただし、<b>multistageRenderer</b> からは計り知れない重要な特徴は、縮小表示の "img"<i></i> 要素は "既に"<i></i> DOM 内にあり、ダウンロードの完了しだい、<b>loadImage</b> 関数によってそのイメージの src<i></i> 属性が設定されることです。属性が設定されたら、promise チェーンの残りが返されしだい、レンダリング エンジンが更新されます。これ以降は、基本的に同期的に処理されます。</p>

<p>さらにその後、多数の縮小表示が、短時間のうちに UI スレッドに返される可能性があります。これにより、レンダリング エンジンに過剰なチャーンが発生し、ビジュアル パフォーマンスがかなり低下します。このチャーンを避けるため、これらの "img"<i></i> 要素が DOM に渡される "前"<i></i> に、完全に img 要素を作成して、バッチに追加し、これらの要素がすべて単一のレンダリング パスで処理されるようにします。</p>

<p>サンプルでは、promise の一部 (<b>createBatch</b> という魔法の関数) で、これを実装しています。<b>createBatch</b> は、アプリ全体で 1 度だけ呼び出され、その結果 (別の関数) は <b>thumbnailBatch</b> という名前の変数に格納されます。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> thumbnailBatch;<br />thumbnailBatch = createBatch();<br /></pre>
  </div>
</blockquote>

<p>この <b>thumbnailBatch</b> 関数への呼び出しは、これ以降参照することになりますが、やはりレンダラーの promise チェーンに挿入されます。この挿入の目的は、この後すぐに説明するバッチ処理コードの性質を踏まえて、読み込まれた複数の "img"<i></i> 要素をグループにまとめ、適切な間を置いて次の処理に渡すことです。レンダラーの promise チェーンだけを見ても、やはり <b>thumbnailBatch()</b> の呼び出しは、promise を返す completed ハンドラー関数を返す必要があります。また、その promise のフルフィルメント値 (チェーンの次のステップを参照) は、DOM に追加できる "img"<i></i> 要素である必要があります。バッチ処理が実行された "後"<i></i> で、これらのイメージを DOM に追加することで、グループ全体を同じレンダリング パスにまとめています。</p>

<p>これは、<b>batchRenderer</b> と、前のセクションの <b>multistageRenderer</b> との重要な違いです。後者では、縮小表示の "img"<i></i> 要素が既に DOM 内に存在し、2 番目のパラメーターとして <b>loadImage</b> に渡されます。したがって、<b>loadImage</b> がイメージの "src"<i></i> 属性が設定されるときに、レンダリングの更新が発生します。ただし、<b>batchRenderer</b> 内では、その "img"<i></i> 要素は、<b>loadImage</b> 内 (ここでも "src"<i></i> が設定されている) で別に作成されますが、"img"<i></i> はまだ DOM に追加されていません。<b>thumbnailBatch</b> ステップが完了しないと DOM に追加されません。これにより、同一のレイアウト パス内にグループを組み込んでいます。</p>

<p>では、このバッチ処理のしくみを見ていきましょう。以下は、<b>createBatch</b> 関数の全容です。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> createBatch(waitPeriod) {<br />    <span style="color: rgb(0, 0, 255);">var</span> batchTimeout = WinJS.Promise.<span style="color: rgb(0, 0, 255);">as</span>();<br />    <span style="color: rgb(0, 0, 255);">var</span> batchedItems = [];<br /><br />    <span style="color: rgb(0, 0, 255);">function</span> completeBatch() {<br />        <span style="color: rgb(0, 0, 255);">var</span> callbacks = batchedItems;<br />        batchedItems = [];<br />        <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = 0; i &lt; callbacks.length; i++) {<br />            callbacks[i]();<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> () {<br />        batchTimeout.cancel();<br />        batchTimeout = WinJS.Promise.timeout(waitPeriod || 64).then(completeBatch);<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />            batchedItems.push(c);<br />        });<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />            <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                <span style="color: rgb(0, 0, 255);">return</span> v;<br />            });<br />        };<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>この場合も、<b>createBatch</b> は "1 度だけ"<i></i> 呼び出され、その結果の  <b>thumbnailBatch</b> がリスト内のレンダリングされた項目のそれぞれに対して呼び出されています。<i></i><i></i><b>thumbnailBatch</b> が生成した completed ハンドラーは、<b>loadImage</b> 操作が完了するたびに呼び出されます。</p>

<p>このような completed ハンドラーは、同程度の手間で、直接レンダリング関数に挿入することもできますが、ここでは、項目ごとではなく、複数の項目全体でアクティビティを調整することが目的です。<i></i>この調整は、<b>createBatch</b> の始めに作成および初期化される、2 つの変数によって実現されます。空の promise を初期化している "batchedTimeout"<i></i> と、最初は空の関数の配列を初期化している "batchedItems"<i></i> です。<b>createBatch</b> では関数 <b>completeBatch</b> も宣言していて、配列内の各関数を呼び出し、batchedItems<i></i> を空にします。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">function</span> createBatch(waitPeriod) {<br />    <span style="color: rgb(0, 0, 255);">var</span> batchTimeout = WinJS.Promise.<span style="color: rgb(0, 0, 255);">as</span>();<br />    <span style="color: rgb(0, 0, 255);">var</span> batchedItems = [];<br /><br />    <span style="color: rgb(0, 0, 255);">function</span> completeBatch() {<br />        <span style="color: rgb(0, 0, 255);">var</span> callbacks = batchedItems;<br />        batchedItems = [];<br />        <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">var</span> i = 0; i &lt; callbacks.length; i++) {<br />            callbacks[i]();<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> () {<br />        batchTimeout.cancel();<br />        batchTimeout = WinJS.Promise.timeout(waitPeriod || 64).then(completeBatch);<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />            batchedItems.push(c);<br />        });<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />            <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                <span style="color: rgb(0, 0, 255);">return</span> v;<br />            });<br />        };<br />    };<br />}<br /></pre>
  </div>
</blockquote>

<p>今度は、<b>thumbnailBatch</b> (<b>createBatch</b> から返される関数) 内の処理を見ていきましょう。これも、レンダリングされる項目ごとに呼び出されます。最初に、既存の batchedTimeout<i></i> をキャンセルし、すぐに作成し直します。<i></i></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">batchTimeout<span style="color: rgb(255, 0, 0);">.</span>cancel();<br />        batchTimeout = WinJS<span style="color: rgb(255, 0, 0);">.</span>Promise<span style="color: rgb(255, 0, 0);">.</span>timeout(waitPeriod || 64)<span style="color: rgb(255, 0, 0);">.</span>then(completeBatch);<br /></pre>
  </div>
</blockquote>

<p>2 行目は、「promise の詳細」&lt;TODO: link> の記事で説明している、将来の配信/フルフィルメント パターンです。ここでは、"waitPeriod" に指定された遅延 (ミリ秒単位、既定値は 64 ミリ秒) の後に、<b>completeBatch</b> を呼び出しています。<i></i>したがって、<b>thumbnailBatch</b> が以前の呼び出しの "waitPeriod"<i></i> で再び呼び出される限り、<b>batchTimeout</b> は新しい waitPeriod<i></i> にリセットされます。また、<b>thumbnailBatch</b> は、<i></i><b>item.loadImage</b> 呼び出しが完了した "後で" しか呼び出されないため、以前の呼び出しの "waitPeriod" 内で完了する <b>loadImage</b> 操作は同じバッチ内に含めることができます。<i></i>"waitPeriod"<i></i> に指定されている間隔を過ぎると、バッチが処理され (DOM にイメージが追加され)、次のバッチが開始されます。</p>

<p>このタイムアウト操作が処理されたら、<b>thumbnailBatch</b> によって新しい promise が作成され、この promise が完了ディスパッチャー関数を "batchedItems"<i></i> 配列にプッシュします。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> delayedPromise = <span style="color: rgb(0, 0, 255);">new</span> WinJS.Promise(<span style="color: rgb(0, 0, 255);">function</span> (c) {<br />         batchedItems.push(c);<br />     });<br /></pre>
  </div>
</blockquote>

<p>「promise の詳細」&lt;TODO: link> では、promise はコード コンストラクトに過ぎず、ここにはそれしかありません。新しく作成される promise 自体には、非同期動作はありません。完了ディスパッチャー関数の "c"<i></i> を "batchedItems"<i></i> に追加しているだけです。ただし、もちろん、"batchedTimeout"<i></i> が非同期に完了するまで、ディスパッチャーによる処理は何も実行されないため、ここでは実際に非同期な関係が成立しています。タイムアウトが発生し、バッチを消去したら (<b>completeBatch</b> 内)、別の場所にある completed ハンドラーを <b>delayedPromise.then</b> に呼び出します。</p>

<p>今度は、<b>createBatch</b> の最後のコード行です。これは、<b>thumbnailBatch</b> が実際に返される関数です。この関数こそが、レンダラーの promise チェーン全体に挿入される completed ハンドラーです。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">function</span> (v) {<br />           <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />               <span style="color: rgb(0, 0, 255);">return</span> v;<br />           });<br />       };<br /></pre>
  </div>
</blockquote>

<p>実際、このコードを直接 promise チェーンに挿入し、最終的な関係を見てみましょう。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">return</span> item.loadImage(item.data.thumbnail);<br />          }).then(<span style="color: rgb(0, 0, 255);">function</span> (v) {<br />              <span style="color: rgb(0, 0, 255);">return</span> delayedPromise.then(<span style="color: rgb(0, 0, 255);">function</span> () {<br />                  <span style="color: rgb(0, 0, 255);">return</span> v;<br />              });<br />          ).then(<span style="color: rgb(0, 0, 255);">function</span> (newimg) {<br /></pre>
  </div>
</blockquote>

<p>これで、引数 "v"<i></i> が <b>item.loadImage</b> の結果であることがわかります。これは作成された "img"<i></i> 要素です。バッチ処理を行わない場合は、<b>return WinJS.Promise.as(v)</b> と記述するだけでも、チェーン全体は機能します。その場合 "v"<i></i> は同期的に渡され、次のステップの "newimg"<i></i> に設定されます。</p>

<p>しかし、ここでは、<b>delayedPromise.then</b> から promise を返しています。これは、現在の "batchedTimeout" がフルフィルメントされるまで、("v" によって) 実行されません。<i></i><i></i>その時点で (ここでも 1 つ目の <b>loadImage</b> が完了してから "waitPeriod"<i></i> で指定されている間隔が空けられます)、"img"<i></i> 要素がチェーン内の次のステップに渡され、そこで DOM に追加されます。</p>

<p>以上です。</p>

<h2>終わりに</h2>

<p><a href="http://code.msdn.microsoft.com/windowsapps/ListView-performance-39fb71f0" target="_blank">HTML ListView パフォーマンス最適化のサンプル</a> (英語) に実装されている 5 種類のレンダリング関数すべてに共通することが、1 つあります。それは、promise によって表現される、ListView とレンダラー間の非同期の関係によって、レンダラーがリスト内の項目の要素を生成する方法とタイミングを非常に柔軟にコントロールできることです。独自のアプリを作成する際に、ListView の最適化にどのような戦略を使うかは、データ ソースのサイズ、項目自体の複雑さ、(リモート イメージのダウンロードなど) それらの項目に非同期で取得するデータの量に大きく依存します。それでも、パフォーマンス目標を達成できるように、項目レンダラーはできるだけシンプルにしたいと思うのは当然です。しかし、いずれにせよ、ListView (とアプリ) のパフォーマンスを最大限引き出すために必要なツールは、これですべて揃いました。</p>

<p>Kraig Brockschmidt
  <br />- Windows エコシステム担当チーム、プログラム マネージャー

  <br />著書『<a href="http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx">HTML、CSS、JavaScript を使った Windows 8 アプリ開発<i></i></a>』(英語)</p>
<!-- Title: “ListView の項目レンダリングの最適化” Tags: “Windows ストア アプリ, レンダー, バッチ処理, バッチ, レンダリング, ListView” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Game On Virtual Event にご参加ください</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/game-on-virtual-event</link>
      <pubDate>Wed, 12 Jun 2013 11:38:41 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/06/12/game-on-virtual-event/</guid>
      <description><![CDATA[ゲームは、Windows ストアにおける重要なアプリの 1 つです。Windows...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>ゲームは、Windows ストアにおける重要なアプリの 1 つです。Windows ストアのゲーム開発の方法を模索している皆様に、ゲーム開発支援を目的とした仮想イベントをお知らせいたします。これは、初めての開発者にもプロの開発者にも役立つ、参加無料のイベントです。</p>  <p>本イベントでは、YoYo Games の <a href="https://aka.ms/yoyogamesgamemaker" target="_blank">GameMaker: Studio</a> (英語) を使って、高品質なゲームをかつてないスピードで開発、公開する方法をお伝えします。GameMaker:Studio には豊富な設計オプションが組み込まれ、各ツールはドラッグ アンド ドロップで操作できるので、ゲームのアイデアがなくても、また開発経験を持たない方でも開発を始めることができます。もちろん、プロフェッショナルの皆様の要求に応える高度なツールも備えておりますので、独自のゲーム エクスペリエンスの開発に挑戦していただくことができます。</p>  <p><a href="https://aka.ms/gameonevent"><img title="clip_image002" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8666.clip_image002_0385EAB3.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8666.clip_5F00_image002_5F00_0385EAB3.jpg" width="500" height="154" /></a></p>  <p>このオンライン イベントは 6 月 15 日午前 10 時 (太平洋夏時間) に開催されます。ローンチ セッションとライブ チャットで幕を開け、<sup></sup>さまざまなゲームの種類、基本的なゲームにグラフィック、レベル、サウンドを追加する方法、ゲームにオリジナリティを加える方法などを紹介していきます。サポートは 1 週間にわたり継続され、GameMaker フォーラムを通して 1 対 1 のサポートが提供される予定です。</p>  <p>学生の皆様、開発を初めたばかりの方、経験豊かなプロフェッショナルの皆様は、ゲームの開発を開始、アップロードし、Windows ストアに公開するために必要なすべての情報を、イベントを通して学ぶことができます。イベントの詳細、登録方法、無料のツールとリソースに関する情報については、<a href="http://msdnevents.com/gameon/" target="_blank">http://msdnevents.com/gameon/</a> (英語) をご覧ください。</p>  <p>--Robert Rodriguez-Lawson、シニア コンテンツ パブリッシング マネージャー、Windows 開発者コンテンツ チーム</p> <!-- Title: “Game On Virtual Event にご参加ください” Tags: “Windows ストア ゲーム, ゲーム, Game On, イベント” --></div>]]></content:encoded>
    </item>
    <item>
      <title>資格情報保管ボックス: Windows ストア アプリのユーザー名とパスワード処理のソリューション</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/windows-124</link>
      <pubDate>Tue, 04 Jun 2013 19:42:00 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/06/04/windows-124/</guid>
      <description><![CDATA[Windows ストア...]]></description>
      <content:encoded><![CDATA[<div class="PostContent">
<p>Windows ストア アプリで使用できる<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465069.aspx" target="_blank">資格情報保管ボックス</a>ついてご存知なければ、ここでぜひ知っておいてください。理由は、資格情報保管ボックスを使うと、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465060.aspx" target="_blank">ユーザー資格情報の格納</a>と<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/jj839731.aspx" target="_blank">取得</a>の作業を簡略化できるだけでなく、資格情報を安全に格納でき、ユーザーの Microsoft アカウントと合わせて "無料で" ローミングできるからです。</p>
<p>たとえば、メディア ファイルやソーシャル ネットワークなど、保護されたリソースにアクセスするサービスに接続するアプリがあるとします。サービスを利用するには、ユーザーごとにログイン情報が必要です。そこで、ユーザーのユーザー名とパスワードを取得し、それを使ってサービスにユーザーをログインする UI をアプリに組み込みました。すべてがスムーズに機能しています。</p>
<p>今度はさらに、ユーザーの利便性を考えて、アプリを使うたびにログインしなくても済むようにログイン情報を安全に格納したいと考えました。そこで、資格情報保管ボックスの出番です。資格情報保管ボックス API を何回か呼び出すだけで、ユーザーのユーザー名とパスワードを格納し、ユーザーが次にアプリを開くときに、簡単に格納した情報を取得して、自動でユーザーのログインを処理できます。</p>
<h2>安全な保存スペース</h2>
<p>アプリにとっての資格情報保管ボックスの最大のメリットは、ユーザー資格情報が安全な場所に格納されることです。資格情報は、ディスク上に格納されるとき、暗号化されます。もちろん、アプリに使うユーザー資格情報をファイルに保存してローカルの保存スペースに格納することもできますが、ユーザー資格情報をプレーンテキストで格納すると、大きなセキュリティ ホールになります。ユーザーのシステムが何かの形で侵害された場合、ユーザーのユーザー名とパスワードにアクセスして操作することは簡単です。ユーザー名とパスワードが資格情報保管ボックスを使って格納されていれば、悪意のあるソースは暗号化されたファイルを入手するのが関の山です。</p>
<p>資格情報保管ボックスは各 Windows PC ユーザーに一意であり、資格情報を格納したアプリしか、その資格情報にアクセスできません。つまり、その特定のアプリのために格納した資格情報以外は取得できません。同様に、他のアプリは、この特定のアプリによって資格情報保管ボックスに格納されている資格情報にはアクセスできません。</p>
<h2>資格情報のローミング</h2>
<p>ユーザーに提供できるもう 1 つのメリットは、資格情報保管ボックスを使ってユーザー名とパスワードを格納すると、格納された資格情報はユーザーの Microsoft アカウントと共に、ユーザーがその Microsoft アカウントを使う限りどの信頼済みコンピューターにもローミングされることです。その結果、ユーザーの Microsoft アカウントに関連付けられていて、アプリがインストールされていれば、どの信頼済みコンピューターからでも、ユーザーはアプリに自動的にログインできる (ユーザーに資格情報の入力が求められない) ため、セキュリティで保護されたアプリはユーザーにとってさらに便利なものになります。</p>
<p>ドメイン アカウントの場合は、処理が少し異なります。Microsoft アカウントを使って格納されている資格情報があり、そのアカウントをドメイン アカウント (仕事で使うアカウントなど) に関連付けている場合、資格情報はそのドメイン アカウントにローミングされます。ただし、そのドメイン アカウント使ってサイン オンするときに追加された新しい資格情報は、ローミングされません。これにより、そのドメイン固有の資格情報が、ドメイン外部に知られないようにしています。</p>
<h2>ユーザー資格情報の格納</h2>
<p>資格情報保管ボックスへのユーザー資格情報の格納は、簡単な 2 ステップのプロセスです。最初に、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a> 名前空間の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a> オブジェクトを使って、資格情報保管ボックスへの参照を取得します。次に、アプリの識別子、ユーザー名およびパスワードを保持する <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordcredential.aspx" target="_blank">PasswordCredential</a> オブジェクトを作成し、このオブジェクトを <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh701231.aspx" target="_blank">PasswordVault.Add()</a> メソッドに渡して、資格情報を資格情報保管ボックスに追加します。</p>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.Add(<span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: #006080;">"My App"</span>, username, password));</pre>
</div>
</blockquote>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">var</span> vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.add(<span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: #006080;">"My App"</span>, username, password));</pre>
</div>
</blockquote>
<h2>ユーザー資格情報の取得</h2>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a> オブジェクトの参照を取得したら、資格情報保管ボックスからユーザー資格情報を取得する方法はいくつかあります。</p>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.retrieveall.aspx" target="_blank">PasswordVault.RetrieveAll()</a> メソッドを使うと、ユーザーがアプリ用に資格情報保管ボックスに格納している資格情報をすべて取得できます。</li>
<li>格納されている資格情報のユーザー名がわかっている場合は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.findallbyusername.aspx" target="_blank">PasswordVault.FindAllByUserName()</a> メソッドを使って、そのユーザー名の資格情報をすべて取得できます。</li>
<li>格納されている資格情報のリソース名がわかっている場合は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.findallbyresource.aspx" target="_blank">PasswordVault.FindAllByResource()</a> メソッドを使って、そのリソース名の資格情報をすべて取得できます。</li>
<li>資格情報のユーザー名とリソース名がわかっている場合は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.retrieve.aspx" target="_blank">PasswordVault.Retrieve()</a> メソッドを使って、その資格情報のみを取得できます。</li>
</ul>
<p>では、リソース名がグローバルにアプリに格納されていて、ユーザーの資格情報を見つけることができた場合、自動的にユーザーがログインできるサンプルを見てみましょう。ユーザーの資格情報が複数見つかった場合は、ログオン時に使用する既定の資格情報を選択するようにユーザーに求めます。</p>
<p><strong>C#</strong></p>
<blockquote>
<div>
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> resourceName = <span style="color: #006080;">"My App"</span>;<br /><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> defaultUserName;<br /><br /><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Login()<br />{<br />    var loginCredential = GetCredentialFromLocker();<br /><br />    <span style="color: #0000ff;">if</span> (loginCredential != <span style="color: #0000ff;">null</span>)<br />    {<br />        <span style="color: #008000;">// There is a credential stored in the locker.</span><br />        <span style="color: #008000;">// Populate the Password property of the credential</span><br />        <span style="color: #008000;">// for automatic login.</span><br />        loginCredential.RetrievePassword();<br />    }<br />    <span style="color: #0000ff;">else</span><br />    {<br />        <span style="color: #008000;">// There is no credential stored in the locker.</span><br />        <span style="color: #008000;">// Display UI to get user credentials.</span><br />        loginCredential = GetLoginCredentialUI();<br />    }<br /><br />    <span style="color: #008000;">// Log the user in.</span><br />    ServerLogin(loginCredential.UserName, loginCredential.Password);<br />}<br /><br /><br /><span style="color: #0000ff;">private</span> Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker()<br />{<br />    Windows.Security.Credentials.PasswordCredential credential = <span style="color: #0000ff;">null</span>;<br /><br />    var vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />    var credentialList = vault.FindAllByResource(resourceName);<br />    <span style="color: #0000ff;">if</span> (credentialList.Count &gt; 0)<br />    {<br />        <span style="color: #0000ff;">if</span> (credentialList.Count == 1)<br />        {<br />            credential = credentialList[0];<br />        }<br />        <span style="color: #0000ff;">else</span><br />        {<br />            <span style="color: #008000;">// When there are multiple usernames,</span><br />            <span style="color: #008000;">// retrieve the default username. If one doesn&rsquo;t</span><br />            <span style="color: #008000;">// exist, then display UI to have the user select</span><br />            <span style="color: #008000;">// a default username.</span><br /><br />            defaultUserName = GetDefaultUserNameUI();<br /><br />            credential = vault.Retrieve(resourceName, defaultUserName);<br />        }<br />    }<br /><br />    <span style="color: #0000ff;">return</span> credential;<br />}</pre>
</div>
</blockquote>
<div><br /><strong>JavaScript</strong></div>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">var</span> resourceName = <span style="color: #006080;">"My App"</span>;<br /><span style="color: #0000ff;">var</span> defaultUserName;<br /><br /><span style="color: #0000ff;">function</span> login() {<br />    <span style="color: #0000ff;">var</span> loginCredential = getCredentialFromLocker();<br /><br />    <span style="color: #0000ff;">if</span> (loginCredential != <span style="color: #0000ff;">null</span>) {<br />        <span style="color: #008000;">// There is a credential stored in the locker.</span><br />        <span style="color: #008000;">// Populate the Password property of the credential</span><br />        <span style="color: #008000;">// for automatic login.</span><br />        loginCredential.retrievePassword();<br />    } <span style="color: #0000ff;">else</span> {<br />        <span style="color: #008000;">// There is no credential stored in the locker.</span><br />        <span style="color: #008000;">// Display UI to get user credentials.</span><br />        loginCredential = getLoginCredentialUI();<br />    }<br /><br />    <span style="color: #008000;">// Log the user in.</span><br />    serverLogin(loginCredential.userName, loginCredential.password);<br />}<br /><br /><br /><span style="color: #0000ff;">function</span> GetCredentialFromLocker() {<br />    <span style="color: #0000ff;">var</span> credential = <span style="color: #0000ff;">null</span>;<br /><br />    <span style="color: #0000ff;">var</span> vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />    <span style="color: #0000ff;">var</span> credentialList = vault.findAllByResource(resourceName);<br />    <span style="color: #0000ff;">if</span> (credentialList.length &gt; 0) {<br />        <span style="color: #0000ff;">if</span> (credentialList.length == 1) {<br />            credential = credentialList[0];<br />        } <span style="color: #0000ff;">else</span> {<br />            <span style="color: #008000;">// When there are multiple usernames,</span><br />            <span style="color: #008000;">// retrieve the default username. If one doesn&rsquo;t</span><br />            <span style="color: #008000;">// exist, display UI to have the user select</span><br />            <span style="color: #008000;">// a default username.</span><br /><br />            defaultUserName = getDefaultUserNameUI();<br />            credential = vault.retrieve(resourceName, defaultUserName);<br />        }<br />    }<br /><br />    <span style="color: #0000ff;">return</span> credential;<br />}</pre>
</div>
</blockquote>
<h2>ユーザー資格情報の削除</h2>
<p>資格情報保管ボックスへのユーザー資格情報の削除も、簡単な 2 ステップのプロセスです。この場合も、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a> 名前空間の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.passwordvault.aspx" target="_blank">PasswordVault</a> オブジェクトを使って、資格情報保管ボックスへの参照を取得します。次に、削除する資格情報を <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh701242.aspx" target="_blank">PasswordVault.Remove()</a> メソッドに渡します。</p>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.Remove(<span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: #006080;">"My App"</span>, username, password));</pre>
</div>
</blockquote>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">var</span> vault = <span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordVault();<br />vault.remove(<span style="color: #0000ff;">new</span> Windows.Security.Credentials.PasswordCredential(<br />    <span style="color: #006080;">"My App"</span>, username, password));</pre>
</div>
</blockquote>
<h2>簡単で安全</h2>
<p>このように、資格情報保管ボックスは、より簡単に、しかも非常に安全に、ユーザーを認証し、ユーザーの資格情報を将来再利用する目的で格納できる、使いやすい機能です。</p>
<p>その他の Windows 8 アプリの認証に関するトピックには、Web サイトからの認証トークン (OAuth など) の取得に使用できる <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465281.aspx" target="_blank">Web 認証ブローカー</a>や、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh770853.aspx" target="_blank">ユーザーの Microsoft アカウントを基にしたアプリのカスタマイズ</a>があります。</p>
<p>詳細については、以下のリンクをご覧ください。</p>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211367.aspx" target="_blank">ユーザー情報の管理 (JavaScript)</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/xaml/BR229572(v=win.10).aspx" target="_blank">ユーザー情報の管理 (C#/VB/C++ と XAML を使った Windows ストア アプリ)</a></li>
<li><a href="http://code.msdn.microsoft.com/windowsapps/PasswordVault-f01be74a" target="_blank">資格情報保管ボックスのサンプル</a> (英語)</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.security.credentials.aspx" target="_blank">Windows.Security.Credentials</a></li>
</ul>
<p>&nbsp;</p>
<p>--Doug Rothaus、Windows 開発者コンテンツ チーム、シニア コンテンツ開発者</p>
<p>今回の記事作成にあたっては、Yashar Bahman 氏にご協力いただきました。ありがとうございました。</p>
<!-- Title: “資格情報保管ボックス: Windows ストア アプリのユーザー名とパスワード処理のソリューション” Tags: “資格情報の取得, 資格情報の格納, 安全な保存スペース, 資格情報保管ボックス” --></div>]]></content:encoded>
    </item>
    <item>
      <title>位置情報と Bing マップを使用して位置認識アプリを作成する</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/bing</link>
      <pubDate>Tue, 28 May 2013 11:04:04 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/05/28/bing/</guid>
      <description><![CDATA[ユーザーの位置情報とアプリのビジネス ロジックを組み合わせることによって、天気、クーポン、スポーツ イベント、コンサートの一覧などの情報を、アプリ...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>ユーザーの位置情報とアプリのビジネス ロジックを組み合わせることによって、天気、クーポン、スポーツ イベント、コンサートの一覧などの情報を、アプリ ユーザーの現在地に合わせて簡単に提供できるようになります。Windows 8 の<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229921.aspx" target="_blank">位置情報機能</a>を Bing マップ SDK と共に使用することで、強力な<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465148.aspx" target="_blank">位置認識 Windows ストア アプリ</a>を開発できます。</p>  <p>この記事では、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br225603.aspx" target="_blank">位置情報サービス</a>を使用するアプリが、IP アドレス、Wi-Fi ネットワーク、GPS データのいずれかを使用してその場所固有の情報をユーザーに提供する方法について説明します。位置情報を取得した後は、Bing マップ SDK を使用して現在地を表示します。</p>  <h2>位置情報を取得する</h2>  <p>位置情報の取得には <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.aspx">Windows.Devices.Geolocation</a> 名前空間を使用します。GPS、Wi-Fi ネットワーク、IP アドレスうちどの情報をユーザーの位置情報の取得に使用するかは、主に以下の 2 つの要因がかかわってきます。</p>  <ol>   <li>要求される精度の正確性: アプリの必要性に応じた最適な精度です。</li>    <li>位置情報データの利用可能性: GPS 機能を搭載していないデバイスがある、または、ネットワークや Wi-Fi 接続が利用できない状況で位置情報が要求される場合があるということです。</li> </ol>  <h3><a>適切な精度</a></h3>  <p>位置情報を要求する場合は、アプリが<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.geolocator.desiredaccuracy.aspx" target="_blank">適切な精度</a>を指定して、指定した精度の範囲内で位置情報データが最も速く返されるようにする必要があります。精度のレベルは、位置情報の種類に応じてそれぞれ以下のように異なります。</p>  <ul>   <li><a href="http://ja.wikipedia.org/wiki/GPS" target="_blank">GPS</a> - GPS は、約 10 m という最も高い精度を提供します。ただしGPS センサーを起動状態にして衛星データを取得し、データを三角測量する場合、詳細な位置情報を返すのに 1 ～ 2 分間かかる場合があります。一方、GPS が衛星との接続を確立した後は、次の位置情報ポイントは最初よりも早く取得されます。もちろん GPS の使用頻度が高くなると消費電力も高くなります。GPS を有効化してデータを取得するには、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.geolocator.desiredaccuracy.aspx" target="_blank">Geolocator.DesiredAccuracy</a> プロパティを High に設定する必要があります。</li>    <li><a href="http://ja.wikipedia.org/wiki/Wi-Fi" target="_blank">Wi-Fi</a> - Wi-Fi 接続の精度は 300 ～ 500 m の範囲となります。Wi-Fi 接続を利用できる場合、衛星接続を取得する GPS の場合よりもデータが速く返されます。Wi-Fi を使用して位置情報を取得するには、DesiredAccuracy プロパティを Default に設定します。</li>    <li><a href="http://ja.wikipedia.org/wiki/IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9" target="_blank">IP</a> - IP レベルの感度の場合は 1 km レベルの精度になります。ネットワーク接続を利用できる場合、衛星接続を取得する GPS の場合よりもデータが速く返されます。IP を使用して位置情報を取得する場合も、設定する DesiredAccuracy プロパティは Default です。位置情報サービスは可能な最大精度でデータを返し、その精度のレベルを <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.geocoordinate.accuracy.aspx" target="_blank">Geocoordinate.Accuracy</a> プロパティ内で通知します。</li> </ul>  <p>アプリのパフォーマンスと消費電力に影響するため、適切な精度の値は慎重に検討する必要があります。たとえば天気予報を提供するアプリの場合、高精度な GPS はほぼ必要ありません。また、返されるデータの精度に基づいて誤差範囲を表示し、データの精度を必ず示す必要があります。適切な精度を設定する C# のコードは以下のようになります。</p>  <p><strong>C#</strong></p>  <blockquote>   <div id="codeSnippetWrapper">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Geolocator geolocator = <span style="color: rgb(0, 0, 255);">new</span> Geolocator();<br />geolocator.DesiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.High;<br /></pre>
  </div>
</blockquote>

<br />精度のレベルにかかわらず、位置情報を取得する呼び出しは以下のようになります。

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);</pre>
  </div>
</blockquote>

<p>Geolocator クラスのインスタンスを作成し、適切な精度を設定し、現在地を取得する JavaScript コードは以下のようになります。以下の 'promise' 変数が <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211867.aspx" target="_blank">WinJS.Promise</a> (英語) オブジェクトである点に注意してください。つまり、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br225537.aspx" target="_blank">getGeopositionAsync</a> への呼び出しからデータにアクセスするには <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh701079.aspx" target="_blank">done</a> (英語)メソッドを使用する必要があります。</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> geolocator = Windows.Devices.Geolocation.Geolocator();<br />geolocator.desiredAccuracy =<br />Windows.Devices.Geolocation.PositionAccuracy.high;<br /><br /><span style="color: rgb(0, 128, 0);">// Get the geoposition, capturing the request in a 'promise' object.</span><br /><span style="color: rgb(0, 0, 255);">var</span> promise = geolocator.getGeopositionAsync();<br /></pre>
  </div>
</blockquote>

<br />適切な精度を High に設定しても、PC に GPS 機能が搭載されていない、無効化している、Wi-Fi に接続していないなどの理由により、ユーザーのデバイスが高精度なデータを返さない可能性があることに注意してください。低精度データのインスタンスを適切に処理できるよう常に備えておく必要がありますが、その方法はアプリの機能によって異なります。低精度でも処理を続行する必要があるか、GPS レベルの精度が必要かどうかなど、詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465148.aspx" target="_blank">位置認識アプリのガイドライン</a>」を参照してください。

<h3>Bing マップ</h3>

<p>利用できる位置情報の精度に対応するアプリの良い例が <a href="http://apps.microsoft.com/webpdp/app/97a2179c-38be-45a3-933e-0d2dbf14a142" target="_blank">Bing マップ アプリ</a>です。GPS や Wi-Fi が利用できないことが多いデスクトップ PC の場合、Bing マップ アプリは IP アドレスに基づき位置情報を特定し、<a>広域図にズームして現在地をマップに示します</a>。ラップトップの場合は通常ワイヤレス カードが搭載されているため、Wi-Fi を使用してより正確な位置情報を取得し、さらに詳細図にズームして現在地を示すことができます。ユーザーがさらにズームすると、現在地アイコンに誤差範囲が表示されます。</p>

<h3>Bing 天気</h3>

<p>前述のとおり、<a href="http://apps.microsoft.com/webpdp/app/421ba874-f903-4965-9b82-d60f3ba3cae0" target="_blank">Bing 天気アプリ</a>は広域の情報のみを必要とします。このため、このアプリが要求および指定する精度は低精度だけになり、位置情報の値も迅速に返され、ユーザーに対するアプリの応答性も高くなります。広域図レベルの情報しか必要としないその他の例としては、ラジオ局ガイド、買い物クーポン、地域のニュース フィードなどのアプリがあります。</p>

<h2>Bing マップ SDK を使用して位置情報を表示する</h2>

<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.geolocator.getgeopositionasync.aspx" target="_blank">GetGeopositionAsync</a> への呼び出しから位置情報を取得した後は、情報をマップに表示します。</p>

<ul>
  <li>最初に、以下のコードを使用して、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.geolocation.geoposition.aspx" target="_blank">Geoposition</a> を Bing マップで使用できる <a href="http://msdn.microsoft.com/ja-jp/library/hh846500.aspx" target="_blank">Location</a> (英語) に変換します。</li>
</ul>

<p> </p>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Location location = <span style="color: rgb(0, 0, 255);">new</span> Location(pos.Coordinate.Latitude, pos.Coordinate.Longitude);</pre>
  </div>
</blockquote>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">promise.done(<br />  <span style="color: rgb(0, 0, 255);">function</span> (pos) {<br />    <span style="color: rgb(0, 128, 0);">// Get the coordinates of the current location.</span><br />    <span style="color: rgb(0, 0, 255);">var</span> coord = pos.coordinate,<br />    location = <span style="color: rgb(0, 0, 255);">new</span> Microsoft.Maps.Location(coord.latitude, coord.longitude);<br /> <br />  },<br />  <span style="color: rgb(0, 0, 255);">function</span> (err) {<br />    <span style="color: rgb(0, 128, 0);">// Handle the error.</span><br />  });<br /></pre>
  </div>
</blockquote>

<p> </p>

<ul>
  <li>次に Bing マップを使用して位置情報を表示します。Bing マップ SDK は<a href="http://visualstudiogallery.msdn.microsoft.com/bb764f67-6b2c-4e14-b2d3-17477ae1eaca">ここ</a> (英語) から入手できます。また、Bing ポータルに登録して <a href="http://msdn.microsoft.com/ja-jp/library/ff428642.aspx">Bing マップ キーの入手</a> (英語) 手順に従い、Bing マップ キーも入手する必要があります。登録の際は、キーの種類ごとの使用量制限を確認のうえ、アプリに最適なキーを選択してください。

    <br />Bing マップ コントロールをデザイナーに追加し、資格情報にキーを挿入します。</li>
</ul>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Page</span><br />    <span style="color: rgb(255, 0, 0);">xmlns</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:x</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:local</span><span style="color: rgb(0, 0, 255);">=&quot;using:SimpleMapping&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:d</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:mc</span><span style="color: rgb(0, 0, 255);">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</span><br />    <span style="color: rgb(255, 0, 0);">xmlns:Maps</span><span style="color: rgb(0, 0, 255);">=&quot;using:Bing.Maps&quot;</span><br />    <span style="color: rgb(255, 0, 0);">x:Class</span><span style="color: rgb(0, 0, 255);">=&quot;SimpleMapping.MainPage&quot;</span><br />    <span style="color: rgb(255, 0, 0);">mc:Ignorable</span><span style="color: rgb(0, 0, 255);">=&quot;d&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Grid</span> <span style="color: rgb(255, 0, 0);">Background</span><span style="color: rgb(0, 0, 255);">=&quot;{StaticResource ApplicationPageBackgroundThemeBrush}&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Maps:Map</span> <span style="color: rgb(255, 0, 0);">x:Name</span><span style="color: rgb(0, 0, 255);">=&quot;Map&quot;</span> <span style="color: rgb(255, 0, 0);">Margin</span><span style="color: rgb(0, 0, 255);">=&quot;0,120,0,0&quot;</span> <span style="color: rgb(255, 0, 0);">Credentials</span><span style="color: rgb(0, 0, 255);">=&quot;Insert Your Bing Maps Key Here&quot;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Grid</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Page</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>
  </div>
</blockquote>

<ul>
  <li>次に、マップが表示されるアプリ内のページで、以下のコードを使用します。これによってマップのズーム レベルが設定され、位置情報が表示されます。ズーム レベルの詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/jj850315.aspx" target="_blank">Bing Map 上の位置情報を表示する方法</a>」を参照してください。</li>
</ul>

<p><strong>C#</strong></p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">double</span> zoomLevel = 13.0f;<br /><br />Map.SetView(location, zoomLevel);<br /></pre>
  </div>
</blockquote>

<br />JavaScript と HTML で Bing マップ コントロールをアプリに追加する場合は、もう少し作業が必要です。以下の &lt;script&gt; タグをアプリの HTML に追加します。

<div> </div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">script</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;text/javascript&quot;</span> <br />   <span style="color: rgb(255, 0, 0);">src</span><span style="color: rgb(0, 0, 255);">=&quot;ms-appx:///Bing.Maps.JavaScript//js/veapicore.js&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />/script<span style="color: rgb(0, 0, 255);">&gt;</span><br /></pre>
  </div>
</blockquote>

<p>次にアプリを格納する &lt;div&gt; タグを作成し、アクセスに必要な id 属性を設定します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">div</span> <span style="color: rgb(255, 0, 0);">id</span>=’<span style="color: rgb(255, 0, 0);">map-div</span>’<span style="color: rgb(0, 0, 255);">&gt;&lt;/</span><span style="color: rgb(128, 0, 0);">div</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>
  </div>
</blockquote>

<p>最後に HTML ページ内でマップ コントロールを初期化します。そのための JavaScript を以下に示します。</p>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">// Load the Microsoft.Maps.Map module and then call getMap when the </span><br /><span style="color: rgb(0, 128, 0);">// module has loaded.</span><br /><span style="color: rgb(0, 0, 255);">function</span> initMap() {<br />  Microsoft.Maps.loadModule(<span style="color: rgb(0, 96, 128);">'Microsoft.Maps.Map'</span>, <br />    { <br />      callback: getMap, <br />      culture: <span style="color: rgb(0, 96, 128);">&quot;en&quot;</span>, <br />      homeRegion: <span style="color: rgb(0, 96, 128);">&quot;US&quot;</span> <br />  });<br />}<br /><br /><span style="color: rgb(0, 128, 0);">// Get the div to contain the map from the interface of the app.</span><br /><span style="color: rgb(0, 0, 255);">function</span> getMap() {<br /><br />  <span style="color: rgb(0, 128, 0);">// Create a new instance of the Map class, passing in the app ID.</span><br />  <span style="color: rgb(0, 0, 255);">var</span> map = <span style="color: rgb(0, 0, 255);">new</span> Microsoft.Maps.Map(<br />    document.getElementById(mapDivId), <br />    { credentials: “Insert your credentials here” });<br /><br />  <span style="color: rgb(0, 128, 0);">// Set the initial zoom level and type of map.</span><br />  map.setView({<br />    mapTypeId: Microsoft.Maps.MapTypeId.road,<br />    zoom: 3<br />  });<br />}<br /></pre>
  </div>
</blockquote>

<ul>
  <li>位置情報を使用するあらゆるアプリは、ユーザーのアクセス権の設定に常に従う必要があります。天気アプリは位置情報を使用して現在地の天気を取得しますが、ユーザーは常に設定にアクセスして位置情報のアクセス権を無効化できる必要があります。アプリは、位置情報のアクセス権が無効化されている可能性に常に対応できる必要があります。この天気アプリの場合、「Your location cannot be found. Change your Permissions to allow Weather to user your location. (ユーザーの位置情報が見つかりません。アクセス権を変更して、天気アプリによる位置情報の使用を許可してください)」というメッセージが表示されます。位置情報のアクセス権を処理する例については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/Hh465148(v=win.10).aspx" target="_blank">位置認識アプリのガイドライン</a>」のユーザー エクスペリエンス ガイドラインを参照してください。

    <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0882.bing-weather_2FEEBCEF.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0882.bing_2D00_weather_5F00_2FEEBCEF.jpg"><img title="Bing 天気 アプリ" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="位置情報を使用して現在地の天気を取得する Bing 天気アプリ" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7356.bing-weather_thumb_084840C5.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7356.bing_2D00_weather_5F00_thumb_5F00_084840C5.jpg" width="600" height="450" /></a></li>
</ul>

<p> </p>

<p>位置情報機能と Bing マップ SDK の使用について隅々までご理解いただくために、位置情報を非同期で取得し Bing マップ SDK に現在地を視覚的に表示するまでの手順を説明する<a></a><a>新しい</a><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/xaml/jj850315.aspx" target="_blank">ビデオ、How-To トピック</a>、<a href="http://code.msdn.microsoft.com/windowsapps/Simple-geolocation-with-7b385c3c" target="_blank">コード サンプル</a> (英語) を用意いたしました。これらのビデオ、How-To トピック、サンプルを通して、位置情報機能を有効にする方法、位置情報を非同期で取得する方法、マップを特定の場所に設定する方法、位置情報データの精度に基づいて現在地アイコンを設定する方法を学習できます。詳細については、<a href="http://msdn.microsoft.com/ja-jp/library/hh846481.aspx" target="_blank">Windows ストア アプリ用の Bing マップ</a> (英語) に関するページを参照してください。</p>

<h2>まとめ</h2>

<p>強力な位置情報機能をアプリに追加することで、ユーザーは時間を有効活用できるようになります。位置情報機能を通して、ユーザーの現在地に合わせてより関連性の高い情報を提供することができます。地域のラジオ局一覧、買い物クーポン、交通情報、天気情報など、現在地に最適化された情報を提供できる機能を搭載することで、アプリがもっと便利なものになります。こうした情報提供を自動化してユーザーの操作を不要にすることは、ユーザーの時間を節約し、アプリの使用頻度を高めることにもつながります。</p>

<p>--Ross Heise、Windows 開発者コンテンツ チーム、シニア コンテンツ開発者</p>
<p>   今回の記事作成にあたっては、Jon Kay 氏と Eric Schmidt 氏にご協力いただきました。ありがとうございました。</p>
<!-- Title: “位置情報と Bing マップを使用して位置認識アプリを作成する” Tags: “Bing マップ, 位置情報, Windows. デバイス. Geolocation, 位置情報サービス” --></div>]]></content:encoded>
    </item>
    <item>
      <title>Windows デベロッパー センターの新しいエクスピリエンスの紹介</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/windows-32057</link>
      <pubDate>Thu, 16 May 2013 09:53:00 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/05/16/windows-32057/</guid>
      <description><![CDATA[Windows デベロッパー センターの 2011 年 10 月の開設以来、Microsoft...]]></description>
      <content:encoded><![CDATA[<div class="PostContent">
<p><a href="http://msdn.microsoft.com/ja-jp/windows/default.aspx" target="_blank">Windows デベロッパー センター</a>の 2011 年 10 月の開設以来、Microsoft では世界中の開発者やデザイナーと連携しながら、アプリ開発者に向けた最適なアドバイスや、アイデア、サンプルのより良い提供方法について取り組んできました。この取り組みでは、非常に多くのアクセスと提供されたフィードバックを基に、ご好評いただいたものと改善する必要があるエクスペリエンスについて検証してきました。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0172.windows_dev_center_1EC86298.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0172.windows_5F00_dev_5F00_center_5F00_1EC86298.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Windows デベロッパー センター" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0184.windows_dev_center_thumb_1DEFFCAE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0184.windows_5F00_dev_5F00_center_5F00_thumb_5F00_1DEFFCAE.png" alt="Windows デベロッパー センター" width="600" height="338" border="0" /></a></p>
<h2>新着情報</h2>
<p>Windows チームは、現在も勢いよく成長しているアプリ エコシステムに重点を置いています。これは、優れたアプリ、経済的価値、そして新しいビジネス チャンスという形によって効果が表れます。新しいデベロッパー センターでは、アプリ開発者、デザイナー、ビジネスの連携をサポートし、優れたアプリの開発と Windows ビジネスの成功に役立つリソースを提供します。</p>
<p>これらの目的を達成するために、以下の点を強化しました。</p>
<ol>
<li>ナビゲーション モデルを変更したことにより、アプリの開発ライフサイクルの進捗状況に応じた関連コンテンツを検索できるようになりました。</li>
<li>サイトのデザインが、上位タスク、シナリオ、新しいコンテンツをハイライトできるようになりました。</li>
</ol>
<p>また、開発者が必要とするコンテンツ、サンプル、各種ダウンロードに加え、デザイナーやビジネス向けのリソースへのアクセスが簡単になりました。</p>
<p>開発するアプリに応じて、<a href="http://msdn.microsoft.com/ja-jp/windows/apps/br229512" target="_blank">Windows ストア アプリ</a>、<a href="http://msdn.microsoft.com/ja-jp/ie/" target="_blank">Internet Explorer</a>、<a href="http://msdn.microsoft.com/ja-jp/windows/desktop" target="_blank">Windows デスクトップ</a>、および <a href="http://msdn.microsoft.com/ja-jp/windows/hardware" target="_blank">ハードウェア</a>の 4 つの分野ごとにアクセスすることができます。これらのサイトでは、上述した新しく実装されたエクスペリエンスを提供しています。今回の投稿では Windows ストア アプリ特有の変更点について詳しく説明します。</p>
<h2>役割にあった最適なコンテンツを</h2>
<p>どんなに情報豊かな Web サイトでも、探している情報が見つからないと役に立ちません。何十万ものトピックを提供しているデベロッパー センターでは、情報が整理されていることや、必要な情報の見つけやすさがとても重要です。Windows ストア アプリの開発においては、デザイナーやビジネスを効率的にサポートするために必要な情報を集約しておくなど、担当する役割とシナリオに応じた分類が必要不可欠です。主な例は次のとおりです。</p>
<h3>開発者</h3>
<p>Windows ストア アプリの効果的な開発に必要なコンテンツを簡素化しました。<a href="http://msdn.microsoft.com/ja-jp/windows/apps/" target="_blank">Windows ストア アプリ ホーム ページ</a>では次のことを確認できます。</p>
<ul>
<li>"主要なタスクとコンテンツ" がわかりやすく表示されているため、必要なコンテンツをすぐに閲覧できます。国または地域固有のイベントや、サイトに新しく追加されたリソースがハイライトされます。</li>
<li>コーディングに役立つ資料のほか、アプリ開発を始めるために必要なすべてのリソースや、アプリを Windows ストアに提出するための詳細なガイドラインをダウンロードすることができます。</li>
<li>重要なコード サンプルはハイライトされ、開発ライフサイクルに沿った視点から手順を分かりやすく説明しています。</li>
<li>&ldquo;<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211360.aspx" target="_blank">One Dev Minute</a>&rdquo; (英語) では、アプリに機能を追加する方法を簡単に紹介しています。</li>
</ul>
<h3>デザイナー</h3>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh779072.aspx" target="_blank">設計セクション</a>がより包括的に、簡単に利用できるようになりました。役立つダウンロードや、再利用可能なデザイン用アセットをより簡単に検索できるほか、インスピレーションやケース スタディでは Windows 固有のエクスペリエンスに必要なツールを提供しています。個性的で存在感のあるアプリを開発するために必要な情報には、タッチ対応のわかりやすいデザインのページからアクセスすることができます。</p>
<h3>ビジネス</h3>
<p>Windows ストアにはビジネス チャンスが溢れています。他のプラットフォームよりさらに向上した経済モデルと柔軟性によってユーザーの求めるビジネスを実現します。新しい<a href="http://go.microsoft.com/fwlink/?LinkID=285998" target="_blank">市場セクション</a>では、アプリの販売促進、使用状況データの確認方法、アプリの認定テストの適合に関するさまざまなヒントを提供しています。ここでは、新しくなったコンテンツをとおして認定プロセスをスムーズに進める方法を紹介しています。</p>
<p>新しく構成されたこのサイトでは、デザインや開発など複数の役割を担当している場合でもお客様のニーズに対応しています。また、個人開発者、クリエイティブ エージェンシー、大規模企業のソフトウェア開発者でも、このサイトをご覧になり Windows で実現するビジネスの成功に役立ててください。</p>
<h2>今後の展開にご期待ください。皆様のフィードバックをお待ちしております。</h2>
<p>約 1 か月後に予定されている <a href="http://www.buildwindows.com">BUILD 2013</a> では、多くの新情報を公開する予定です。現在 Microsoft では、今年のイベントで発信する予定の新しいコンテンツ準備に取り組んでいます。この Blog を定期的にご確認いただくほか、Twitter の <a href="https://twitter.com/#!/windevs" target="_blank">@windevs</a> をフォローいただくか、<a href="http://www.windowsstore.com/newsletter-signup" target="_blank">Windows ストア ニュースレター</a>にご登録いただくと、更新情報をご確認いただけます。</p>
<p>私たちがお届けしていく Windows ストア アプリのデザイン、マーケティング、開発をサポートするコンテンツをとおして、皆様のデベロッパー センターに対するエクスペリエンスの向上を願っております。お客様がフィードバックを簡単に送信できるように、すべてのページに 2 つのフィードバック オプションを用意しました。皆様からのフィードバックをお待ちしております。私たちは常に皆様からの声に耳を向け、さらなる改善に努力していきます。</p>
<p>&nbsp;</p>
<p>Keith Boyd、コンテンツ パブリッシング マネージャー、Windows 開発者コンテンツ チーム</p>
<!-- Title: “Windows デベロッパー センターの新しいエクスピリエンスの紹介” Tags: “デベロッパー センター、デベロッパー情報、アプリ開発、Windows ストア アプリ、開発、Windows デベロッパー センター” --></div>]]></content:encoded>
    </item>
    <item>
      <title>ターゲット アプリに対する共有</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/83</link>
      <pubDate>Wed, 15 May 2013 09:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/05/15/83/</guid>
      <description><![CDATA[「Sharing from your app」(英語) では、サンプル アプリ Food with Friends (英語) のコンテンツを複数のターゲット...]]></description>
      <content:encoded><![CDATA[<div class="PostContent">
<p>「<a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/12/21/10380196.aspx" target="_blank">Sharing from your app</a>」(英語) では、サンプル アプリ <a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/07/17/metro-from-the-crowd.aspx" target="_blank">Food with Friends</a> (英語) のコンテンツを複数のターゲット アプリで共有するというアイデアを紹介しました。これらのターゲット アプリによりユーザーは、リッチなエンド ツー エンド シナリオを実現できます。Windows 8 アプリは、皆さんのユーザーが、友達や他のアプリとの間で<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465251.aspx" target="_blank">共有</a>したいと思うような興味深いコンテンツを提供しています。魅力的で優れたデザインの共有ターゲット アプリは、ユーザーのソーシャルな "つながり" のエクスペリエンスの中心になることができます。</p>
<p>この記事では、特に Food with Friends のようなアプリでの共有ターゲット コントラクトの使用方法について考えます。このコントラクトを使用するとアプリは、他のアプリからコンテンツを受信して、そのコンテンツを品質向上に役立てることができます。<em></em>私たちは、皆さんのアプリをそれぞれのカテゴリで最高のアプリへ導くお手伝いがしたいのです。</p>
<p>ターゲット アプリは、共有ターゲット <a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/03/30/windows-8-activating-contracts.aspx" target="_blank">コントラクト</a> (英語) を使用して構築されており、すばやく簡単に共有を実現できるよう設計されています。Windows のすべてのアプリが共有ターゲットになるわけではありませんが、アプリがコンテンツを発行、変換、格納、または、他のアプリから受信したコンテンツになんらかの方法で価値を追加することができる場合は、共有ターゲットを作成するとメリットがあります。</p>
<ul>
<li>アプリは常にターゲット アプリのリストに表示されるようになります。アプリはすぐに必要なデータを共有できる他のアプリと関連し、つながります。</li>
<li>共有コントラクトにより、アプリとあらゆるソース アプリの間にブリッジが作成されます。どちらのアプリでも、1 対 1 で統合する必要はありません。</li>
<li>共有チャームが常に OS に存在し、使用可能であるため、ターゲット アプリが OS でアプリの境界を越えて表示されるようになります。これにより、さらに多くのユーザーをアプリに集客することが可能になるでしょう。</li>
</ul>
<h2>共有コンテンツの受信</h2>
<p>共有ターゲット アプリで魅力的なエクスペリエンスをどのように提供できるかを示す例をいくつか見てみましょう。</p>
<p>Windows 8 のメール アプリや People アプリについては、既によくご存知かもしれません。メールでは複数の友人のコンテンツを受信して共有できる共有ターゲットの簡単でパーソナルなエクスペリエンスが作成されます。People アプリを使用すると、ソーシャル ネットワークのより幅広いユーザーとコンテンツを共有できます。ソーシャルな共有に加え、アプリ間共有でさらに機能を活用できます。SkyDrive のような生産性アプリでは、Windows のあらゆる場所からファイルを受信し、それらをクラウドに格納できます。メモ アプリでは、テキストやリンクだけでなく、場合によってはさまざまな形式のデータを受信してアーカイブし、後で参照することができます。また、創造性を発揮する余地も十分にあります。</p>
<p>以下の 2 つの図は、フォト アプリから PuzzleTouch に写真を共有するときの共有フローのようすを示しています。PuzzleTouch は、写真をビジュアルなパズルに変換するゲーム アプリです。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8637.puzzletouch1_6E4332DA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8637.puzzletouch1_5F00_6E4332DA.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="ソース アプリ (左) と、共有ウィンドウで写真を受信できるターゲット アプリのフィルターされたリスト (右)。" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1307.puzzletouch1_thumb_2681A9F3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1307.puzzletouch1_5F00_thumb_5F00_2681A9F3.png" alt="ソース アプリ (左) と、共有ウィンドウで写真を受信できるターゲット アプリのフィルターされたリスト (右)。" width="700" height="394" border="0" /></a></p>
<p align="center">図 1: ソース アプリ (左) と、共有ウィンドウで写真を受信できるターゲット アプリのフィルターされたリスト (右)。 <br />PuzzleTouch は、フォト アプリから写真を受信できる共有ターゲットの 1 つです。<em></em></p>
<p align="left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6661.puzzletouch2_463083BB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6661.puzzletouch2_5F00_463083BB.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="右はターゲット アプリのプレビュー。ここからユーザーは、作成するパズルの種類を選択できます" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/2474.puzzletouch2_thumb_65DF5D83.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/2474.puzzletouch2_5F00_thumb_5F00_65DF5D83.png" alt="右はターゲット アプリのプレビュー。ここからユーザーは、作成するパズルの種類を選択できます" width="700" height="394" border="0" /></a></p>
<p align="center">図 2: 右はターゲット アプリのプレビュー。ここからユーザーは、 <br />作成するパズルの種類を選択できます。ユーザーがアプリに戻ると、パズルが作成されています。<em></em></p>
<h2>共有ターゲット アプリとは</h2>
<p>Windows のエンド ツー エンドの共有エクスペリエンスには、2 つの構成要素があります。ソース アプリは、そのコンテンツを各種の形式で Windows に提供します。また、共有ターゲット アプリでは、特定の形式を認識し、共有するコンテンツの受け入れ先になるための登録を行います。共有コントラクトを使用して、ソース アプリと共有ターゲット アプリは相互に通信します。</p>
<p>アプリの共有エクスペリエンスを提供する場合は、ホストされた共有ウィンドウで共有ターゲット アプリをレンダリングすることを考慮してください。ユーザーが自分のコンテンツをすばやくプレビューして、このビューの共有を確認できるように、エクスペリエンスがデザインされていることを確認してください。この例では、メールの共有ターゲット アプリ ビューを示しています。このビューでユーザーは、ブラウザーからリンクを、メールの連絡先の 1 つとすばやく共有できます。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8561.Share-Target-Image_3ED44139.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8561.Share_2D00_Target_2D00_Image_5F00_3ED44139.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="共有ターゲットのイメージ" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6011.Share-Target-Image_thumb_4FD86F1C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6011.Share_2D00_Target_2D00_Image_5F00_thumb_5F00_4FD86F1C.png" alt="共有ターゲットのイメージ" width="700" height="435" border="0" /></a></p>
<p align="center">図 3: メール ターゲット アプリを使用した、フォト アプリからのリンクの共有<em></em></p>
<h2>Food with Friends のシナリオ</h2>
<p>それでは、魅力的な共有ターゲット アプリのエクスペリエンスを <a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/07/17/metro-from-the-crowd.aspx" target="_blank">Food with Friends</a> (英語) で作成する方法を考えてみましょう。このアプリを使い慣れている場合は、Food with Friends で 2 つの主な操作、つまり、プランの作成と、ウィッシュリストへのレストランの追加をユーザーが実行できることをご存知でしょう。<em></em><em></em>もちろん、レビューを書く、コメントを投稿する、友人のウィッシュリストを表示する、などの他の操作もありますが、これらのエクスペリエンスが有意義なのは、メイン アプリのコンテキスト内です。典型的な 2 つのコア シナリオに対して、これらの操作を Food with Friends ターゲット アプリで効果的に実行できるかどうかを手短に確認してみましょう。</p>
<h3>今夜のプランの作成</h3>
<p>これは、メイン アプリのコア シナリオですが、共有ターゲット エクスペリエンスの最高のシナリオではありません。なぜなら、共有ターゲット エクスペリエンスは、すばやく簡単であることがセールス ポイントであるためです。プランの作成は、手間のかかる作業です。ユーザーは、友人が他のどのレストランに行ってみたいのかを知り、ウィッシュリストにあるレストランを比較し、その評価を調べることになります。プランを作成する作業では、メイン アプリ ビューに詳しく表示された情報を活用するため、その機能を共有ターゲット アプリに集約することは、特に必要ではありません。</p>
<p>&nbsp;</p>
<h3>ウィッシュリストへの追加</h3>
<p>このシナリオは、共有ターゲットで、短く直接的なタスクとして非常に役立ちます。このアプリのエクスペリエンスの重要な部分を、いくつか示します。<strong></strong></p>
<ul>
<li>レストランは、他のアプリでも見つけることができます。たとえば、旅行プラン作成アプリ、お勧めの店を紹介する地方都市アプリ、食べ物に関するブログなどです。Food with Friends は、[My Wishlist] セクションにレストランを集めるために最適なアプリです。</li>
<li>アプリのターゲット アプリ ビューは、ユーザーが別のアプリのコンテキストで操作している間にすばやく操作できるようデザインされています。このため、ウィッシュリストにレストランを追加することは、共有ターゲットで表示するための優れた方法です。</li>
<li>ユーザーは、アプリを切り替えてレストランの検索を繰り返した後に、レストランをウィッシュリストに追加することもできますが、[共有] をすばやくタップする方がはるかに簡単です。</li>
</ul>
<p>Food with Friends のウィッシュリストは、ユーザーがデザインして作成するには最適な共有ターゲット アプリ エクスペリエンスです。念頭に置いているエンド ツー エンドのシナリオは、次のとおりです。</p>
<p>地域のフード トラックを表示するアプリを閲覧している間に、面白そうなフード トラックのお勧め記事を見つけました。後でプランを作成するときに役立つよう、このアプリからフード トラックを Food with Friends の [My Wishlist] に追加します。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7658.contoso_truck_6C263411.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7658.contoso_5F00_truck_5F00_6C263411.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="アプリをブラウズすると、地域のフード トラックが表示され、気になる場所が紹介されます" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3022.contoso_truck_thumb_4B9EF45F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3022.contoso_5F00_truck_5F00_thumb_5F00_4B9EF45F.png" alt="アプリをブラウズすると、地域のフード トラックが表示され、気になる場所が紹介されます" width="700" height="394" border="0" /></a>図 4:アプリをブラウズすると、地域のフード トラックが表示され、気になる場所が紹介されます<em></em></p>
<p>この図は、使用する共有ターゲット アプリ ビューを表します。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3835.contoso_truck2_565C4BB4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3835.contoso_5F00_truck2_5F00_565C4BB4.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="共有ターゲット アプリ ビュー" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/8637.contoso_truck2_thumb_760B257C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/8637.contoso_5F00_truck2_5F00_thumb_5F00_760B257C.png" alt="共有ターゲット アプリ ビュー" width="700" height="394" border="0" /></a></p>
<p align="center">図 5: 共有ターゲット アプリ ビュー<em></em></p>
<p>ターゲット アプリ ビューで共有操作を完了すると、ユーザーは、現在のイマーシブなアプリのエクスペリエンスからコンテキストを切り替えることなく、Food with Friends でレストランをキュレーションできます。</p>
<h2>共有ターゲットの実装</h2>
<p>共有ターゲットを実装すべき状況の例をいくつか紹介しましたので、今度は、共有ターゲットの実装方法を見てみましょう。まず、アプリが受信できるデータ形式を決定します。</p>
<h3>サポートすべきデータ形式はどれか</h3>
<p>共有では、テキスト、URI、HTML、ビットマップ、ファイルなどの標準データ形式、または <a href="http://schema.org" target="_blank">http://schema.org</a> の一覧にあるものなどのカスタム データ形式をサポートできます。Windows では、サポートしているデータ形式でターゲット アプリがフィルターされ、フィルター後のターゲット アプリの一覧が共有ウィンドウに表示されます。アプリは、アプリ エクスペリエンスに重要なデータ形式をサポートしている必要があります。たとえば、写真を表示するアプリの場合は、テキスト形式をサポートしても役に立たないかもしれません。複数のデータ形式のサポートを宣言する場合は、共有データを表すのに最も役立つデータ形式を決定して、それを最初にデータ パッケージから選択できるようにしてください。</p>
<p>Food with Friends が実装している共有ターゲット エクスペリエンスでは、ユーザーがアプリを対象にレストランを共有できるため、ここでは、<a href="http://schema.org" target="_blank">http://schema.org</a> (英語) の一覧にある <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a> (英語) データ形式を使用します。Food with Friends は、共有ターゲット コントラクトに登録して、このデータ形式を受信できます。そして、受信したパッケージのデータを使用し、そのターゲット アプリ ビューで魅力的なエクスペリエンスを作成できます。これで、ユーザーは自分のウィッシュリストにそのレストランを追加できます。</p>
<p>一部のソース アプリが明確に <a href="http://schema.org/Restaurant" target="_blank">Restaurant</a> (英語) データ形式を共有するのに対し、その他のソース アプリは、<a href="http://schema.org/" target="_blank">schema.org</a> (英語) の一覧にある <a href="http://schema.org/Place" target="_blank">Place</a> (英語)、<a href="http://schema.org/LocalBusiness" target="_blank">LocalBusiness</a> (英語)、および <a href="http://schema.org/FoodEstablishment" target="_blank">FoodEstablishment</a> (英語) のような他のデータ形式を使用して、同様の情報を表します。このため、Food with Friends は、共有コントラクトでの複数の形式の受信をサポートし、多種多様なソース アプリに提供することができます。</p>
<p>Food with Friends は、アプリ マニフェストの共有ターゲット宣言で次の形式をサポートしています。</p>
<ul>
<li><span style="text-decoration: underline;"><a href="http://schema.org/Restaurant" target="_blank">Restaurant</a></span> (英語)</li>
<li><span style="text-decoration: underline;"><a href="http://schema.org/Place" target="_blank">Place</a></span> (英語)</li>
<li><span style="text-decoration: underline;"><a href="http://schema.org/LocalBusiness" target="_blank">LocalBusiness</a></span> (英語)</li>
<li><span style="text-decoration: underline;"><a href="http://schema.org/FoodEstablishment" target="_blank">FoodEstablishment</a></span> (英語)</li>
</ul>
<p>&nbsp;</p>
<p>ここでは、簡潔に説明するために、<a href="http://schema.org/Restaurant" target="_blank">Restaurant</a> (英語) というデータの種類を取り上げますが、その概念は、他のデータの種類にも適用されます。</p>
<h3>除外すべきデータ形式とシナリオ</h3>
<p>Food with Friends がサポートするのは、アプリが既に認識しているレストランの情報と、受信したレストラン情報が一致した場合に、ユーザーのウィッシュリストにレストランを追加することだけです。これは、アプリに同じレストランが複数追加されないようにするための意図的な動作です。</p>
<p>標準的なデータの種類はサポートされていません。なぜなら、ソース アプリから共有したテキスト、ファイル、写真、URI、または HTML は、レストランと地元の企業のどちらにも関連付けられないためです。たとえば、Food with Friends がテキストの受信をサポートしているとすると、ソースであるメモ アプリのターゲット アプリ リストに Food with Friends が表示されることになります。この場合、Food With Friends は、ユーザーのソース アプリと連携しない理由を示すエラー メッセージをユーザーに表示する必要があります。つまり、データ形式によって、ソース アプリとその提供先のターゲット アプリがつながっているのです。データ形式が異なる場合は、共有する価値のあるものは存在しません。</p>
<p>必ず、重要であることがすぐわかるようなデータ形式をすべて考慮して、共有エクスペリエンスに役立たないデータ形式は除外するようにしてください。</p>
<h3>共有ターゲット コントラクトのサポート</h3>
<p>データ形式をサポートするには、アプリの Visual Studio マニフェスト デザイナーでデータ形式を宣言します。ユーザーが共有操作のターゲットとしてアプリを選択すると、次のようになります。</p>
<ol>
<li>アプリの新しいインスタンスが、ソース アプリに優先して、共有ターゲット ウィンドウで起動されます。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.activation.sharetargetactivatedeventargs.aspx" target="_blank">共有ターゲット アクティベーション</a> イベントが実行され、その結果、アプリが <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a><strong></strong> オブジェクトを受信します。</li>
<li>アプリは、このオブジェクトからユーザーが共有したデータを取得できます。</li>
<li>このデータを使用してターゲット アプリ ビューをレンダリングし、ユーザーの共有を完了できます。</li>
</ol>
<p>このエクスペリエンスの作成方法の詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465255.aspx" target="_blank">クイックスタート: 共有コンテンツの受信</a>」ガイドを参照してください。</p>
<p>さらに、Visual Studio では、共有ターゲットのテンプレートをサポートしています。プロジェクトを右クリックし、<strong>[項目の追加]</strong>、<strong>[新しい項目の追加]</strong> をクリックして、リストにある <strong>[共有ターゲット コントラクト]</strong> をクリックすると、コントラクトをサポートするために追加されたコードが表示されます。共有コンテンツを受信する方法は、「<a href="http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782" target="_blank">Sharing content target app sample</a>」(英語) に記載されています。</p>
<h2>カスタマイズされたターゲット アプリ ビューのデザイン</h2>
<p>ユーザーが、共有ウィンドウのアプリ一覧からターゲット アプリを選択すると、アプリが起動され、その共有ターゲット ビューが表示されます。ターゲット アプリ ビューは、共有ウィンドウでホストされた特別なビューで、アプリのメイン ビューとは異なります。「<a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/03/30/windows-8-activating-contracts.aspx" target="_blank">Activating Windows 8 contracts in your app</a>」(英語) には、ホストされたビューと、これらのビューのアクティベーションの詳細が記載されています。ターゲット アプリ ビューは、ユーザーが開始した共有操作を完了できるようにデザインされています。このビューでは、ユーザーがコンテンツを一目でプレビューでき、簡単な操作を行って、共有することを確定できます。</p>
<p>Food with Friends のターゲット アプリ デザインを説明する前に、既に知っているターゲット アプリについて考えてみましょう。下の図は、メール アプリのターゲット アプリ ビューと、このアプリの Windows 8 での全画面表示ビューです。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1307.target-app_4AC68E75.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1307.target_2D00_app_5F00_4AC68E75.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="フォト アプリからターゲットのメール アプリへの共有 (右)" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0724.target-app_thumb_5583E5CA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0724.target_2D00_app_5F00_thumb_5F00_5583E5CA.png" alt="フォト アプリからターゲットのメール アプリへの共有 (右)" width="700" height="438" border="0" /></a></p>
<p align="center">図 6: フォト アプリからターゲットのメール アプリへの共有 (右)<em></em></p>
<p align="left"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1385.mail_154DCC50.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1385.mail_5F00_154DCC50.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="メールのメイン アプリ ビューでの新規メール作成" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/2055.mail_thumb_510D6503.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/2055.mail_5F00_thumb_5F00_510D6503.png" alt="メールのメイン アプリ ビューでの新規メール作成" width="700" height="438" border="0" /></a></p>
<p align="center">図 7: メールのメイン アプリ ビューでの新規メール作成<em></em></p>
<p>メールの共有ターゲット アプリ ビューは、その全画面アプリ ビューよりシンプルであることがわかります。ユーザーが共有しようとしているコンテンツの必要最小限のプレビューが、サムネイルと関連テキストおよび HTML 形式で表示されます。受信者を追加するための <strong>[宛先]</strong> 行や、簡単なメッセージを作成するための入力領域があり、メールの送信を <strong>[送信]</strong> ボタンで簡単に確定できます。</p>
<p>アプリのターゲット アプリ ビューはシンプルなビューですが、メール アプリと同じ機能を持つことが明確にわかるため、ユーザーは安心して、共有コンテンツを宛先に送信できます。</p>
<h2>共有ターゲット アプリとしての Food with Friends</h2>
<p>ターゲット アプリ ビューのデザインの概要を理解したので、今度は、ユーザーが [My Wishlist] にレストランを追加するために使用するターゲット アプリを Food with Friends で作成する方法を説明しましょう。</p>
<p>Food with Friends は、<a href="http://schema.org/Restaurant">Restaurant</a> (英語) を含むデータ パッケージをソース アプリから受信すると、<a href="http://schema.org/Restaurant">Restaurant</a> (英語) データ形式の詳細を使用して、既存のデータベースにあるレストランから、受信したデータ パッケージと一致するものを見つけます。そして、そのレストランのプレビューをターゲット アプリ ビューに表示できます。これで、共有されているコンテンツの整合性に対する信頼度が向上します。</p>
<p>下の図は、Food with Friends のターゲット アプリ ビューです。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3837.contoso_truck3_0305058E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3837.contoso_5F00_truck3_5F00_0305058E.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Food with Friends のターゲット アプリ ビュー" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5584.contoso_truck3_thumb_1B94A2DE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5584.contoso_5F00_truck3_5F00_thumb_5F00_1B94A2DE.png" alt="Food with Friends のターゲット アプリ ビュー" width="700" height="394" border="0" /></a>図 8:Food with Friends のターゲット アプリ ビュー<em></em></p>
<p>ここに示すように、この Food with Friends のビューはシンプルで、共有ターゲット アプリ向けに調整されています。ここには、ユーザーが共有しようとしているレストランのプレビューと、操作しやすいシンプルなボタン、<strong>[ウィッシュリストへの追加]</strong> が表示されており、共有コンテンツのメイン アプリでの宛先が明確にわかります。ユーザーがこのボタンをタップまたはクリックすると、共有操作が確定されます。ここで、タップまたはクリックが要求されるため、誤って共有することが防止され、共有エクスペリエンス全体に対する信頼が築かれます。</p>
<p>アプリで、データ パッケージ コンテンツの情報と一致するレストランが複数見つかった場合は、Food with Friends が共有ターゲット アプリ ビューでそれらを表示し、ユーザーはそこから、共有するものを選択できます。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5582.contoso_truck4_70500BD6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5582.contoso_5F00_truck4_5F00_70500BD6.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="ターゲット アプリ ビューに選択肢が表示され、そこからユーザーは、共有するものを選択できます" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/6175.contoso_truck4_thumb_6FE3D8E1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/6175.contoso_5F00_truck4_5F00_thumb_5F00_6FE3D8E1.png" alt="ターゲット アプリ ビューに選択肢が表示され、そこからユーザーは、共有するものを選択できます" width="700" height="394" border="0" /></a></p>
<p align="center">図 9: ターゲット アプリ ビューに選択肢が表示され、ユーザーはそこから、共有するものを選択できます<em></em></p>
<p>&nbsp;</p>
<p>アプリが正確にレストランを識別できないか、受信したデータ パッケージに基づいて有効な選択肢を識別できない場合は、ターゲット アプリ ビューを使用して、そのことを示すメッセージを伝えてください。</p>
<h2>QuickLink の作成</h2>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.quicklink.aspx" target="_blank">QuickLink</a> とは、共有 API に用意された機能の 1 つで、これによってユーザーは、ターゲット アプリ内の使い慣れた共有先とすばやくコンテンツを共有できます。QuickLink は、ターゲット ビューへのカスタマイズ済みリンクで、特定の動作を提供します。Windows で、ユーザーが使用できるターゲット アプリの一覧がフィルターされると、QuickLink の一覧は、共有ウィンドウの最上部に、使用可能なターゲットの一覧として表示されます。これらの使い慣れた共有先またはユーザー操作には、よくターゲット アプリ経由で共有される場所や人々が含まれる場合があります。たとえば、メール アプリは、以前にメールした連絡先として QuickLink を返します。同様に、ターゲット アプリに対してよく共有するフォルダー、グループ、ノートブック、およびプレイリストに QuickLink を追加できます。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5001.quicklink_2FADBF67.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5001.quicklink_5F00_2FADBF67.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="以前にターゲット アプリを使ってメールを送信した連絡先としてメール ターゲット アプリが提供した QuickLink を表示した共有ウィンドウ" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1374.quicklink_thumb_334BDA44.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1374.quicklink_5F00_thumb_5F00_334BDA44.png" alt="連絡先としてメール ターゲット アプリが提供した QuickLink を表示した共有ウィンドウ" width="700" height="438" border="0" /></a></p>
<p align="center">図 10: 以前にターゲット アプリを使ってメールを送信した連絡先として <br />メール ターゲット アプリが提供した QuickLink を表示した共有ウィンドウ<em></em></p>
<p>ターゲット アプリは、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a> オブジェクトの <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportcompleted.aspx" target="_blank">reportCompleted</a> メソッドを呼び出して、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.quicklink.aspx" target="_blank">QuickLink</a> を提供できます。<strong></strong><strong></strong><strong></strong><strong></strong>QuickLink には、タイトル、アイコン、および ID が必要です。タイトル ("母にメール" など) とアイコンは、ユーザーが共有チャームをタップすると表示されます。ID は、アプリが、メール アドレスやフォルダーの場所などのカスタム情報にアクセスするために使用します。このツールの詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh758299.aspx" target="_blank">クイックリンクを作成する方法</a>」を参照してください。&nbsp;</p>
<p>注: QuickLink は、ターゲット アプリからの複数の操作をアプリがサポートしている場合に便利です。Food with Friends がサポートしているのは、共有ターゲットで単一の操作、つまり、<strong>[ウィッシュリストへの追加]</strong> のみであるため、アプリは QuickLink を実装しません。</p>
<h2>拡張共有とエラー レポート機能</h2>
<p>ソース アプリが、写真、ビデオ、または長い転送時間が必要になるファイルのような、サイズの大きいデータを共有する場合があります。このような共有操作は拡張共有<em></em>と呼ばれており、ターゲット アプリが、データの受信と処理に長時間を要する場合があります。</p>
<p>共有は短時間で円滑に行われるものであり、ターゲット アプリ ビューは、メイン アプリに優先する軽量のホストされたビューであるため、ユーザーがタップして、ターゲット アップ ビューからメイン アプリに戻る可能性があります。このため、ターゲット アプリでは、共有の開始後にユーザーによるターゲット アプリ ビューの操作を必要としたり、想定したりするべきではありません。ターゲット アプリは、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br205977.aspx" target="_blank">ShareOperation</a><strong></strong> オブジェクトとそのメソッドを使用して、データの処理中であることを Windows に知らせることができます。</p>
<ul>
<li><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportstarted.aspx" target="_blank">reportStarted</a></strong> &ndash; このメソッドを呼び出して、アプリがソース アプリから DataPackage オブジェクトのデータを取得し始めたことを Windows に知らせます。</li>
<li><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportdataretrieved.aspx" target="_blank">reportDataRetrieved</a></strong> &ndash; このメソッドを呼び出して、アプリがパッケージのデータを取得し終わったことを Windows に知らせます。<strong></strong></li>
<li><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget.shareoperation.reportcompleted.aspx" target="_blank">reportCompleted</a></strong> <strong><span style="text-decoration: underline;">&ndash;</span></strong> このメソッドを呼び出して、アプリが共有操作を完了したことを Windows に知らせます。<strong></strong><strong></strong></li>
</ul>
<p>アプリが拡張共有のデータを処理している間は、ターゲット アプリ ビューに進捗状況 UI が表示されるようにしてください。こうすると、要求の処理中であることがユーザーにわかるため、アプリに戻って、共有操作の進捗を確認したときに信頼度が向上します。Windows 8 のプログレス コントロールの詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465487.aspx" target="_blank">クイック スタート: プログレス コントロールの追加</a>」を参照してください。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0702.progress-bar_52FAB40C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0702.progress_2D00_bar_5F00_52FAB40C.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="進捗状況バー" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3438.progress-bar_thumb_40B1ED4A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3438.progress_2D00_bar_5F00_thumb_5F00_40B1ED4A.png" alt="進捗状況バー" width="700" height="438" border="0" /></a></p>
<p align="center">図 11: メール ターゲット アプリ ビューには、サイズの大きい添付ファイルの送信などの拡張共有を完了するときに進捗状況リングが表示されます<em></em></p>
<p>データ転送中に問題が発生したためにターゲット アプリで共有操作の終了が必要になった場合は、<strong><span style="text-decoration: underline;">reportError</span></strong> を呼び出して、Windows にエラー メッセージを送信できます。このメッセージは、ユーザーが共有ウィンドウで共有の状態をチェックしたときに表示されます。エラーをレポートした後、アプリがシャットダウンされ、共有が終了します。ユーザーは、アプリとコンテンツを共有するには、再起動する必要があります。</p>
<p>Food with Friends の共有ターゲットの例では、<a href="http://schema.org/Restaurant" target="_blank">Restaurant</a> (英語) データ形式でソース アプリから共有したレストランに一致するものがデータベースで見つからない場合、アプリはエラーをレポートする必要があります。</p>
<h2>復習しましょう</h2>
<p>アプリ間の共有は、ターゲット アプリを共有する絶好の機会です。アプリが共有コンテンツを受信できるようにすると、ユーザーは、別のアクティビティを行っている間でも、アプリから価値を得ることができます。デザインの原則だけでなく、優れた共有ターゲットを作成するために使用できるデータの種類、クラス、プロパティについて、理解を深めていただくことが私たちの願いです。 皆さんのアプリで共有コンテンツが変化し、幅広く豊かなエンド ユーザー エクスペリエンスが作成されていくのを見ると、実に嬉しく思います。</p>
<p>共有の詳細について調べるには、最初に「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh464923.aspx" target="_blank">データの共有と交換</a>」および「<a href="http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782" target="_blank">Share content target app sample</a>」(英語) をお読みください。</p>
<p>Ishita Kapur</p>
<p>プログラム マネージャー</p>
<p>Windows ユーザー エクスペリエンス</p>
<!-- Title: “ターゲット アプリに対する共有” Tags: “アプリの共有、ターゲット アプリ、共有コンテンツ、共有ターゲット、ターゲット アプリの共有” --></div>]]></content:encoded>
    </item>
    <item>
      <title>NFC を使った最先端のアプリの開発</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/nfc</link>
      <pubDate>Thu, 25 Apr 2013 17:48:36 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/04/25/nfc/</guid>
      <description><![CDATA[近距離無線通信 (NFC) は、現在発展しつつある短距離のワイヤレス テクノロジです。NFC を利用すると、ちょうど 2 cm...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"> <p>近距離無線通信 (NFC) は、現在発展しつつある短距離のワイヤレス テクノロジです。NFC を利用すると、ちょうど 2 cm の範囲内で、デバイスどうしを物理的にタップしてコンテンツの送受信を行うことができます。タップすると、何か (またはだれか) をすばやく選択できます。これはすばやいだけでなく、わかりやすい操作でもあります。一度見れば理解できるので、説明書は必要ありません。</p>  <p>たとえば、友だちと一緒に写真を見ているとき、その友だちがあなたの写真をほしがったとします。NFC を使えば、あなたのデバイスを友だちの PC に対してタップするだけで写真を送信できます。この説明は少々単純化しすぎているかもしれませんが、要点は、デバイス間でのコンテンツの共有がシンプルになるということです。</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/1732.NFC-image_04E645BB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/1732.NFC_2D00_image_5F00_04E645BB.png"><img title="&#39;Nokia 360 スピーカーで Bluetooth ペアリング情報を Windows Phone と共有しているところ" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="&#39;Nokia 360 スピーカーで Bluetooth ペアリング情報を Windows Phone と共有しているところ" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3566.NFC-image_thumb_38420917.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3566.NFC_2D00_image_5F00_thumb_5F00_38420917.png" width="400" height="348" /></a></p>  <p align="center">図 1: Nokia 360 スピーカーで Bluetooth ペアリング情報を   <br />Windows Phone と共有しているところ</p>  <p>Bluetooth や Wi-Fi と同様に、NFC は標準ワイヤレス プロトコルの 1 つで、<a href="http://www.nfc-forum.org/home/" target="_blank">NFC フォーラム</a><u></u> (英語) によって定義されています。<u></u>NFC を利用するには、PC が NFC 通信機能を搭載している必要があります。Windows 8 PC には、NFC 通信機能が直接組み込まれているものが多くあります。お使いの PC に NFC が搭載されていない場合は、NFC ドングルを購入して PC に装着することもできます。</p>  <p>NFC は便利な機能を実現します。タップして写真を送信したり、レストランでメニューをタップして料理を注文したりできるほか、タップして Bluetooth デバイスをペアリングすることも可能です。これらは互いに大きく異なるシナリオですが、"タップ" して操作を始めるという点が共通しています。NFC は、PC、携帯電話、スピーカー、ヘッドセット、ワイヤレス ディスプレイなど、さまざまなデバイスで使用され、きわめて直感的な方法でデバイスどうしを接続します。また、NFC で使われる RFID タグは、非常に安価で軽量な受動アンテナで、相当な量のデータを保持することができ、実質的に何にでも貼り付けることができます。よくある利用例はポスターです。たとえば、映画のチケット購入を、映画のポスターをタップするだけというシンプルな手順にできるのです。この記事では、NFC タグをタップする基本的な例を紹介しながら、NFC API の主要概念の一部について具体的に説明します。</p>  <p>その前に、デバイスどうしをタップするとはどういうことか、もう少し詳しく見てみましょう。</p>  <h2>"タップ" の定義</h2>  <p>タップして Bluetooth マウスをペアリングする場合でも、タップして写真を共有する場合でも、重要なのは、デバイスどうしを同じようにタップするという点です。タップ自体はよく知られた概念ですが、PC を別のデバイスに対してタップするという動作は、多くのユーザーにとって新しいものです。このようなタップ操作に関して、ユーザーに伝えるべき情報を示すガイドラインの一部を以下に紹介します。</p>  <ol>   <li>     <div align="center"><b>デバイスどうしをタップする位置を示す</b> - タッチマークを使用して NFC アンテナの位置を示します。タッチマークは、"Tap and Do" ビジュアル マークとも呼ばれます。タップする部分は、PC のモデルによって異なります。たとえば、タブレットでは背面であったり、オールインワン モデルでは前面であったりする可能性があります。NFC 対応の Windows 8 PC では、次のようなマークが使われます。        <br /></div>     <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/0830.NFC-logo_66E85720.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/0830.NFC_2D00_logo_5F00_66E85720.png"><img title="Tap and Do ビジュアル マーク" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="Tap and Do ビジュアル マーク" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5611.NFC-logo_thumb_3FAE0DEB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5611.NFC_2D00_logo_5F00_thumb_5F00_3FAE0DEB.png" width="200" height="147" /></a>      <p align="center">図 2: Tap and Do ビジュアル マーク</p>   </li>    <li><b>デバイスが相互に通信していることを示す</b> - タップしている間、転送中のデータは目に見えなくても、何かが行われていることをユーザーが確信できるようにする必要があります。Windows では、デバイスどうしが通信範囲内にあって相互に通信しているときにサウンドが再生されます。</li> </ol>  <p>これらは Windows によって自動的に行われるため、アプリ開発者は気にする必要はありません。このようなユーザー エクスペリエンス要素の詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/hardware/hh770524.aspx" target="_blank">Windows 8 の近距離通信実装の仕様</a>」<u></u>を参照してください。以上を念頭に置いたうえで、NFC で実現できる便利なシナリオをいくつか見ていきましょう。</p>  <h2>NFC を活用できる場面</h2>  <p>NFC は、アプリ内でユーザーが何かを選択する必要があるとき、またはだれかを選択する必要があるときに使用します。NFC によって実現される選択方法は直感的で、多くの場合、手動で検索するよりもすばやく (かつクールに) 行うことができます。この操作を開始するトリガーがタップです。操作の結果はアプリによって異なり、写真の受信からプレイリストの再生までさまざまなものがあります。タップの後に何が起きるかを決めるのは、それぞれのアプリに任されています。話をシンプルにするために、私たちはこの一連の動作をまとめて "Tap and Do" エクスペリエンスと呼んでいます。</p>  <p>以下に、NFC を使ってアプリで何かを選択する例をいくつか紹介します。たとえば、タップして次のようなことを実行できます。</p>  <ul>   <li><u>ポスターから情報を取得する</u>: <a href="http://www.nfc-forum.org/news/pr/view?item_key=2c0cb92de7d47bbbe7c99f13912b3307fc03c1c6" target="_blank">NFC タグ</a> (英語) は軽量で安価な RFID タグであり、$0.15 ～ $1.00 程度で入手できます (価格は印刷料金に応じて変わります)。これらは QR コードと互換性がありますが、より簡単にすばやく使用できます。タグをタップする操作は、バー コードの写真を (カメラのアングルを気にしながら) 撮影するよりも快適です。空港、地下鉄駅、バス停などの通行量の多い場所で、ポスターにタグを埋め込むメーカーが増えています。タグには 48 B ～ 4 KB のデータを保持できます。タグは、独自のアプリを起動して特定のページを開くようにプログラミングすることができます。</li> </ul>  <ul>   <li><u>連絡先情報を交換する</u>: 自分の連絡先情報を友だちに伝えるとき、相手が正しく書き取ってくれることを期待しながら 1 文字ずつ説明する必要はありません。互いのデバイスをタップして連絡先情報を交換できます。同様の例として、NFC 対応の名刺/タグに自分の情報をプログラミングしたり、アプリを通じて直接情報を交換したりすることもできます。</li>    <li><u>お気に入りの音楽放送局を聴く</u>: ジムに行こうとしているときでも、車に乗り込んだときでも、自宅でくつろいでいるときでも、NFC タグを使用してラジオを流し始めることができます。別々のタグに別々の音楽放送局をプログラミングすることも可能です。たとえば、ジム用のタグ、くつろいだ時間のためのタグ、就寝時のタグのように使い分けることができます。</li>    <li><u>混雑したレストランで食事を注文する</u>: 人気のあるレストランに夕食の時間帯に行くと、注文するだけでも長時間待たされることがあります。店員を待つ代わりに、テーブルでタグをタップして食事を注文できます。</li>    <li><u>友だちとマルチプレイヤー ゲームをプレイする</u>: バトルシップ、チェス、スクラブルなどのマルチプレイヤー ゲームで、デバイスどうしをタップするだけで簡単に友だちと接続できます。タップした後は、Bluetooth や Wi-Fi Direct など、より広範囲で高スループットの帯域外トランスポートを介して接続が維持されます。</li> </ul>  <p>ここまでの説明では、NFC を活用できる場面について魅力的なアイデアを紹介してきました。次はお待ちかね、Windows 8 の Proximity (NFC) API を使うアプリの作成方法についてお話しします。</p>  <h2>NFC の実装方法</h2>  <p>おわかりのように、NFC によって、エンド ユーザーはさまざまな日常のタスクをより簡単に行えるようになります。ここでは、例としてアラームの設定を取り上げます。朝のアラームの時刻を間違えて設定してしまった経験はだれにでもあるでしょう。夜遅くなって早く眠りたいと思っているときは、頭が十分に働いているとは限らないものです。でも、NFC を使えば簡単です。あらかじめ設定したタグをタップして確認するだけで、何の心配もなく眠ることができます。この毎日の習慣を支援するために、ここでは、NFC タグを使ってアラームを設定できる基本的なアラーム アプリを作成すると想定しましょう。これは 2 つのシナリオに分けられます。</p>  <ol>   <li><u>タグ<b>に</b>アラームを設定する</u>: NFC タグは再利用が可能なので、アプリでは、ユーザーがアラームを設定するための手段を用意する必要があります。たとえば、平日用と週末用など、複数のアラームを設定したい場合があります。これは、タグにデータを発行するというシナリオです。</li>    <li><u>タグ<b>から</b>アラームを設定する</u>: ユーザーがタグをタップしたら、アプリを起動してアラームの設定を確認する必要があります。これは、コンテキスト (引数) を指定してアプリを起動できるようにするということです。</li> </ol>  <p>NFC API には同じ処理を実現できる方法がいくつかありますが、ここでは最も簡単な方法でこのシナリオを実装します。</p>  <p>まず、NFC タグにアラームを設定する流れを順番に見ていきましょう。</p>  <ol>   <li>ユーザーがアラーム アプリを起動して時刻を設定します。設定時刻は午前 7 時とします。これは通常のアラームの操作で、まだ NFC は使いません。</li>    <li>次に、ユーザーが "NFC タグにアラームを設定する" オプションを選択します。このとき、アプリでは NFC API を呼び出して NFC 通信機器に情報を発行します。具体的には、アプリの識別子文字列と 07:00 という情報が発行されます。NFC タグでは NDEF (NFC Data Exchange Format) という標準メッセージ形式が使われますが、NDEF メッセージ形式へのデータの変換をアプリが心配する必要はなく<b></b>、Windows が自動的に処理してくれます。これで、ユーザーが NFC タグをタップできるようになります。</li>    <li>ユーザーが PC に対してタグをタップすると、アプリがタグのプログラミングを確認します。タグがタップされたら、アプリでタグを正しくプログラミングしたという結果をユーザーに通知することが重要です。既に説明したとおり、PC をタップする操作は多くのユーザーにとって新しい概念です。そのため、確認の通知を返して、操作がうまくいったことをユーザーが確信できるようにします。アプリでは、メッセージ転送ハンドラーを登録することで、メッセージが正しく転送されたことを検出できます。</li> </ol>  <p>NFC API は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.proximity.aspx" target="_blank">Windows.Networking.Proximity</a> 名前空間に用意されています。手順 2 でユーザーが "NFC タグのアラームを設定する" オプションを選択したら、この API の出番です。まず、アプリで近接通信オブジェクトを初期化します。近接通信オブジェクトは、タグ (またはデバイス) が範囲内に入ったこと、あるいは範囲から外れたことを検出するために使われます。次に、DeviceArrival イベント ハンドラーを追加します。このハンドラーはタグがタップされたことを認識します。つまり、このハンドラーが呼び出されたらタグへの情報の書き込みを開始できます。タグへの書き込み中は、その状況がユーザーに伝わるようにすると、デバイスが通信範囲外に動かされるのを防ぐために役立ちます。同じイベントを使用して、近接通信デバイスがタップされたことも認識できます。</p>  <p>初期化して DeviceArrival イベント ハンドラーを追加する方法を次のコードに示します。</p>  <p><strong>JavaScript</strong></p>  <blockquote>   <div>     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> initializeProximityDevice() {<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (proximityDevice) {<br />        proximityDevice.addEventListener(<span style="color: rgb(0, 96, 128);">&quot;devicearrived&quot;</span>, proximityDeviceArrived);<br />       <br />}<br />   <span style="color: rgb(0, 0, 255);">else</span> {<br />        <span style="color: rgb(0, 128, 0);">// No NFC radio on the PC, display an error message</span><br />    }<br /><br /><br /><span style="color: rgb(0, 0, 255);">function</span> proximityDeviceArrived(device) {<br />        <span style="color: rgb(0, 128, 0);">// Let the user know we’re ‘Writing to Tag’</span><br /><br />}<br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> InitializeProximityDevice()<br />{<br /><br />Windows.Networking.Proximity.ProximityDevice proximityDevice;<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br />    <span style="color: rgb(0, 0, 255);">if</span> (proximityDevice != <span style="color: rgb(0, 0, 255);">null</span>) {<br />        proximityDevice.DeviceArrived += ProximityDeviceArrived;<br />    <br />    }<br />    <span style="color: rgb(0, 0, 255);">else</span><br />    {<br />        <span style="color: rgb(0, 128, 0);">// No NFC radio on the PC, display an error message</span><br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> ProximityDeviceArrived(Windows.Networking.Proximity.ProximityDevice device)<br />{<br />            <span style="color: rgb(0, 128, 0);">// Let the user know we’re ‘Writing to Tag’</span><br /><br />}<br /></pre>
  </div>
</blockquote>

<p>
  <br />次に、情報をタグに発行します。アプリが発行する情報は 2 つあります。1 つはアプリの識別子文字列で、これはアプリ ID とアプリ プラットフォームから構成されます。もう 1 つは起動引数です。Windows 8 では、アプリ ID は&lt;<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.applicationmodel.packageid.familyname.aspx" target="_blank">パッケージのファミリ名</a>>!&lt;<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211415.aspx" target="_blank">アプリ Id</a>> (リンク先は英語の可能性があります)、アプリ プラットフォームは "Windows" になります。アプリ ID の値は、アプリのパッケージ マニフェストに記述されている Application 要素の ID 属性からコピーする必要があります。起動引数は "07:00" で、ユーザーが設定したアラームを表します。これを "<b>メッセージ</b>" と呼ぶことにしましょう。</p>

<p>アプリが複数のプラットフォームで動作する場合は、代替のアプリ ID とアプリ プラットフォームを発行できます。これにより、NFC をサポートする別のデバイス (Windows Phone 8 など) でも同じタグをタップできるようになります。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.proximity.peerfinder.alternateidentities.aspx" target="_blank">代替 ID</a> の詳細については、MSDN を参照してください。</p>

<p>アプリからタグにデータを発行するには、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh701134.aspx" target="_blank">publishBinaryMessage</a> というメソッドを使用します。このメソッドは、パラメーターとして messageType、message、および messageTransmittedHandler 関数の 3 つを受け取ります。今回の例では、messageType を "LaunchApp:WriteTag" に設定して、アプリから NFC タグに情報を書き込もうとしていることを Windows に伝えます。message は、先ほど定義したメッセージ (アプリの識別子文字列と起動引数) です。バッファーには、メッセージをバイナリ メッセージとして格納する必要があります。messageTransmittedHandler 関数はコールバックに登録されます。これを通じて、メッセージがタグに正しく書き込まれたことがアプリに通知されます。アプリでは、この関数を使って、メッセージがタグに正しく書き込まれたこと、およびタグを通信範囲内に保つ必要がなくなったことの 2 点をユーザーに通知します。</p>

<p>メッセージは、StopPublishingMessage 関数を呼び出すまで、または ProximityDevice オブジェクトが解放されるまで発行され続けます。この記事の例では停止関数を使用します。PublishBinaryMessage はパブリケーション ID を返すので、その同じパブリケーション ID を使って NFC 通信機器へのメッセージの発行を停止します。</p>

<p>次のコード スニペットでは、NFC タグにデータを書き込む方法を示します。</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">var</span> proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">function</span> getAlarmTime(){<br /><br />    <span style="color: rgb(0, 128, 0);">// Grab time set by the user, call this variable ‘Alarm’</span><br />    <span style="color: rgb(0, 0, 255);">return</span> Alarm;<br /><br />}<br /><br /><span style="color: rgb(0, 0, 255);">function</span> publishLaunchApp() {<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br /><span style="color: rgb(0, 0, 255);">if</span> (proximityDevice) {<br />        <span style="color: rgb(0, 128, 0);">// The format of the app launch string is: &quot;&lt;args&gt;\tWindows\t&lt;AppName&gt;&quot;.</span><br />        <span style="color: rgb(0, 128, 0);">// The string is tab or null delimited.</span><br /><br />        <span style="color: rgb(0, 128, 0);">// The &lt;args&gt; string can be an empty string (&quot;&quot;).</span><br />        <span style="color: rgb(0, 0, 255);">var</span> launchArgs = getAlarmTime();<br /><br />        <span style="color: rgb(0, 128, 0);">// The format of the AppName is: PackageFamilyName!PRAID.</span><br />        <span style="color: rgb(0, 0, 255);">var</span> praid = <span style="color: rgb(0, 96, 128);">&quot;AlarmApp&quot;</span>; <span style="color: rgb(0, 128, 0);">// The Application Id value from your package.appxmanifest.</span><br /><br />        <span style="color: rgb(0, 0, 255);">var</span> appName = Windows.ApplicationModel.Package.current.id.familyName + <span style="color: rgb(0, 96, 128);">&quot;!&quot;</span> + praid;<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> launchAppMessage = launchArgs + <span style="color: rgb(0, 96, 128);">&quot;\tWindows\t&quot;</span> + appName;<br /><br />        <span style="color: rgb(0, 0, 255);">var</span> dataWriter = <span style="color: rgb(0, 0, 255);">new</span> Windows.Storage.Streams.DataWriter();<br />        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;<br />        dataWriter.writeString(launchAppMessage);<br />        <span style="color: rgb(0, 0, 255);">var</span> launchAppPubId =<br />             proximityDevice.publishBinaryMessage(<br />                 <span style="color: rgb(0, 96, 128);">&quot;LaunchApp:WriteTag&quot;</span>, <br />                 dataWriter.detachBuffer(), <br />                 proximityWriteTagLaunchAppMessageTransmitCallback);<br />        <br />    <span style="color: rgb(0, 0, 255);">if</span> (launchAppPubId != -1) {<br />            <span style="color: rgb(0, 128, 0);">// Stop publishing the message on NFC radio</span><br />        proximityDevice.stopPublishingMessage(launchAppPubId);<br />    }<br /><br />     }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">function</span> proximityWriteTagLaunchAppMessageTransmitCallback() {<br />    <span style="color: rgb(0, 128, 0);">// Inform the user that: the message has been successfully written to a tag &amp; the tag no longer needs to be in range</span><br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Windows.Networking.Proximity.ProximityDevice proximityDevice;<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">string</span> GetAlarmTime(){<br /><br />    <span style="color: rgb(0, 128, 0);">// Grab time set by the user, call this variable ‘Alarm’</span><br />    <span style="color: rgb(0, 0, 255);">return</span> Alarm;<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> PublishLaunchApp()<br />{<br />    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();<br /><br /><span style="color: rgb(0, 0, 255);">if</span> (proximityDevice != <span style="color: rgb(0, 0, 255);">null</span>)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// The format of the app launch string is: &quot;&lt;args&gt;\tWindows\t&lt;AppName&gt;&quot;.</span><br />        <span style="color: rgb(0, 128, 0);">// The string is tab or null delimited.</span><br /><br />        <span style="color: rgb(0, 128, 0);">// The &lt;args&gt; string can be an empty string (&quot;&quot;).</span><br />        <span style="color: rgb(0, 0, 255);">string</span> launchArgs = getAlarmTime();<br /><br />        <span style="color: rgb(0, 128, 0);">// The format of the AppName is: PackageFamilyName!PRAID.</span><br />        <span style="color: rgb(0, 0, 255);">string</span> praid = <span style="color: rgb(0, 96, 128);">&quot;MyAppId&quot;</span>; <span style="color: rgb(0, 128, 0);">// The Application Id value from your package.appxmanifest.</span><br /><br />        <span style="color: rgb(0, 0, 255);">string</span> appName = Windows.ApplicationModel.Package.Current.Id.FamilyName + <span style="color: rgb(0, 96, 128);">&quot;!&quot;</span> + praid;<br /><br />        <span style="color: rgb(0, 0, 255);">string</span> launchAppMessage = launchArgs + <span style="color: rgb(0, 96, 128);">&quot;\tWindows\t&quot;</span> + appName;<br /><br />        var dataWriter = <span style="color: rgb(0, 0, 255);">new</span> Windows.Storage.Streams.DataWriter();<br />        dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;<br />        dataWriter.WriteString(launchAppMessage);<br />        var launchAppPubId =<br />        proximityDevice.PublishBinaryMessage(<br />            <span style="color: rgb(0, 96, 128);">&quot;LaunchApp:WriteTag&quot;</span>, dataWriter.DetachBuffer(), <br />            proximityWriteTagLaunchAppMessageTransmitCallback);<br />    <br />    <span style="color: rgb(0, 0, 255);">if</span> (launchAppPubId!= -1)<br />    {<br />        proximityDevice.StopPublishingMessage(launchAppPubId);<br />    <span style="color: rgb(0, 128, 0);">// Stop publishing the message on NFC radio</span><br />    }<br /><br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> proximityWriteTagLaunchAppMessageTransmitCallback(<br />    Windows.Networking.Proximity.ProximityDevice sender,<br />    <span style="color: rgb(0, 0, 255);">long</span> messageId)<br />{<br />        <span style="color: rgb(0, 128, 0);">// Inform the user that: the message has been successfully written to a tag &amp; the tag no longer needs to be in range</span><br />}<br /></pre>
  </div>
</blockquote>

<br />これで Windows ストア アプリから NFC タグに書き込む方法がわかりました。非常にシンプルですね。次は、タグ<b>から</b>アラームを設定するシナリオに移ります。NFC タグからアラームを読み取る流れを順番に見ていきましょう。

<ol>
  <li>ユーザーは、ホーム画面をチェックしたり、メールを書いたり、ゲームで遊んだり、Windows を使ったりしているうちに、月曜日の朝のアラームを設定しなければならないと思い立ちました。そこでユーザーは、"平日のアラーム" というタグを持って PC とタップします。これにより、アラーム アプリの起動を促すトーストが表示されます。ここまでの処理はすべて Windows によって行われるため、アプリでは何もする必要はありません。</li>

  <li>ユーザーが承諾すると、アプリが起動してアラームの確認画面が表示され、午前 7 時という時刻が示されます。ユーザーがトーストを受け入れた後、アプリのアクティブ化の間に、Windows からアプリに起動引数 (上で説明したもの) が渡されます。これはコンテキストに応じた起動と呼ばれ、アプリを起動して特定のページを開くことと同じです。</li>

  <li>ユーザーがアラームを設定します。これは通常のアラームの操作で、NFC は使いません。</li>
</ol>

<p>NFC タグから起動引数を取得するのは非常に簡単です。アプリでは、NFC タグに指定された起動時のコンテキストを適切に処理する必要があります。コンテキストに応じた起動とは、アプリを起動して特定のページを表示することと同じです。この例での起動引数は、午前 7 時というアラーム時刻を指定しています。アプリでは、この情報を使って指定されたアラームを表示します。さらに、アプリが PC にインストールされていない場合に備えて、Windows ストアからアプリをインストールするための案内も表示されます。これは Windows が自動的に処理してくれます。</p>

<p>次のコード スニペットでは、コンテキストに応じた起動を実装する方法を示します。</p>

<p><strong>JavaScript</strong></p>

<blockquote>
  <div>
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">app.onactivated = <span style="color: rgb(0, 0, 255);">function</span> (args) {<br />    <span style="color: rgb(0, 0, 255);">if</span> (args.detail.kind === activation.ActivationKind.launch) {<br />        <span style="color: rgb(0, 0, 255);">if</span> (args.detail.arguments == <span style="color: rgb(0, 96, 128);">&quot;Windows.Networking.Proximity.PeerFinder:StreamSocket&quot;</span>) {<br />            <span style="color: rgb(0, 128, 0);">//do nothing here.</span><br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span> {<br />    <span style="color: rgb(0, 128, 0);">// Use args.detail.arguments to parse out ’07.00’ string, and display to the user</span><br />        }<br /><br />        args.setPromise(WinJS.UI.processAll());<br />    }<br />}<br /></pre>
  </div>
</blockquote>

<div>
  <br /><strong>C#</strong></div>

<blockquote>
  <div id="codeSnippetWrapper">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">async <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> OnLaunched(LaunchActivatedEventArgs args)<br />        {<br />            <span style="color: rgb(0, 0, 255);">if</span> (args.Arguments == <span style="color: rgb(0, 96, 128);">&quot;Windows.Networking.Proximity.PeerFinder:StreamSocket&quot;</span>)<br />            {<br />                _isLaunchedByTap = <span style="color: rgb(0, 0, 255);">true</span>;<br />            }<br />            <span style="color: rgb(0, 0, 255);">else</span><br />            {<br /><span style="color: rgb(0, 128, 0);">// Use args.Arguments to parse out ’07.00’ string, and display to the user</span><br /><br />            }<br />            Window.Current.Activate();<br />        }<br /></pre>
  </div>
</blockquote>

<p>
  <br />NFC タグへの読み書きのサポートに必要な処理はこれだけです。最先端のシナリオにもかかわらず、実にシンプルだと思いませんか。最後に、衛生上の対策についても見ていきましょう。エラー処理です。</p>

<h2>エラー処理</h2>

<p>アプリで発生する可能性のある問題として、いくつかの一般的なエラーがあります。</p>

<ul>
  <li>タップされたタグが NDEF 形式でない。Windows 8 では、タグを自動的に NDEF 形式に変換する機能はサポートされていないため、NDEF フォーマッタをダウンロードしてインストールする必要があります。</li>

  <li>タップされたタグが読み取り専用である。NFC タグによっては、読み取り専用としてロックされている場合があります (昔の <a href="http://ja.wikipedia.org/wiki/VHS" target="_blank">VHS テープ</a>に似ています)。</li>

  <li>タップされたタグが小さすぎて、データ全体を保持できない。</li>

  <li>ユーザーの PC に NFC が搭載されていない。最初に触れたように、NFC は新しく発展しつつあるテクノロジであり、広く普及が進むのはこれからと言えます。PC で近接通信がサポートされているかどうかを確認するには、ProximityDevice.getDefault() メソッドを使用します。NFC 通信機能が搭載されていない場合、このメソッドは NULL を返します。</li>
</ul>

<h2>楽しく直感的</h2>

<p>いよいよ NFC が登場し、一般コンシューマーが利用できる環境が整ってきました。Windows は NFC 対応のエコシステムであり、よく設計されたエンド ツー エンドのユーザー エクスペリエンスを提供します。このテクノロジには、アプリやデバイス エクスペリエンスをこれまでにないほどインタラクティブにできる大きな可能性があります。NFC で実現される操作は、楽しくて直感的です。</p>

<p>NFC の応用分野は多岐にわたります。このブログでは、開発者から見た Windows 8 の NFC に関して、役立つ情報を他にも取り上げていく予定です。今後の記事にご注目ください。</p>

<p>NFC と近接通信の詳細については、以下のリソースを参照してください。</p>

<h2>リソース</h2>

<div align="center">
  <table class="b8table" cellspacing="0" cellpadding="3" width="298" align="center" border="0"><tbody>
      <tr>
        <td valign="top" width="197">
          <p><strong>リンク</strong></p>
        </td>

        <td valign="top" width="99">
          <p><strong>種類</strong></p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><u><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465215.aspx" target="_blank">近接通信を使った開発のガイドライン</a></u></p>
        </td>

        <td valign="top" width="99">
          <p>ドキュメント</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br241250.aspx" target="_blank">Proximity API</a></p>
        </td>

        <td valign="top" width="99">
          <p>ドキュメント</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh967765.aspx" target="_blank">近接通信アプリのテストとトラブルシューティング</a></p>
        </td>

        <td valign="top" width="99">
          <p>ドキュメント</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465223.aspx" target="_blank">発行と受信登録 (詳細)</a></p>
        </td>

        <td valign="top" width="99">
          <p>ドキュメント</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Proximity-Sample-88129731" target="_blank">近接通信アプリのサンプル</a> (英語)</p>
        </td>

        <td valign="top" width="99">
          <p>サンプル</p>
        </td>
      </tr>

      <tr>
        <td valign="top" width="197">
          <p align="left"><a href="http://social.msdn.microsoft.com/Forums/ja-jp/category/windowsapps" target="_blank">近接通信に関する質問の投稿先</a> (英語)</p>
        </td>

        <td valign="top" width="99">
          <p>フォーラム</p>
        </td>
      </tr>
    </tbody></table>
</div>

<p>お読みいただき、ありがとうございました。</p>

<p>Priya Dandawate
  <br />Devices and Networking プログラム マネージャー</p>

<p>協力: Max Morris、Marzena Makuta、Mike Loholt、Jake Sabulsky、Vishal Mhatre</p>

<!-- Title: “NFC を使った最先端のアプリの開発” Tags: “共有, NFC, 近距離無線通信, ファイルの共有, Bluetooth ペアリング, データの共有” --></div>]]></content:encoded>
    </item>
    <item>
      <title>接続された Windows ストア アプリの作成</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/windows</link>
      <pubDate>Fri, 19 Apr 2013 10:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/04/19/windows/</guid>
      <description><![CDATA[私たちの周囲には、ネットワークに接続されたデバイスがあふれています。冷蔵庫や洗濯機でさえ、最近ではインターネットやホーム...]]></description>
      <content:encoded><![CDATA[<div class="postcontent">
<p>私たちの周囲には、ネットワークに接続されたデバイスがあふれています。冷蔵庫や洗濯機でさえ、最近ではインターネットやホーム ネットワークに接続できるのです。ですから、アプリも同じようにネットワークに接続したいとエンド ユーザーが考えても不思議はありません。これらの "接続アプリ" は、Web 上の最新コンテンツ (ソーシャル メディア、デジタル メディア、ブログなど、さまざまな種類のコンテンツ) を利用します。接続アプリの開発は標準になりつつありますが、ネットワークの切断、従量制課金接続のコスト、パフォーマンスなどの一般的な問題への対応が課題として残っています。Windows 8 では、接続アプリを今までにないほど簡単に開発できます。</p>
<p>この記事では、Windows ストア アプリのユーザーに、高速かつ滑らかで手間のかからない接続エクスペリエンスを提供するための有効なヒントについてご説明します。</p>
<ul>
<li>シナリオに合った API を選ぶ</li>
<li>適切なネットワーク機能を選ぶ</li>
<li>アプリの動作を従量制課金接続に対応させる</li>
<li>ネットワークの状態の変化に対応する</li>
<li>コンテンツをキャッシュして滑らかな動作を実現する</li>
</ul>
<p>では、それぞれのヒントについて詳しく説明していきましょう。</p>
<h2>適切な API を選ぶ</h2>
<p>家を建てようとする場合、適切な道具が必要ですね。釘を打つなら金づち、板を切るならのこぎり、ネジを締めるならドライバーがそれぞれ必要です。同様に、ネットワークに接続される Windows ストア アプリを開発する場合にも、適切な Networking API を使用する必要があります。Windows 8 には、アプリがインターネットとプライベート ネットワークのどちらを介して他のコンピューターやデバイスと通信する場合にも使用できる、さまざまな Networking API が用意されています。したがって、最初のステップは、開発するアプリに必要なネットワーク機能を把握することです。</p>
<p>ネットワークにおける最も一般的なシナリオは、Web サイトにアクセスして情報を取得または保存することです。簡単な例として、Web サイトを使用してユーザー情報やスコアを保存するゲームがあります。もう少し複雑な例としては、REST ベースの Web サービスに接続し、その Web サービスが提供するライブラリを使用して情報へのアクセスや保存を行うアプリがあります。Windows 8 には、Web サービスや Web サイトに接続する API がいくつかあります。アプリでこれらの API を使用すると、REST をサポートする Web サービスにアクセスしたり、Web サーバーに基本的な HTTP プロトコルのコマンド (GET や POST など) を送信することができます。Web アクセスの場合、必要な API はアプリの開発に使用する言語によって変わります。</p>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh453379.aspx" target="_blank">XMLHTTPRequest</a> (英語) および <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229787.aspx" target="_blank">WinJS.xhr</a> (英語) - JavaScript および HTML で作成したアプリ。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/system.net.http.httpclient.aspx" target="_blank">HttpClient</a> (機械翻訳) - C# または Visual Basic .NET と XAML で作成したアプリ。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh831163.aspx" target="_blank">XML HTTP Request 2</a> (IXHR2) (英語) - C++ および XAML で作成したアプリ。</li>
</ul>
<p>以下のコードは、REST ベースの Web サービスを使用して基本的な要求と応答を実行する方法を示しています。この場合、Web サービスは Web サーバー上で ASP.NET スクリプトを実行する可能性があります。</p>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">function</span> makeXHRCall() {<br />    WinJS.xhr({ uri: <span style="color: #006080;">"http://www.microsoft.com/en-us/default.aspx&rdquo; }).done(<br /> function onComplete(result) {<br /> print(result.responseText);<br /> },<br /> function onError(err) {<br /> print("</span>Error: " + err.responseText);<br />        });<br />}</pre>
</div>
</blockquote>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">private</span> async <span style="color: #0000ff;">void</span> MakeHttpCall()<br />{<br />    HttpClient httpClient = <span style="color: #0000ff;">new</span> HttpClient();<br />    <span style="color: #0000ff;">try</span> {<br />        <span style="color: #0000ff;">string</span> response = await httpClient.GetStringAsync(<span style="color: #006080;">"http://www.microsoft.com/en-us/default.aspx"</span>);<br />    }<br />    <span style="color: #0000ff;">catch</span> (Exception) {<br />        <span style="color: #008000;">// Handle exception.</span><br />    }<br />}</pre>
</div>
</blockquote>
<p><strong>WinJS.xhr</strong> の詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh761502.aspx" target="_blank">Web サービスへの接続 (JavaScript と HTML を使った Windows ストア アプリ)</a>」を参照してください。<strong>HttpClient</strong> の詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/xaml/hh781239.aspx" target="_blank">クイックスタート: HttpClient を使用した接続 (C#/VB/C++ と XAML を使った Windows ストア アプリ)</a>」および「<a href="http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664" target="_blank">HttpClient のサンプル</a>」(英語) を参照してください。</p>
<p>ネットワークにおけるもう 1 つの一般的なシナリオは、ファイル転送に時間がかかる場合のファイルのダウンロードやアップロードです。例として、写真やフォト アルバムの Web サービスへのアップロードや、Web サービスからのダウンロードを行うカメラやフォト ギャラリーのアプリがあります。これらの転送には時間がかかりますが、転送が終わるまでユーザーを待たせることはありません。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">Windows.Networking.BackgroundTransfer</a> API は、アプリが実行されていなくてもファイルのダウンロードやアップロードを行う機能を備えています。アプリがフォアグラウンドで実行されていてフォーカスがある状態のときに転送を開始すると、その後アプリが終了しても、Windows 8 がバックグラウンドで転送を続けます。</p>
<p>もっと特殊なシナリオとして、シンジケート コンテンツへのアクセスがあります。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.web.syndication.aspx" target="_blank">Windows.Web.Syndication</a> API は、RSS 形式または Atom 形式でフィードを取得できます。さらに、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.web.atompub.aspx" target="_blank">Windows.Web.AtomPub</a> API により、アプリはさまざまな AtomPub 形式でデータを公開できます。</p>
<p>API を介して特定のより高度なネットワーク プロトコルを利用することができないシナリオでは、Windows ランタイムが TCP ソケットと UDP ソケットも (マルチキャストと共に) サポートします。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.sockets.aspx" target="_blank">Windows.Networking.Sockets</a> API は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.sockets.streamsocket.aspx" target="_blank">StreamSocket</a> (TCP) および <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.sockets.datagramsocket.aspx" target="_blank">DatagramSocket</a> (UDP) を提供して、より上位のレイヤーにある他のプロトコルを実装できるようにします。</p>
<p><strong>注: </strong>Windows 8 には、WebSocket という新しい種類のソケットが用意されています。<em></em>WebSocket および WebSocket を使用するタイミングの詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh761442.aspx" target="_blank">WebSocket を使った接続</a>」を参照してください。</p>
<p>次の表に、サポートされるネットワーク機能の詳細と、追加情報へのリンクを示します。</p>
<div align="center">&nbsp;
<table class="b8table" border="0" cellspacing="0" cellpadding="3" align="center">
<tbody>
<tr>
<td valign="top" width="217">
<p align="center"><strong>API</strong><strong></strong></p>
</td>
<td valign="top" width="221">
<p align="center"><strong>機能</strong><strong></strong></p>
</td>
<td valign="top" width="145">
<p align="center"><strong>例</strong><strong></strong></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.web.syndication.aspx" target="_blank">Windows.Web.Syndication</a></strong><strong></strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.web.atompub.aspx" target="_blank">Windows.Web.AtomPub</a></strong><strong></strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">複数のバージョンの RSS 形式または Atom 形式でフィードを取得します。これらの API により、OData などの新しい形式のサポートを簡単に実装できます。Windows ランタイムは Atom 公開プロトコルもサポートしているので、Atom コレクションを公開することができます。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh452973.aspx/" target="_blank">概要コンテンツへのアクセスと管理</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Syndication-sample-07ef6b0d" target="_blank">Syndication のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/AtomPub-sample-c1fcdc8e" target="_blank">AtomPub のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">RSS リーダー</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">Windows.Networking.BackgroundTransfer</a></strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">呼び出し元のアプリがフォアグラウンドにない場合でも、持続的、コスト認識可能、再開可能な方法で、コンテンツのダウンロードとアップロードを実行します。この API は、HTTP、HTTPS、FTP の各プロトコルを使用したコンテンツ転送をサポートします。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh452979.aspx" target="_blank">バックグラウンドでのデータの転送</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Background-Transfer-Sample-d7833f61" target="_blank">バックグラウンド転送のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">SkyDrive</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">Xbox ビデオ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh453379.aspx" target="_blank">XMLHTTPRequest</a></strong><strong> (英語) (JavaScript)</strong><strong></strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br229787.aspx" target="_blank">WinJS.xhr</a></strong><strong> </strong><strong>(英語) (JavaScript)</strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/system.net.http.httpclient.aspx" target="_blank">HttpClient</a></strong><strong> </strong><strong>(英語) (C#)</strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh831163.aspx">XML HTTP Request 2</a></strong><strong> (IXHR2)</strong><strong></strong><strong> (英語) (C++)</strong><strong></strong></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">REST ベースの Web サービスと他の HTTP ベースのプロトコルを操作します。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh761502.aspx" target="_blank">Web サービスへの接続</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/XHR-handling-navigation-50d03a7a" target="_blank">XHR、ナビゲーション エラーの処理、および URL スキームのサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664" target="_blank">HttpClient のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">Bing マップ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.proximity.aspx" target="_blank">Windows.Networking.Proximity</a></strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">アプリがソケット API を使用して 2 つのデバイス間のネットワーク通信をトリガーした後、そのデバイス間の近接通信を検出します。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465229.aspx" target="_blank">近接通信とタップのサポート</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Proximity-Sample-88129731" target="_blank">近接通信のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">ゲーム</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">共用アプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left"><strong><a href="http://msdn.microsoft.com/library/windows/apps/BR207928" target="_blank">Windows.Storage.Pickers</a></strong><strong></strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">リモート ファイル共有と通信します。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh464959.aspx" target="_blank">データとファイルへのアクセス</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/File-picker-sample-9f294cba" target="_blank">ファイル ピッカーのサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">Xbox Music</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">フォト</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left"><strong><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.sockets.aspx" target="_blank">Windows.Networking.Sockets</a></strong><strong></strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">これまでに説明した API でサポートされていないプロトコル (SMTP、MAPI、telnet など) を使用するサービス、または同じローカル ネットワーク上にある別のデバイスに接続します。また、Web (HTTP プロキシを含む) を介して新しいサービスに接続するためにソケットのようなセマンティクス (非同期、双方向) を必要とするアプリにも使用されます。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh452977.aspx" target="_blank">ソケットを使った接続</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/StreamSocket-Sample-8c573931" target="_blank">StreamSocket のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/DatagramSocket-sample-76a7d82b" target="_blank">DatagramSocket のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/Connecting-with-WebSockets-643b10ab" target="_blank">WebSocket を使った接続のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left"><a href="http://code.msdn.microsoft.com/windowsapps/site/search?query=controlchanneltrigger&amp;f%5B0%5D.Value=controlchanneltrigger&amp;f%5B0%5D.Type=SearchText&amp;ac=3" target="_blank">ControlChannelTrigger のサンプル</a> (英語)</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">Lync、共有型ホワイトボード、またはストック ピッカー</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p align="left">&nbsp;</p>
<p align="left"><strong><a href="http://msdn.microsoft.com/library/windows/apps/BR241587" target="_blank">Windows.Storage.ApplicationData</a></strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="221">
<p align="left">&nbsp;</p>
<p align="left">Windows 8 では、一部のアプリケーション データがユーザー デバイス間で自動的に移行されます。アプリケーション データのローミングは、アプリのユーザーが複数のデバイスを活用している場合 (職場では PC、自宅ではタブレットを使用して、複数のデバイスに同じアプリをインストールしている場合など) に役立ちます。 <br />詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh465094.aspx" target="_blank">アプリケーション データのローミングのガイドライン</a>」を参照してください。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="145">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<li>
<div align="left"><a href="http://go.microsoft.com/fwlink/p/?linkid=231478" target="_blank">アプリケーション データのサンプル</a> (英語)</div>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<h2>適切なネットワーク機能を選ぶ</h2>
<p>ネットワークの分離は、Windows 8 で使用されるアプリ セキュリティ モデルの一部です。Windows は、積極的にネットワーク境界を発見し、ネットワーク アクセスを制限してネットワークの分離を適用します。これらの機能を適切に展開すると、ユーザーやアプリを悪意のある攻撃から守ることができます。</p>
<p>アプリでネットワークの分離の機能を宣言して、ネットワーク アクセスの範囲を定義する必要があります。これらの機能を宣言しないと、アプリはネットワーク リソースにアクセスできません。Windows でネットワークの分離をアプリに適用する方法の詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/Hh770532.aspx" target="_blank">ネットワーク機能を設定する方法</a>」を参照してください。</p>
<p>同一デバイス上の Windows ストア アプリとデスクトップ アプリ間のプロセス間通信メカニズムとしてネットワークを使用することはできません。したがって、Windows ストア アプリで IP ループバック アドレスは使用できません。開発目的の限定的な例外として、Visual Studio デバッガーで操作するときは IP ループバック アドレスの使用が許可されます。詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/Hh780593.aspx" target="_blank">ループバックを有効にする方法とネットワーク分離のトラブルシューティングを行う方法</a>」を参照してください。</p>
<p>ネットワークへのアクセス要求は、2 つのカテゴリに分けられます。</p>
<ol>
<li><strong>クライアントによる発信要求</strong>: アプリはクライアントとして機能し、最初のネットワーク要求をリモート コンピューター (通常はサーバー) に送信することでネットワーク アクセスを開始します。アプリは 1 つ以上の要求をサーバーに送信し、サーバーは 1 つ以上の応答を返します。たとえば、Web クライアント アプリから Web サーバーへのすべてのトラフィックは、このカテゴリに入ります。</li>
<li><strong>未承諾の着信要求</strong>: アプリはネットワーク サーバーとして機能し、リモート コンピューターからの着信ネットワーク要求をリッスンします。リモート コンピューターは、サーバーとして機能しているアプリに最初の要求を送信することで、ネットワーク アクセスを開始します。リモート コンピューターは 1 つ以上の要求をアプリに送信し、アプリは 1 つ以上の応答をリモート コンピューターに返します。たとえば、メディア サーバーとして機能するアプリがこのカテゴリに入ります。</li>
</ol>
<p>最小権限の原則に従い、アプリが必要とする機能のみを追加します。クライアントによる発信要求のみが必要なアプリもあれば、未承諾の着信要求も受け取る必要があるアプリもあります。アプリによっては、ネットワークを介して認証を行う際に、ユーザーの資格情報や証明書へのアクセスが必要になるものもあります。</p>
<p>次の表に、接続アプリで必要とされることが多いネットワークの分離機能とその他の関連機能を詳しく示します。最初の 3 つは、接続アプリが使用する主要なネットワークの分離機能です。実際、接続アプリでは、これらの 3 つの機能のうち少なくとも 1 つを有効にする必要があります。表内の他のエントリは、一部の接続アプリでよく必要とされる追加機能です。</p>
<p>&nbsp;</p>
<div align="center">
<table class="b8table" style="width: 612px;" border="0" cellspacing="0" cellpadding="3" align="center">
<tbody>
<tr>
<td valign="top" width="146">
<p><strong>ネットワーク機能</strong></p>
</td>
<td valign="top" width="273">
<p><strong>説明</strong></p>
</td>
<td valign="top" width="191">
<p><strong>アプリの例</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">インターネット (クライアント)</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">インターネットや公共の場所 (空港や喫茶店など) のネットワークへの発信アクセスを提供します。インターネット アクセスを必要とするほとんどのアプリは、この機能を宣言する必要があります。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">RSS リーダー</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">ソーシャル ネットワーク</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">ゲーム</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">&nbsp;</p>
<p align="left">インターネット (クライアントおよびサーバー)</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">インターネットや公共の場所 (空港や喫茶店など) のネットワークへの着信アクセスと発信アクセスの両方を提供します。クリティカル ポートへの着信アクセスは常にブロックされます。この機能は、インターネット (クライアント) 機能のスーパーセットであるため、両方を宣言する必要はありません。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">P2P アプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">マルチキャストを使ってプレイヤーを見つけるマルチプレイヤー ゲーム</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">&nbsp;</p>
<p align="left">プライベート ネットワーク (クライアントおよびサーバー)</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">ユーザーによって信頼済みのプライベートな場所で、着信および発信のネットワーク アクセスを提供します。これらは通常、自宅や職場のネットワークです。クリティカル ポートへの着信アクセスは常にブロックされます。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">ネットワーク接続ストレージ (NAS) のコンテンツにアクセスするアプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">基幹業務アプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">プライベートな (自宅または職場の) ネットワーク上で、マルチキャストを使ってプレイヤーを見つけるマルチプレイヤー ゲーム</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">&nbsp;</p>
<p align="left">近接通信</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">デバイスとの近接通信に必要です。招待の送信または承認に対するユーザーの承諾を得て、アプリが近接通信でデバイスに接続してネットワークにアクセスすることを許可します。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">近接通信のユーザーとのマルチプレイヤー ゲーム<em></em></div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">&nbsp;</p>
<p align="left">エンタープライズ認証</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">ドメイン資格情報が必要な企業イントラネット リソースに接続する機能を提供します。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">基幹業務アプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="146">
<p align="left">&nbsp;</p>
<p align="left">共有ユーザー証明書</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="273">
<p align="left">&nbsp;</p>
<p align="left">ユーザーの ID を検証するために、スマート カード証明書などのソフトウェアとハードウェアの証明書にアクセスする機能を提供します。関連 API が実行時に呼び出されたときは、ユーザーはアクション (カードの挿入や証明書の選択など) を行う必要があります。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="191">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">仮想プライベート ネットワーク アプリ</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<li>
<div align="left">基幹業務アプリ</div>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<p>このチェック リストを使用して、アプリ内でネットワークの分離が構成されていることを確認します。</p>
<ul>
<li>アプリが必要とするネットワーク アクセスの方向 (クライアントによる発信要求、未承諾の着信要求、その両方) を確認します。</li>
<li>アプリが通信するネットワーク リソースの種類 (自宅または職場のネットワーク上の信頼済みのリソース、インターネット上のリソース、その両方) を確認します。</li>
<li>最低限必要なネットワークの分離機能をアプリ マニフェストで構成します。そのためには、Microsoft Visual Studio 2012 の<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br230259.aspx" target="_blank">アプリ マニフェスト デザイナー</a>を使用するか、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br211477.aspx" target="_blank">手動で追加</a> (英語) します。</li>
<li>アプリを展開して実行し、トラブルシューティング用に提供されているネットワークの分離ツールを使用してテストします。詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/Hh780593.aspx" target="_blank">ループバックを有効にする方法とネットワーク分離のトラブルシューティングを行う方法</a>」を参照してください。</li>
</ul>
<p>次のスクリーン ショットは、Microsoft Visual Studio 2012 の<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/br230259.aspx" target="_blank">アプリ マニフェスト デザイナー</a>を使用してネットワーク機能を有効にする方法を示しています。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7268.app-manifest-design_47107BBF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7268.app_2D00_manifest_2D00_design_5F00_47107BBF.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Visual Studio 2012 でアプリの package.appxmanifest を使ってネットワーク機能を選択する" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/7752.app-manifest-design_thumb_5EC7B325.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/7752.app_2D00_manifest_2D00_design_5F00_thumb_5F00_5EC7B325.png" alt="Visual Studio 2012 でアプリの package.appxmanifest を使ってネットワーク機能を選択する" width="600" height="318" border="0" /></a></p>
<p align="center">Visual Studio 2012 でアプリの package.appxmanifest を使ってネットワーク機能を選択する<em></em></p>
<h2>アプリの動作を従量制課金接続に対応させる</h2>
<p>データ通信量が毎月の上限値に近づいた場合や、海外旅行に出かける場合を考えてみてください。このような場合、通常は大事をとってデバイスとアプリの使用を中止し、不要なネットワーク使用料が発生しないようにします。</p>
<p>Windows 8 では、アプリが利用可能なネットワーク リソースを監視し、従量制課金接続の場合はそれに応じた動作をさせることで、この問題を解決します。ユーザーのアプリへの信頼度を高めるため、接続によって費用が発生する場合にはそのことを通知し、費用を抑えるようにアプリを動作させることができます。</p>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.aspx" target="_blank">Windows.Networking.Connectivity</a> API は、ネットワーク接続の種類と費用に関する情報を提供します。これにより、ネットワーク リソースを普通に使ってよい場合、控えめに使ったほうがよい場合、ユーザーに問い合わせる場合をアプリが判断できます。</p>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectionprofile.aspx" target="_blank">ConnectionProfile</a> は、ネットワーク接続を表します。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectionprofile.aspx" target="_blank">ConnectionProfile</a> の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> を使用して、アプリの動作を対応させるかどうかを判断することができます。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> プロパティは、ネットワーク接続の種類を示します。有効な値は次の 4 つです。</p>
<ul>
<li><strong>Unrestricted</strong> - このネットワーク接続の使用は無制限です。使用料や容量の制約はありません。</li>
<li><strong>Fixed</strong> - このネットワーク接続の使用は、一定の限度までは無制限です。</li>
<li><strong>Variable</strong> - このネットワーク接続の使用は、バイト ベースの従量制です。</li>
<li><strong>Unknown</strong> - このネットワーク接続に関するコスト情報を使用できません。</li>
</ul>
<p>他にも <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> のブール型プロパティがいくつかあり、より詳細な情報を提供します。</p>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.roaming.aspx" target="_blank">Roaming</a> - ホーム プロバイダーの外側のネットワークに接続されているかどうかを示します。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.approachingdatalimit.aspx" target="_blank">ApproachingDataLimit</a> - 接続がデータ プランで指定されたデータ使用量の上限に近づいているかどうかを示します。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.overdatalimit.aspx" target="_blank">OverDataLimit</a> - 接続がデータ プランで指定されたデータ使用量の上限を超えているかどうかを示します。</li>
</ul>
<p>これらのプロパティで示された状況にアプリを対応させます。接続が <strong>Roaming</strong> であれば、ネットワーク使用に関連するデータ コストは高くなる可能性があります。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Variable</strong> の場合、ネットワークは従量制課金接続で、ユーザーはネットワーク上で送受信したデータ量に基づいて料金を支払います。<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Fixed</strong> の場合、ユーザーが既にデータ量の上限に近づいているか、または上限を超えているかどうかが心配の種になります。</p>
<p>この情報を使用することにより、アプリはこれらのガイドラインに従って最適なネットワーク リソースの使用方法を決定できます。</p>
<div align="center">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<table class="b8table" border="0" cellspacing="0" cellpadding="3" align="center">
<tbody>
<tr>
<td valign="top" width="97">
<p><strong>動作</strong></p>
</td>
<td valign="top" width="150">
<p><strong>接続コスト</strong></p>
</td>
<td valign="top" width="168">
<p><strong>アプリのガイドライン</strong></p>
</td>
<td valign="top" width="175">
<p><strong>例</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="97">
<p align="left">標準</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="150">
<p align="left">&nbsp;</p>
<p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Unrestricted</strong> または <strong>Unknown</strong> で、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> が <strong>Roaming</strong> 以外</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="168">
<p align="left">&nbsp;</p>
<p align="left">アプリは制限を実装しません。アプリは接続のコストを<strong>無制限</strong>として扱い、使用料や容量の制約はありません。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="175">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">メディア プレーヤー アプリは、HD ムービー全体を再生できます。</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">アプリが大きなファイルをダウンロードする際に制限はなく、メッセージも表示されません。</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="97">
<p align="left">&nbsp;</p>
<p align="left">控えめ</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="150">
<p align="left">&nbsp;</p>
<p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Fixed</strong> または <strong>Variable</strong> で、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> は <strong>Roaming</strong> でも <strong>OverDataLimit</strong> でもない</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="168">
<p align="left">&nbsp;</p>
<p align="left">アプリは、従量制課金接続での操作を処理するために制限を実装して、ネットワーク使用量を最適化します。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="175">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">メディア プレーヤー アプリは、ムービーを低解像度で再生できます。</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">アプリは、クリティカルでないダウンロードを遅延させることができます。</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
</td>
</tr>
<tr>
<td valign="top" width="97">
<p align="left">&nbsp;</p>
<p align="left">承認</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="150">
<p align="left">&nbsp;</p>
<p align="left"><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.aspx" target="_blank">ConnectionCost</a> は <strong>Roaming</strong> または <strong>OverDataLimit</strong></p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="168">
<p align="left">&nbsp;</p>
<p align="left">ネットワーク アクセス コストが計画したコストより大幅に高くなる場合、アプリは例外処理を行います。</p>
<p align="left">&nbsp;</p>
</td>
<td valign="top" width="175">
<p align="left">&nbsp;</p>
<p align="left">&nbsp;</p>
<ul>
<ul>
<li>
<div align="left">アプリは、ネットワークにアクセスするかどうかをユーザーに確認します。</div>
</li>
</ul>
</ul>
<p align="left">&nbsp;</p>
<ul>
<li>
<div align="left">アプリは、バックグラウンドのすべてのデータ ネットワーク アクティビティを中断します。<em></em></div>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<p>以下のサンプル コードは、接続コストをチェックして、適切なアプリの動作を提案します。</p>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">var</span> CostGuidance = { Normal: 0, Conservative: 1, OptIn: 2 };<br /><span style="color: #008000;">// GetCostGuidance returns an object with a Cost (with value of CostGuidance), </span><br /><span style="color: #008000;">// CostName (a string) and Reason, which says why the cost is what it is.</span><br /><span style="color: #0000ff;">function</span> GetCostGuidance() <br />{<br />    <span style="color: #0000ff;">var</span> connectionCost = Windows.Networking.Connectivity.NetworkInformation.getInternetConnectionProfile().getConnectionCost();<br />    <span style="color: #0000ff;">var</span> networkCostConstants = Windows.Networking.Connectivity.NetworkCostType;<br />    <span style="color: #0000ff;">var</span> Retval = <span style="color: #0000ff;">new</span> Object();<br />    <span style="color: #0000ff;">if</span> (connectionCost.roaming || connectionCost.overDataLimit)<br />    {<br />        Retval.Cost = CostGuidance.OptIn;<br />        Retval.CostName = <span style="color: #006080;">"OptIn"</span>;<br />        Retval.Reason = connectionCost.roaming<br />            ? <span style="color: #006080;">"Connection is roaming; using the connection may result in additional charge."</span><br />            : <span style="color: #006080;">"Connection has exceeded the usage cap limit."</span>;<br />    }<br />    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (connectionCost.networkCostType == networkCostConstants.<span style="color: #0000ff;">fixed</span><br />        || connectionCost.networkCostType == networkCostConstants.variable)<br />    {<br />        Retval.Cost = CostGuidance.conservative;<br />        Retval.CostName = <span style="color: #006080;">"Conservative"</span>;<br />        Retval.Reason = connectionCost.networkCostType == NetworkCostType.<span style="color: #0000ff;">fixed</span><br />            ? <span style="color: #006080;">"Connection has limited allowed usage."</span><br />            : <span style="color: #006080;">"Connection is charged based on usage. "</span>;<br />    }<br />    <span style="color: #0000ff;">else</span><br />    {<br />        Retval.Cost = CostGuidance.Normal;<br />        Retval.CostName = <span style="color: #006080;">"Normal"</span>;<br />        Retval.Reason = connectionCost.networkCostType == networkCostConstants.unknown<br />            ? <span style="color: #006080;">"Connection is unknown."</span><br />            : <span style="color: #006080;">"Connection cost is unrestricted."</span>;<br />    }<br /><br />    <span style="color: #0000ff;">return</span> Retval;<br />}</pre>
</div>
</blockquote>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">enum</span> NetworkCost { Normal, Conservative, OptIn };<br /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> CostGuidance<br />{<br />    <span style="color: #0000ff;">public</span> CostGuidance()<br />    {<br />        var connectionCost = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();<br />        Init(connectionCost);<br />    }<br />    <span style="color: #0000ff;">public</span> NetworkCost Cost { get; <span style="color: #0000ff;">private</span> set; }<br />    <span style="color: #0000ff;">public</span> String Reason { get; <span style="color: #0000ff;">private</span> set; }<br /><br /><br />    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Init(ConnectionCost connectionCost)<br />    {<br />        <span style="color: #0000ff;">if</span> (connectionCost == <span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">return</span>;<br />        <span style="color: #0000ff;">if</span> (connectionCost.Roaming || connectionCost.OverDataLimit)<br />        {<br />            Cost = NetworkCost.OptIn;<br />            Reason = connectionCost.Roaming<br />                ? <span style="color: #006080;">"Connection is roaming; using the connection may result in additional charge."</span><br />                : <span style="color: #006080;">"Connection has exceeded the usage cap limit."</span>;<br />        }<br />        <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (connectionCost.NetworkCostType == NetworkCostType.Fixed<br />            || connectionCost.NetworkCostType == NetworkCostType.Variable)<br />        {<br />            Cost = NetworkCost.Conservative;<br />            Reason = connectionCost.NetworkCostType == NetworkCostType.Fixed<br />                ? <span style="color: #006080;">"Connection has limited allowed usage."</span><br />                : <span style="color: #006080;">"Connection is charged based on usage. "</span>;<br />        }<br />        <span style="color: #0000ff;">else</span><br />        {<br />            Cost = NetworkCost.Normal;<br />            Reason = connectionCost.NetworkCostType == NetworkCostType.Unknown<br />                ? <span style="color: #006080;">"Connection is unknown."</span><br />                : <span style="color: #006080;">"Connection cost is unrestricted."</span>;<br />        }<br />    }<br />}</pre>
</div>
</blockquote>
<p>アプリ動作の従量制課金接続への対応の詳細については、<a href="http://code.msdn.microsoft.com/windowsapps/Network-Information-Sample-63aaa201" target="_blank">ネットワーク情報のサンプル</a> (英語) を参照してください。</p>
<p>タスク マネージャーを実行して、各アプリが使用しているネットワーク データの量を確認することもできます。次のスクリーン ショットにその例を示します。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/5618.task-manager_6C99F920.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/5618.task_2D00_manager_5F00_6C99F920.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="タスク マネージャーの [アプリの履歴] タブでアプリごとの CPU とネットワークの使用量を確認" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/51/31/metablogapi/3554.task-manager_thumb_4C7EEC63.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3554.task_2D00_manager_5F00_thumb_5F00_4C7EEC63.png" alt="タスク マネージャーの [アプリの履歴] タブでアプリごとの CPU とネットワークの使用量を確認" width="600" height="545" border="0" /></a></p>
<p align="center">タスク マネージャーの [アプリの履歴] タブでアプリごとの CPU とネットワークの使用量を確認<em></em></p>
<h2>ネットワークの状態の変化に対応する</h2>
<p>モバイル デバイスの使用中に、ネットワークの状態が変化することがあります。ユーザーの自宅やガレージなどで、3G または 4G のモバイル ブロードバンド ネットワークが、Wi-Fi が利用可能であるにもかかわらず圏外になることがあります。同様に、ユーザーが自宅を離れると Wi-Fi が圏外になることもあります。こうした場合、ネットワークが使用できなくなる可能性があります。Wi-Fi やモバイル ブロードバンド ネットワークの普及に伴い、このようなネットワークの状態の変化が頻繁に発生します。</p>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a> イベントは、利用可能コストや接続オプションが変化したことを示します。<em></em><em></em>ネットワークの状態の変化に対応し、変化が起こった場合でもシームレスなエクスペリエンスを提供するために、接続アプリは以下のシナリオのガイドラインに従います。</p>
<h3>エラーによる切断</h3>
<p>ほとんどの場合、ネットワーク操作を再試行するだけで、改めて接続を確立できます。うまくいかない場合は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a> イベントを待機します。接続が続けてエラーになる場合は、アプリが再試行に使用するバックオフの間隔を増加させる (50 ミリ秒から始めて、指数関数的にこの間隔を増加させる) ことをお勧めします。</p>
<h3>ネットワークの損失</h3>
<p>接続が切れたことをユーザーに通知し、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a> イベントを登録して待機します。</p>
<h3>新しいネットワークの利用範囲</h3>
<p>デバイスが複数のネットワークに接続している場合もあります。たとえば、ユーザーが家に着く前にモバイル ブロードバンドに接続して Windows 8 のメッセージング アプリで友人とチャットしながら、自宅でも無制限のネットワークに接続する場合があります。Windows 8 の既定のポリシーでは、従量制課金接続よりも無制限のネットワークを優先し、低速のネットワークよりも高速のネットワークを優先します。しかし、アプリによって確立された既存の接続は、新しいネットワークに自動的には切り替わりません。新しいネットワークに切り替えるかどうかの判断ができるのはアプリだけであるため、アプリ自身が関与する必要があります。</p>
<p>たとえば、ビデオ ストリームが終わりかけている場合、新しいネットワークに切り替える意味はあまりありません。しかし、現在のネットワークがパケットを損失していたり、あまりに遅かったり、ストリームの終了までにまだ時間がかかりそうな場合には、新しいネットワークへの切り替えが最良の選択です。</p>
<p>アプリのシナリオにおいてネットワークの切り替えが妥当であると判断した場合は、新しいネットワークの検出時に次のガイドラインに従ってください。</p>
<ol>
<li>既存のネットワークと新しいネットワークのコストを確認します。新しいネットワークへの切り替えに意味がある場合は、新しいネットワーク接続の確立を試行し、前述したガイドラインに基づくネットワーク操作を再試行します。Windows は、(利用可能であれば) 従量制課金接続よりも無制限のネットワーク、低速のネットワークよりも高速のネットワークを自動的に選択します。</li>
<li>新しいネットワーク接続が確立できたら、この新しい接続をアプリで使用し、以前のネットワーク接続がまだ存在している場合は元のネットワーク操作をキャンセルします。</li>
</ol>
<h3>ネットワーク コストの変化</h3>
<p>ネットワーク コストの変化は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Fixed</strong> で、使用量がデータ量の上限に近づいた、または超えた場合に起こる可能性があります。ネットワーク コストの変化は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.networkcosttype.aspx" target="_blank">NetworkCostType</a> が <strong>Variable</strong> になるか、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.connectioncost.roaming.aspx" target="_blank">Roaming</a> が true に変わった場合にも起こる可能性があります。こうした場合には、前のヒントのガイドラインに基づいて、アプリの動作を変化に対応させます。</p>
<p>以下のコード例は、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a> イベントを使用して、さまざまなネットワーク状態の変化に対してアプリのシームレスなエクスペリエンスを提供します。どちらの例でも、registeredNetworkStatusNotification というグローバルなブール型変数を使用します。この変数の初期設定値は <strong>false</strong> です。<em></em></p>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">// Register for NetworkStatusChanged notifications, and display new </span><br /><span style="color: #008000;">// Internet ConnectionProfile info upon network status change.</span><br /><span style="color: #0000ff;">function</span> registerForNetworkStatusChange() {<br />    <span style="color: #0000ff;">try</span> {<br /><br />        <span style="color: #008000;">// Register for network status change notifications.</span><br />        <span style="color: #0000ff;">if</span> (!registeredNetworkStatusNotification) {<br />            <span style="color: #0000ff;">var</span> networkInfo.addEventListener(<span style="color: #006080;">"networkstatuschanged"</span>, onNetworkStatusChange);<br />            registeredNetworkStatusNotification = <span style="color: #0000ff;">true</span>;<br />        }<br />    }<br />    <span style="color: #0000ff;">catch</span> (e) {<br />        print(<span style="color: #006080;">"An unexpected exception occurred: "</span> + e.name + <span style="color: #006080;">": "</span> + e.message);<br />    }<br />}<br /><br /><span style="color: #008000;">// Event handler for NetworkStatusChanged event</span><br /><span style="color: #0000ff;">function</span> onNetworkStatusChange(sender) {<br />    <span style="color: #0000ff;">try</span> {<br />        <span style="color: #008000;">// Get the ConnectionProfile that is currently used to connect </span><br />        <span style="color: #008000;">// to the Internet.</span><br />        <span style="color: #0000ff;">var</span> internetProfile = networkInfo.getInternetConnectionProfile();<br />        <span style="color: #0000ff;">if</span> (internetProfile === <span style="color: #0000ff;">null</span>) {<br />            print(<span style="color: #006080;">"Not connected to Internet\n\r"</span>);<br />        }<br />        <span style="color: #0000ff;">else</span> {<br />            internetProfileInfo += getConnectionProfileInfo(internetProfile) + <span style="color: #006080;">"\n\r"</span>;<br />            print(internetProfileInfo);<br />        }<br />        internetProfileInfo = <span style="color: #006080;">""</span>;<br />    }<br />    <span style="color: #0000ff;">catch</span> (e) {<br />        print(<span style="color: #006080;">"An unexpected exception occurred: "</span> + e.name + <span style="color: #006080;">": "</span> + e.message);<br />    }<br />}</pre>
</div>
</blockquote>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">// Register for NetworkStatusChanged notifications, and display new </span><br /><span style="color: #008000;">// Internet ConnectionProfile info upon network status change.</span><br /><span style="color: #0000ff;">void</span> NetworkStatusChange()<br />{<br />    <span style="color: #008000;">// Register for network status change notifications.</span><br />    <span style="color: #0000ff;">try</span><br />    {<br />        var networkStatusCallback = <span style="color: #0000ff;">new</span> NetworkStatusChangedEventHandler(OnNetworkStatusChange);<br />        <span style="color: #0000ff;">if</span> (!registeredNetworkStatusNotification)<br />        {<br />            NetworkInformation.NetworkStatusChanged += networkStatusCallback;<br />            registeredNetworkStatusNotification = <span style="color: #0000ff;">true</span>;<br />        }<br />    }<br />    <span style="color: #0000ff;">catch</span> (Exception ex)<br />    {<br />        rootPage.NotifyUser(<span style="color: #006080;">"Unexpected exception occurred: "</span> + ex.ToString(), NotifyType.ErrorMessage);<br />    }<br />}<br /><br /><span style="color: #008000;">// Event handler for NetworkStatusChanged event</span><br />async <span style="color: #0000ff;">void</span> OnNetworkStatusChange(<span style="color: #0000ff;">object</span> sender)<br />{<br />    <span style="color: #0000ff;">try</span><br />    {<br />        <span style="color: #008000;">// Get the ConnectionProfile that is currently used to connect </span><br />        <span style="color: #008000;">// to the Internet </span><br />        ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();<br /><br />        <span style="color: #0000ff;">if</span> (InternetConnectionProfile == <span style="color: #0000ff;">null</span>)<br />        {<br />            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =&gt;<br />            {<br />                rootPage.NotifyUser(<span style="color: #006080;">"Not connected to Internet\n"</span>, NotifyType.StatusMessage);<br />            });<br />        }<br />        <span style="color: #0000ff;">else</span><br />        {<br />            connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);<br />            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =&gt;<br />            {<br />                rootPage.NotifyUser(connectionProfileInfo, NotifyType.StatusMessage);<br />            });<br />        }<br />        internetProfileInfo = <span style="color: #006080;">""</span>;<br />    }<br />    <span style="color: #0000ff;">catch</span> (Exception ex)<br />    {<br />        rootPage.NotifyUser(<span style="color: #006080;">"Unexpected exception occurred: "</span> + ex.ToString(), NotifyType.ErrorMessage);<br />    }<br />}</pre>
</div>
</blockquote>
<p><a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.networking.connectivity.networkinformation.networkstatuschanged" target="_blank">NetworkStatusChanged</a> イベントの詳細については、「<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/hh700376.aspx" target="_blank">クイック スタート: 接続イベントと可用性の変更の管理</a>」および「<a href="http://code.msdn.microsoft.com/windowsapps/Network-Information-Sample-63aaa201" target="_blank">ネットワーク情報のサンプル</a>」(英語) を参照してください。</p>
<h2>コンテンツをキャッシュして滑らかな動作を実現する</h2>
<p>コンテンツをディスクにキャッシュすると、アプリが高速かつ滑らかに動作します。たとえば、RSS フィード リーダー アプリは、前回のセッションでディスクにキャッシュされたフィードをすぐに表示できます。最新のフィードが利用可能になると、アプリはコンテンツを更新します。キャッシュすることにより、ユーザーはアプリ起動時にすぐにコンテンツを確認でき、その間にアプリは新しいコンテンツを取得できます。</p>
<p>Windows 8 には、<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.storage.aspx" target="_blank">Windows.Storage</a><strong></strong> 名前空間の <a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.storage.applicationdata.aspx" target="_blank">ApplicationData</a><strong></strong> クラスが用意されています。このクラスは、アプリ データ ストアへのアクセスを提供します。このデータ ストアは、デバイスのローカルなファイルと設定、複数デバイス間のローミング、または一時的なデータで構成されます。</p>
<p>ファイルは、大規模なデータ セット、データベース、または一般的なファイル形式のデータの格納に最適です。ファイルは、Roaming フォルダー、Local フォルダー、Temporary フォルダーのいずれかに格納されます。これらはそれぞれ次のように扱われます。</p>
<ul>
<li>Roaming のファイルは、ユーザーが接続されたアカウントでサインインした複数のコンピューターやデバイスの間で同期されます。ファイルのローミングはすぐには実行されません。複数の要素が評価されて、データ送信のタイミングが決定されます。ローミング データの使用量はクォータ (<a href="http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.storage.applicationdata.roamingstoragequota.aspx" target="_blank">RoamingStorageQuota</a><strong></strong> プロパティによって利用可能) を超えないようにします。クォータを超えると、データのローミングは中断されます。アプリが書き込み中のファイルをローミングすることはできません。したがって、アプリのファイル オブジェクトは、必要なくなったら閉じるようにしてください。</li>
<li>Local のファイルは、コンピューター間で同期されません。これらのファイルは、最初に作成されたコンピューター上にそのまま存在します。</li>
<li>Temporary のファイルは、使用されなくなると削除されます。一時ファイルの削除は、使用可能なディスク容量やファイル作成からの経過日数などの要素を考慮して決定されます。</li>
</ul>
<p>以下のコード例は、コンテンツをディスクにキャッシュします。サーバーの応答をキャッシュすると、強制終了/再起動の後、アプリがすぐにコンテンツを表示することができます。簡潔にするため、これらの例ではアプリ データ ストアへの設定の書き込み方法やローミング イベントへの応答方法は示していません。これらの詳細については、「<a href="http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2" target="_blank">アプリケーション データのサンプル</a>」(英語) を参照してください。</p>
<p><strong>JavaScript</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">var</span> roamingFolder = Windows.Storage.ApplicationData.current.roamingFolder;<br /><span style="color: #0000ff;">var</span> filename = <span style="color: #006080;">"serverResponse.txt"</span>;<br /><br /><span style="color: #0000ff;">function</span> cacheResponse(strResponse) {<br />    roamingFolder.createFileAsync(filename, Windows.Storage.CreationCollisionOption.replaceExisting)<br />        .done(<span style="color: #0000ff;">function</span> (file) {<br />            <span style="color: #0000ff;">return</span> Windows.Storage.FileIO.writeTextAsync(file, strResponse);<br />        });<br />}<br /><br /><span style="color: #0000ff;">function</span> getCachedResponse() {<br />    roamingFolder.getFileAsync(filename)<br />        .then(<span style="color: #0000ff;">function</span> (file) {<br />            <span style="color: #0000ff;">return</span> Windows.Storage.FileIO.readTextAsync(file);<br />        }).done(<span style="color: #0000ff;">function</span> (response) {<br />            print(response);<br />        }, <span style="color: #0000ff;">function</span> () {<br />            <span style="color: #008000;">// getFileAsync or readTextAsync failed. </span><br />            <span style="color: #008000;">// No cached response.</span><br />        });<br />}</pre>
</div>
</blockquote>
<p><strong>C#</strong></p>
<blockquote>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">MainPage rootPage = MainPage.Current;<br />StorageFolder roamingFolder = <span style="color: #0000ff;">null</span>;<br /><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> filename = <span style="color: #006080;">"serverResponse.txt"</span>;<br /><br />async <span style="color: #0000ff;">void</span> cacheResponse(<span style="color: #0000ff;">string</span> strResponse)<br />{<br />    StorageFile file = await roamingFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);<br />    await FileIO.WriteTextAsync(file, strResponse);<br />}<br /><br />async <span style="color: #0000ff;">void</span> getCachedResponse()<br />{<br />    <span style="color: #0000ff;">try</span><br />    {<br />        StorageFile file = await roamingFolder.GetFileAsync(filename);<br />        <span style="color: #0000ff;">string</span> response = await FileIO.ReadTextAsync(file);<br />    }<br />    <span style="color: #0000ff;">catch</span> (Exception)<br />    {<br />        <span style="color: #008000;">// getFileAsync or readTextAsync failed.</span><br />        <span style="color: #008000;">// No cached response.</span><br />    }<br />}</pre>
</div>
</blockquote>
<p>アプリ データ ストアの詳細については、「<a href="http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/07/25/roaming.aspx" target="_blank">アプリ データのローミング</a>」と「<a href="http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2" target="_blank">アプリケーション データのサンプル</a>」(英語) を参照してください。</p>
<h2>まとめ</h2>
<p>Windows ストア アプリを開発する際には、この記事のガイドラインを使用して、手間のかからない優れた接続エクスペリエンスを提供してください。これらのヒントを使用すると、開発プロセスが簡単になるだけではなく、アプリの滑らかさを維持しながらユーザーの信頼度も上げることができます。</p>
<p>- Windows プログラム マネージャー II、Suhail Khalid</p>
<p>協力: Steven Baker、Peter Smith</p>
<!-- Title: “接続された Windows ストア アプリの作成” Tags: “Windows ストア アプリ, HttpClient, 接続アプリ, XMLHTTPRequest, IXHR2, XML HTTP Request 2, WinJS.xhr” --></div>]]></content:encoded>
    </item>
    <item>
      <title>//build/ 2013 の参加登録が開始されました</title>
      <link>https://docs.microsoft.com/archive/blogs/windowsappdev_ja/build-2013</link>
      <pubDate>Fri, 05 Apr 2013 10:32:39 GMT</pubDate>
      <dc:creator><![CDATA[Windows 8 Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/windowsappdev_ja/2013/04/05/build-2013/</guid>
      <description><![CDATA[先週の Steve Guggenheimer による発表のとおり、//build/ 2013 を 2013 年 6 月 26 日～ 28 日にサンフランシスコ Moscone Center...]]></description>
      <content:encoded><![CDATA[<div class="PostContent"><p>先週の Steve Guggenheimer による<a href="http://blogs.technet.com/b/microsoft_blog/archive/2013/03/26/announcing-build-2013.aspx" target="_blank">発表</a>のとおり、//build/ 2013 を 2013 年 6 月 26 日～ 28 日にサンフランシスコ Moscone Center で開催いたします。//build/ は、Windows ストア アプリの開発について詳しく知る絶好の機会です。質の高いプレゼンテーション、デモ、情報セッションにご興味に合わせてご参加ください。また、デモを発表し皆様の質問に答えるため、Microsoft エンジニアリング チームの多くがサンフランシスコに集結する予定です。//build/ 2013 は、Windows ストア アプリ開発に関する最も新しく、最も有意義な情報が得られる場所になるでしょう。</p>  <p>参加登録は本日 4 月 2 日より開始いたします。<sup></sup>すべての詳細情報と登録については、<a href="http://www.buildwindows.com" target="_blank">www.buildwindows.com</a> をご覧ください。</p>  <p>会場でお会いできることを楽しみにしております。</p> <!-- Title: “//build/ 2013 の参加登録が開始されました” Tags: “build” --></div>]]></content:encoded>
    </item>
  </channel>
</rss>