Добавление служб Майкрософт в приложение (HTML)
[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]
Здесь вы узнаете, как добавить возможности, предоставляемые службами Майкрософт, в приложение среды выполнения Windows, чтобы предоставить ему доступ к информации из профиля пользователя, файлам и фотографиям в Microsoft OneDrive и данным в Outlook.com. Шаги, описанные в данном учебнике, начинаются с пустого приложения, в которое затем добавляются компоненты для входа в учетную запись Майкрософт пользователя и для получения информации профиля, которая отображается в приложении.
Важно В учебнике по данному разделу показано приложение Магазина Windows. В приложение магазина Windows Phone можно также добавить службы Майкрософт. Поскольку пользовательский интерфейс Windows Phone не поддерживает всплывающие элементы, для реализации функций, для которых в данном разделе используются всплывающие элементы, необходимо использовать страницы в приложении магазина Windows Phone.
Что необходимо знать
Технологии
Необходимые условия
- Windows 8
- Microsoft Visual Studio
- Пакет Live SDK
- Учетная запись разработчика приложений для Магазина Windows
- Два файла изображений (формата PNG), используемые в приложении
Инструкции
Этап 1: Создание проекта "Пустое приложение" и добавление Live SDK
Создайте новое приложение из шаблона Visual Studio следующим образом.
- В меню Visual Studio Файл щелкните Создать проект.
- В диалоговом окне Создать проект перейдите в раздел Установленные > Шаблоны > JavaScript > Магазин Windows.
- Выберите Пустое приложение.
- Введите имя и расположение вашего нового приложения и нажмите кнопку ОК.
- Выполните сборку и проверьте свое приложение. Оно должно запускать и отображать пустую страницу с надписью Место для содержимого. Если вы это видите, закройте приложение и продолжайте.
Этап 2: Добавление приложения в учетную запись разработчика приложений для Магазина Windows
Чтобы ваше приложение могло использовать облачные службы, к которым получает доступ Live SDK, оно должно быть зарегистрировано в вашей учетной записи разработчика приложений для Магазина Windows. Вам не нужно отправлять приложение в Магазин Windows для сертификации. Нужно просто ввести название для него в учетной записи разработчика приложений для Магазина Windows.
Этап 3: Добавление данных приложения и всплывающих элементов "Параметры"
Приложение Магазина Windows, использующее Live SDK, должно выполнять как минимум следующее.
- Давать пользователям возможность войти в свою учетную запись Майкрософт и выйти из нее, если это возможно.
- Отображать политику конфиденциальности, описывающее, как вы защищаете персональные данные, к которым получает доступ ваше приложение.
Дополнительные сведения о взаимодействии входа и выхода, а также о политики конфиденциальности см. в разделе Требования для входа с учетной записью Майкрософт.
В приложениях Магазина Windows это осуществляется с помощью всплывающих элементов "Параметры".
Чтобы добавить в приложение всплывающий элемент, выполните следующее.
Создайте страницу всплывающего элемента Учетная запись.
Создайте новую папку для файлов всплывающего элемента 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, выберите Добавить и Создать элемент.
В диалоговом окне Добавление нового элемента перейдите в раздел Установленные > 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); }
Выполните сборку и запустите свое приложение.
Откройте чудо-кнопку "Параметры". Убедитесь, что команды Учетная запись и Конфиденциальность отображаются на панели "Параметры".
Щелкните каждую команду, чтобы убедиться в запуске всплывающего элемента.
Убедившись, что оба элемента отображаются, закройте приложение и продолжайте.
Этап 4: Добавление содержимого пользовательского интерфейса и привязка данных
Пользовательский интерфейс приложения должен отображать текущее состояние подключения к учетной записи Майкрософт пользователя. Вместо размещения в пользовательском интерфейсе статичного текста используйте привязку данных, чтобы содержимое пользовательского интерфейса изменялось по мере изменения значений соответствующих данных.
На этом этапе необходимо добавить код, который соединяет данные приложения с пользовательским интерфейсом.
Обновите default.html, чтобы включить элементы пользовательского интерфейса и атрибуты привязки, которые соединяют интерфейс с данными приложения.
Для этого замените содержимое тега <body> в default.html следующим кодом.
<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 поля данных, привязанные к атрибуту, также отображаются в значении тега. Это делается для отладки. Если привязка выполнена успешно, этот текст заменят значения данных из программы. Если привязка не выполнена, вы увидите имя значения данных, которое не отображается в пользовательском интерфейсе, что поможет вам отладить ошибку.
Создайте объект данных для использования в качестве объекта привязки.
Создайте новый файл с именем data.js в папке js вашего проекта и добавьте в него код. Для этого сделайте следующее.
В обозревателе решений щелкните правой кнопкой мыши папку js и выберите Добавить и Создать элемент.
Перейдите в раздел Установленные > JavaScript > Code и выберите Файл 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, введя данный код перед тегом <script>, ссылающимся на default.js.
<!-- The app's data definition --> <script src="/js/data.js"></script>
Добавьте код, чтобы привязать объект данных к пользовательскому интерфейсу.
В 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);
Добавьте обработчик событий, чтобы обновлять пользовательский интерфейс данными объекта привязки после загрузки документа приложения.
В 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); }
Добавьте функцию, которая будет синхронизировать данные приложения с данными пользователя.
На данном этапе эта функция предоставляет лишь статичные данные для тестирования. Функции, позволяющие получать данные пользователя из его учетной записи Майкрософт, будут добавлены позже.
В 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."; } }
Добавьте свои файлы изображений.
Скопируйте два файла изображений в папку images вашего проекта. Переименуйте одно изображение в "SignedOutImage.png", а другое — в "SignedInImage.png".
В обозревателе решений щелкните правой кнопкой мыши папку images и выберите Добавить > Существующий элемент.
Выберите два файла изображений, которые вы только что добавили, и нажмите кнопку Добавить.
Выполните сборку и проверьте свое приложение. Если на странице отображается правильный текст и изображение SignedOutImage.png, переходите к следующему этапу.
Если ваше приложение отображает имя поля данных вместо текста, значит, существует проблема с привязкой данных, которую необходимо устранить, прежде чем продолжать работу.
Этап 5: Обновление всплывающего элемента "Учетная запись" для использования объекта привязки
В 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(); }
Затем измените функцию варианта ready вызова WinJS.UI.Pages.define таким образом, чтобы она включала вызов 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); },
Добавьте в файл default.js функции, которые обеспечивают вход и выход пользователя из учетной записи Майкрософт.
Эти функции пока не взаимодействуют с компонентами служб Windows Live —. Это взаимодействие будет добавлено позже. Эти функции дают вам возможность протестировать объект привязки, чтобы убедиться, что он работает в обоих состояниях входа и обновляет пользовательский интерфейс при изменении состояния входа.
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.
Откройте чудо-кнопку "Параметры" и выберите команду Учетная запись. Убедитесь, что появляется кнопка Вход и приглашение.
Нажмите кнопку Вход и убедитесь, что состояние приложения и содержимое всплывающего элемента "Учетная запись" изменилось и отобразилось состояние входа.
Во всплывающем элементе Учетная запись убедитесь, что появилась кнопка Выход и приглашение.
Нажмите кнопку Выход и убедитесь, что состояние приложения и содержимое всплывающего элемента "Учетная запись" изменилось и отобразилось состояние выхода.
Если ваше приложение работает таким образом, вы готовы добавлять компоненты служб Windows Live.
Этап 6: Добавление функций Live SDK
Добавьте в приложение ссылку на Live SDK.
В обозревателе решений щелкните правой кнопкой мыши Ссылки и выберите Добавить ссылку.
Перейдите в раздел Windows > Расширения, поставьте флажок рядом с пунктом Live SDK, а затем нажмите кнопку ОК.
В тег <head> файла default.html добавьте следующую строку перед ссылкой default.css.
<!-- The Live SDK --> <script src="///LiveSDKHTML/js/wl.js"></script>
Инициализируйте Live SDK.
В default.js введите следующий код после назначения binding.Person в обработчике app.onactivated.
// Initialize the Live SDK. WL.init();
Обновите функцию getInfoFromAccount, чтобы ваше приложение получило состояние входа пользователя из его учетной записи Майкрософт.
В файле default.js в getInfoFromAccount замените два оператора if, которые тестируют p.index, следующим кодом.
// 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."; } );
Обновите функцию 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()); }
Добавьте тест возможности выхода пользователя из учетной записи. Если пользователь входит в приложение с учетной записи компьютера, связанной с учетной записью Майкрософт, он не сможет выйти из приложения. Эта функция тестирует выполнение этого условия и отображение правильного приглашения для пользователя.
В файле account.js в функции updateDisplay замените оператор if следующим кодом. Обратите внимание на тест, который был добавлен, чтобы узнать, следует ли отображать кнопку Выход.
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();
Теперь ваше приложение готово к тестированию с учетной записью Майкрософт.
Этап 7: Тестирование приложения
Выполните сборку и запустите свое приложение и протестируйте следующие действия.
Протестируйте вход в учетную запись Майкрософт.
Начиная с приложения в состоянии выхода из учетной записи Майкрософт, выполните следующие шаги.
- Откройте всплывающий элемент "Параметры", выберите команду Учетная запись и нажмите Вход.
- Войдите с учетной записью Майкрософт. Если приложение спрашивает разрешения продолжить, нажмите Да.
- Убедитесь, что текст и изображение в приложении изменились в соответствии с состоянием входа.
Протестируйте выход из приложения.
Примечание Если вы тестируете приложение с учетной записи компьютера, связанной с учетной записью Майкрософт, кнопка Выход будет отключена. Это ожидаемое поведение. Чтобы выполнить этот тест, вы должны запустить свое приложение с учетной записи компьютера, не связанной с учетной записью Майкрософт.
Начиная с приложения в состоянии входа в учетную запись Майкрософт, выполните следующие шаги.
- Откройте всплывающий элемент "Параметры", выберите команду Учетная запись и нажмите Выход.
- Убедитесь, что текст и изображение в приложении изменились в соответствии с состоянием выхода.
Тестирование единого входа
Единый вход — это функция Windows, которая позволяет связывать учетную запись компьютера с учетной записью Майкрософт. Если вы запускаете приложение с такой учетной записи компьютера, поведение приложения будет отличаться от описанного выше.
Пример.
- Приложение может автоматически начать работу в состоянии входа.
- Кнопка Выход не отображается на всплывающем элементе "Учетная запись", потому что вы не можете выйти из своей учетной записи в приложении.
- На всплывающем элементе "Учетная запись" отображается дополнительное сообщение о том, что вы не можете выйти из приложения.