Microsoft サービスをアプリに追加する方法 (HTML)
ここでは、Microsoft サービスの機能を Windows ランタイム アプリに追加して、ユーザーのプロファイル情報、Microsoft OneDrive にあるファイルや写真、Outlook.com 情報にアクセスできるようにする方法について説明します。このチュートリアルでは、まず空のアプリを用意し、ユーザーの Microsoft アカウントにサインインする機能とユーザーのプロファイル情報を取得してアプリに表示する機能を追加します。
重要 このトピックのチュートリアルでは、Windows ストア アプリについて説明します。また、Windows Phone ストア アプリに Microsoft サービスを追加することもできます。ただし、Windows Phone ユーザー インターフェイスではポップアップがサポートされないので、このトピックでポップアップが使われる機能を実装するために Windows Phone ストア アプリ内のページを使う必要があります。
理解しておく必要があること
テクノロジ
必要条件
- Windows 8
- Microsoft Visual Studio
- Live SDK
- Windows ストア開発者アカウント
- アプリ内で使う 2 つの画像ファイル (PNG 形式)
手順
ステップ 1: "空のアプリケーション" プロジェクトを作って Live SDK を含める
次のように、Visual Studio のテンプレートから新しいアプリを作ります。
- Visual Studio で、[ファイル] メニューの [新しいプロジェクト] をクリックします。
- [新しいプロジェクト] ダイアログ ボックスで、[インストール済み]、[テンプレート]、[JavaScript]、[Windows ストア] の順にクリックします。
- [空のアプリケーション] を選びます。
- 新しいアプリの名前と場所を入力し、[OK] をクリックします。
- アプリをビルドしてテストします。アプリが起動し、空白のページが開いて "コンテンツをここに挿入" というテキストのみが表示されます。この表示を確認できたら、アプリを閉じて次に進みます。
ステップ 2: アプリを Windows ストア開発者アカウントに追加する
Live SDK がアクセスするクラウド サービスをアプリが使用できるように、アプリを Windows ストア開発者アカウントに登録する必要があります。認定を受けるためにアプリを Windows ストアに提出する必要はありません。必要な作業は、Windows ストア開発者アカウントでアプリの名前を入力することだけです。
ステップ 3: アプリ データと設定ポップアップを追加する
Live SDK を使う Windows ストア アプリでは、少なくとも次に示す 2 つを行う必要があります。
- ユーザーが自分の Microsoft アカウントにサインインし、可能な場合はサインアウトできるようにする。
- アプリからアクセスする個人データの保護方法を説明したプライバシー ポリシーを表示する。
サインイン/サインアウトのエクスペリエンスとプライバシー ポリシーについて詳しくは、「Microsoft アカウントのサインインの要件」をご覧ください。
Windows ストア アプリでは、設定ポップアップからこれらにアクセスできるようにします。
アプリにポップアップを追加するには、次のようにします。
[Account] ポップアップ ページを作ります。
[Account] ポップアップ用ファイルに使う新しいフォルダーを作ります。ソリューション エクスプローラーで、プロジェクト名を右クリックし、[追加]、[新しいフォルダー] の順にクリックします。
新しいフォルダーの名前を「account」に変更します。
[account] フォルダーを右クリックし、[追加]、[新しい項目] の順にクリックします。
[新しい項目の追加] ダイアログ ボックスで、[インストール済み]、[JavaScript]、[Windows ストア]、[ページ コントロール] の順にクリックします。
[名前] ボックスに「"account.html"」と入力し、[追加] をクリックします。
新しいファイルをアプリ用に変更します。
account.html ファイルで、<div> 要素を次のコードに置き換えます。
<div id="account" data-win-control="WinJS.UI.SettingsFlyout" data-win-options="{width: 'narrow'}"> <div class="SettingsPane"> <div class="win-label"> <button onclick="WinJS.UI.SettingsFlyout.show()" class="win-backbutton"> </button> <span class="SettingsTitle">Account</span> </div> <article class="SettingsContent"> <p id="accountPrompt"></p> </article> <div> <!-- define one button to sign in and another to sign out, but show only --> <!-- one at a time, depending on whether the user is currently signed in or not. --> <button id="signInBtn" onclick="signInCmd()" style="display: none">Sign in</button> <button id="signOutBtn" onclick="signOutCmd()" style="display: none">Sign out</button> </div> </div> </div>
次のコードを account.css ファイルの末尾に追加します。
.account p { margin-left: 120px; } .SettingsPane { margin-top:36px; margin-left:48px; } .SettingsTitle { margin-left: 36px; } .SettingsContent { margin-top: 24px; } #account { background-color: gray ; }
[Privacy] ポップアップ ページを作ります。
[Privacy] ポップアップ用ファイルに使う新しいフォルダーを作ります。ソリューション エクスプローラーで、プロジェクト名を右クリックし、[追加]、[新しいフォルダー] の順にクリックします。
新しいフォルダーの名前を「privacy」に変更します。
[privacy] フォルダーを右クリックし、[追加]、[新しい項目] の順にクリックします。
[新しい項目の追加] ダイアログ ボックスで、[インストール済み]、[JavaScript]、[Windows ストア]、[ページ コントロール] の順にクリックします。
[名前] ボックスに「"privacy.html"」と入力し、[追加] をクリックします。
新しいファイルをアプリ用に変更します。
privacy.html ファイルで、<div> 要素を次のコードに置き換えます。
<div id="privacy" data-win-control="WinJS.UI.SettingsFlyout" data-win-options="{width: 'narrow'}"> <div class="SettingsPane"> <div class="win-label"> <button onclick="WinJS.UI.SettingsFlyout.show()" class="win-backbutton"> </button> <span class="SettingsTitle">Privacy</span> </div> <article class="SettingsContent"> <!-- Customize this text to fit your application. --> <h2>How we protect your personal information</h2> <h4>Your privacy statement or a link to your privacy statement goes here.</h4> </article> </div> </div>
独自のプライバシーに関する声明が示されるように privacy.html の内容を変更してください。
次のコードを account.css ファイルの末尾に追加します。
.privacy p { margin-left: 120px; } .SettingsPane { margin-top:36px; margin-left:48px; } .SettingsTitle { margin-left: 36px; } .SettingsContent { margin-top: 24px; } #privacy { background-color: gray ; }
設定コマンドを追加します。
default.js ファイル内で、次のコードを app.onactivated イベント ハンドラーに追加します。
// Define the Settings flyout commands. // The commands appear in the Settings charm from top-to-bottom // in the order they are added. app.onsettings = function (e) { e.detail.applicationcommands = { // Add the Account command "account": { // Location of page content href: "/account/account.html", // Command to show in settings menu title: "Account" }, // Add the privacy command. "privacy": { // Location of page content href: "/privacy/privacy.html", // Command to show in settings menu title: "Privacy" } } // Command to update app's settings menu // using the preceding definition. WinJS.UI.SettingsFlyout.populateSettings(e); }
アプリをビルドして実行します。
設定チャームを開きます。[Account] コマンドと [Privacy] コマンドが [設定] ウィンドウに表示されることを確認します。
各コマンドをクリックして、ポップアップが開くことを確認します。
両方のポップアップを確認できたら、アプリを閉じて次に進みます。
ステップ 4: UI コンテンツとデータ バインディングを追加する
ユーザーの Microsoft アカウントへの接続の現在の状態が、アプリの UI で表されるようにする必要があります。静的なテキストをアプリの UI に配置する代わりに、データ バインディングを使います。これにより、対応するデータ値が変化すると、UI コンテンツも変化します。
この手順では、アプリのデータを UI に関連付けるコードを追加します。
default.html を更新して、UI をアプリ データに関連付けるバインド属性を持つ UI 要素を含めます。
これを行うには、default.html 内の <body> タグの内容を次のコードに置き換えます。
<div id="bindingDiv"> <!-- The elements in this div get their data from the app's data object by using a binding object. --> <div class="heading"> <h1> <!-- The app's title. This is configured by the program. --> <span id="titleText" data-win-bind="innerText: person.titleText">person.titleText</span> </h1> </div> <div class="content"> <!-- The app's content. This is a photo for this example. When the user is signed out, one photo is shown; when they are signed in, another is shown. --> <img id="appImage" data-win-bind="src: image.url; title: image.caption" /> <!-- Show the caption as text in the display as well as hover text in the image. --> <p id="appImageCaption" data-win-bind="innerText: image.caption">image.caption</p> </div> </div>
data-win-bind 属性のあるタグでは、属性にバインドされるデータ フィールドがタグの値にもなっています。これはデバッグのみを目的とした動作です。バインドに成功すると、このテキストはプログラムからのデータ値によって置き換えられます。バインドに失敗すると、データ値の名前が UI に表示されるものと異なるため、エラーのデバッグに役立ちます。
バインド オブジェクトとして使うデータ オブジェクトを作ります。
プロジェクトの js フォルダーに data.js という新しいファイルを作り、このファイルにコードを追加します。そのためには、次のようにします。
ソリューション エクスプローラーで、js フォルダーを右クリックし、[追加]、[新しい項目] の順にクリックします。
[インストール済み]、[JavaScript]、[コード]、[JavaScript ファイル] の順にクリックします。
[名前] ボックスに「"data.js"」と入力し、[追加] をクリックします。
data.js の内容を次の例のコードに置き換えます。
(function () { "use strict"; // The global data object used to reference the binding object WinJS.Namespace.define("binding", { Person: null } ); // Static text WinJS.Namespace.define("display", { state: ["Some nice photo", "'s favorite photo"] } ); // The app's data object that is used to map the // sign-in state to the UI. WinJS.Namespace.define("appInfo", { index: 0, // The sign-in state. image: { // The image to show url: "/images/SignedOutImage.png", caption: "Something not so special." }, person: { // The info about the user userName: null, titleText: display.state[0] } } ); })();
default.html 内で、この新しいファイルへの参照を追加します。これを行うには、default.js を参照する <script> タグの前に次のコードを挿入します。
<!-- The app's data definition --> <script src="/js/data.js"></script>
データ オブジェクトを UI にバインドするコードを追加します。
バインド オブジェクトを作って初期化するために、default.js 内の app.onactivated イベント ハンドラーに次のコードを追加します。
// Create the binding object that connects the appInfo data // to the app's UI. binding.Person = WinJS.Binding.as(appInfo); // Update the binding object so that it reflects the state // of the app and updates the UI to reflect that state. getInfoFromAccount(binding.Person);
アプリのドキュメントが読み込まれた後にバインド オブジェクトからのデータで UI を更新するイベント ハンドラーを追加します。
default.js 内で、次のイベント ハンドラーを app.oncheckpoint 割り当ての直前に追加します。
app.onloaded = function (args) { // Initialize the UI to match the corresponding data object. var div = document.getElementById("bindingDiv"); WinJS.Binding.processAll(div, appInfo); }
アプリのデータをユーザーのデータと同期する関数を追加します。
この手順では、この関数はテスト用に静的データのみを提供します。ユーザーのデータを Microsoft アカウントから取得するための関数は、後の手順で追加します。
default.js 内で、匿名関数の後にこの関数を追加します。これにより、アプリ内の他のモジュールからこの関数を認識できるようになります。
function getInfoFromAccount(p) { // Test for a parameter and assign the unbound data object // if a parameter wasn't passed. This doesn't refresh the binding // object, but it does keep the data object coherent with the // sign-in state. if (undefined === p) { p = appInfo; } if (0 == p.index) { // The program executes this branch when the user is // not signed in. // Set the data to the signed-out state values // and update the app title. p.person.userName = null; p.person.titleText = display.state[p.index]; // These elements are the default values to show // when the user is not signed in. p.image.url = "/images/SignedOutImage.png"; p.image.caption = "Something not so special."; } if (1 == p.index) { // The program executes this branch when the user is // signed in. // Set the data to the signed-in state, // get the user's first name, and update the app title. p.person.userName = "Bob"; p.person.titleText = p.person.userName + display.state[p.index]; // These elements would normally be read from the user's data, // but in this example, app resources are used. p.image.url = "/images/SignedInImage.png"; p.image.caption = "Something special to me."; } }
画像ファイルを追加します。
2 つの画像ファイルをプロジェクトの [images] フォルダーにコピーします。1 つ目の画像の名前を "SignedOutImage.png" に変更し、2 つ目を "SignedInImage.png" に変更します。
ソリューション エクスプローラーで、[images] フォルダーを右クリックし、[追加]、[既存の項目] の順にクリックします。
追加した 2 つの画像ファイルを選択し、[追加] をクリックします。
アプリをビルドしてテストします。適切なテキストと SignedOutImage.png 画像がページに表示されたら、次の手順に進みます。
アプリで、テキストの代わりにデータ フィールドの名前が表示された場合は、データ バインディングに問題があるため、先へ進む前に修正する必要があります。
ステップ 5: バインド オブジェクトを使うために [Account] ポップアップを更新する
account.html 内で、<button> タグを次のように変更します。これにより、サインインの状態を使ってポップアップに正しいボタンが表示されるようになります。
<button id="signInBtn" onclick="signInCmd(binding.Person)" style="display:none">Sign in</button> <button id="signOutBtn" onclick="signOutCmd(binding.Person)" style="display:none">Sign out</button>
account.js 内で、匿名関数の後に次の各関数を追加します。
function updateDisplay(p) { // Update the display to show the caption text and button // that apply to the current sign-in state. // Test for a parameter and assign the unbound global data object // if a parameter wasn't passed. This doesn't refresh the screen // but it does keep the data object coherent. if (undefined === p) { p = appInfo; } // Get the elements in the display for this function to update. var prompt = document.getElementById("accountPrompt"); var inBtn = document.getElementById("signInBtn"); var outBtn = document.getElementById("signOutBtn"); // Update the elements to show the correct text and button for the // the sign-in state. if (0 == p.index) { // The user is signed out, so prompt them to sign in. prompt.innerText = "Sign in to see your favorite photo." outBtn.style.display = "none"; inBtn.style.display = "block"; } else { // The user is signed in so welcome them and show the sign-out button. prompt.innerText = "Welcome, " + p.person.userName + "!" inBtn.style.display = "none"; outBtn.style.display = "block"; } } function signInCmd(p) { // Sign the new user in. // This call closes the Flyout and Settings charm. SignInNewUser(p); // Update the display to the signed-in state but keep the Flyout open // in case they want to sign in again. updateDisplay(p); // Return to the Settings flyout. WinJS.UI.SettingsFlyout.show(); } function signOutCmd(p) { // Sign the current user out. SignOutUser(p); // Update the display to the signed-out state but keep the Flyout open // in case they want to sign in again. updateDisplay(p); // Return to the Settings flyout. WinJS.UI.SettingsFlyout.show(); }
次に、WinJS.UI.Pages.define 呼び出しの ready ケースの関数を変更して、次の例のように updateDisplay の呼び出しを含めます。
ready: function (element, options) { // TODO: Initialize the page here. // Update the Account Flyout to reflect // the user's current sign-in state. updateDisplay(binding.Person); },
Microsoft アカウントに対するユーザーのサインインとサインアウトを行う関数を default.js に追加します。
現時点では、これらの関数は Windows Live サービス機能と連携しません。その部分は後の手順で追加します。これらの関数は、バインド オブジェクトが両方のサインイン状態で動作し、サインイン状態が変化したら UI が更新されるように、テストすることのみを目的としています。
function SignInNewUser(p) { // Sign the user in. // Test for a parameter and assign the unbound global data object // if a parameter wasn't passed. This doesn't refresh the screen // but it does keep the data object coherent. if (undefined === p) { p = appInfo; } p.index = 1; getInfoFromAccount(p); } function SignOutUser(p) { // Sign the user out. // Test for a parameter and assign the unbound global data object // if a parameter wasn't passed. This doesn't refresh the screen // but it does keep the data object coherent. if (undefined === p) { p = appInfo; } p.index = 0; getInfoFromAccount(p); }
アプリをビルドしてテストします。
アプリが起動し、SignedOutImage.png が表示されます。
設定チャームを開き、[Account] コマンドをクリックします。[Sign in] ボタンとプロンプトが表示されることを確認します。
[Sign in] ボタンをクリックし、アプリの状態を確認します。サインインの状態を反映して、[Account] ポップアップのコンテンツが変化します。
[Account] ポップアップで、[Sign out] ボタンとプロンプトが表示されることを確認します。
[Sign out] ボタンをクリックし、アプリの状態を確認します。サインアウトの状態を反映して、[Account] ポップアップのコンテンツが変化します。
アプリがこのように動作する場合は、Windows Live サービス機能を追加できる状態になっています。
ステップ 6: Live SDK 関数を追加する
Live SDK への参照をアプリに追加します。
ソリューション エクスプローラーで、[参照設定] を右クリックし、[参照の追加] をクリックします。
[Windows]、[拡張機能] の順にクリックし、[Live SDK] をオンにして、[OK] をクリックします。
default.html 内で、<head> タグ内の default.css リンクの前に、次の行を追加します。
<!-- The Live SDK --> <script src="///LiveSDKHTML/js/wl.js"></script>
Live SDK を初期化します。
default.js 内で、app.onactivated ハンドラー内の binding.Person 割り当ての後に、次のコードを挿入します。
// Initialize the Live SDK. WL.init();
アプリが Microsoft アカウントからユーザーのサインイン情報を取得できるように、getInfoFromAccount 関数を更新します。
default.js 内の getInfoFromAccount 内で、p.index をテストする 2 つの if ステートメントを次のコードに置き換えます。
// Call the user's Microsoft account to get the identity of the current // user. If the user is signed in, the success branch runs. // If the user is not signed in, the failure branch runs. WL.api({ path: "me", method: "GET" }).then( function (response) { // The program executes this branch when the user is // signed in. // Save the app's sign-in state. p.index = 1; // Set the data to the signed-in state, // get the user's first name, and update the app title. p.person.userName = response.first_name; p.person.titleText = p.person.userName + display.state[p.index]; // These elements would normally be read from the user's data, // but in this example, app resources are used. p.image.url = "/images/SignedInImage.png"; p.image.caption = "Something special to me."; }, function (responseFailed) { // The program executes this branch when the user is // not signed in. // Reset the app state. p.index = 0; // Set the data to the signed-out state values // and update the app title. p.person.userName = null; p.person.titleText = display.state[p.index]; // These elements are the default values to show // when the user is not signed in. p.image.url = "/images/SignedOutImage.png"; p.image.caption = "Something not so special."; } );
ユーザーが自分の Microsoft アカウントにサインインできるように、SignInNewUser 関数を更新します。
default.js 内の SignInNewUser 内で、パラメーター テストの後のコードを次のコードに置き換えます。
// Sign the user in with the minimum scope necessary for the app. WL.login({ scope: ["wl.signin"] }).then(function (response) { getInfoFromAccount(p); });
SignOutUser 関数を更新します。
default.js 内の SignOutUser 内で、パラメーター テストの後のコードを次のコードに置き換えます。
// Sign out and then refresh the app's data object. WL.logout().then(function (response) { getInfoFromAccount(p); });
ShowSignOutButton 関数を追加します。
default.js の末尾に、次に示す ShowSignOutButton 関数を追加します。
function ShowSignOutButton() { // Return true or false to indicate whether the user // can sign out of the app. return (WL.canLogout()); }
ユーザーがサインアウトできるかどうかを確認するテストを追加します。Microsoft アカウントに関連付けられているコンピューター アカウントでアプリにサインインした場合、ユーザーはアプリからサインアウトできません。この関数では、適切なプロンプトをユーザーに表示できるように、この条件をテストします。
account.js 内の updateDisplay 関数内で、if ステートメントを次のコードに置き換えます。[Sign out] ボタンを表示するかどうかを示すために、テストが追加されています。
if (0 == p.index) { // The user is signed out, so prompt them to sign in. prompt.innerText = "Sign in to see your favorite photo." outBtn.style.display = "none"; inBtn.style.display = "block"; } else { // The user is signed in, so welcome them. // If the user can sign out, show them the sign-out button. var promptText = "Welcome, " + p.person.userName + "!"; var signOutBtnStyle = "block"; if (ShowSignOutButton()) { // The user is signed in and can sign out later, // so welcome them and show the sign-out button. signOutBtnStyle = "block"; } else { // The user is signed in and can't sign out later, // so welcome them and hide the sign-out button. promptText = promptText + " The app is signed in through your Windows 8 account." signOutBtnStyle = "none"; } prompt.innerText = promptText; outBtn.style.display = signOutBtnStyle; inBtn.style.display = "none" }
これまでにテスト目的で使用したダミー コードを削除します。
account.js 内の signInCmd 内で、updateDisplay と WinJS.UI.SettingsFlyout.show の呼び出しを削除します。その結果、この関数内のコードは次の行のみになります。
// Sign the new user in. // This call closes the Flyout and Settings charm. SignInNewUser(p);
account.js 内の signOutCmd 内で、updateDisplay の呼び出しを削除します。その結果、この関数内のコードは以下のみになります。
// Sign the current user out. SignOutUser(p); // Return to the Settings flyout. WinJS.UI.SettingsFlyout.show();
これで、アプリを Microsoft アカウントに対してテストする準備ができました。
ステップ 7: アプリをテストする
アプリをビルドして実行し、各操作をテストします。
Microsoft アカウントへのサインインをテストします。
ユーザーの Microsoft アカウントからアプリをサインアウトした状態で、次の手順を試します。
- 設定ポップアップを開き、[Account] をクリックして、[Sign in] をクリックします。
- Microsoft アカウントでサインインします。続行の許可を求めるメッセージが表示されたら、[はい] をクリックします。
- アプリ内のテキストと画像が、サインイン時のテキストと画像に変わることを確認します。
アプリからのサインアウトをテストします。
注 Microsoft アカウントに関連付けられているコンピューター アカウントでアプリをテストしている場合、[Sign out] ボタンは無効になります。これは予期される動作です。このテストを実行するには、Microsoft アカウントに関連付けられていないコンピューター アカウントでアプリを実行する必要があります。
ユーザーの Microsoft アカウントにアプリをサインインした状態で、次の手順を試します。
- 設定ポップアップを開き、[Account] をクリックして、[Sign out] をクリックします。
- アプリ内のテキストと画像が、サインアウト時のテキストと画像に変わることを確認します。
シングル サインオンをテストします。
シングル サインオンは、コンピューター アカウントを Microsoft アカウントに関連付けることのできる Windows の機能です。このようなコンピューター アカウントでアプリを実行している場合、アプリはこれまでの説明とは異なる形で動作します。
たとえば、次のようになります。
- 自動的にサインインした状態でアプリが起動することがあります。
- アプリ内でアカウントからサインアウトできないため、[Account] ポップアップに [Sign out] ボタンが表示されません。
- アプリからサインアウトできないことを示すメッセージが [Account] ポップアップに表示されます。