Май 2016
Том 31 номер 5
Универсальные Windows-приложения - Размещенные веб-приложения для предприятия
Tim Kulp | Май 2016
Продукты и технологии:
Приложения Universal Windows Platform (UWP), JavaScript, веб-разработка, UWP Bridges
В статье рассматриваются:
- применение UWP Bridges для передачи веб-приложений в Windows Store;
- создание размещенных веб-приложений (hosted Web applications) в Visual Studio 2015;
- расширение размещенных веб-приложений «родной» функциональностью;
- работа с другими мобильными платформами в одном и том же размещенном веб-приложении.
Разработчики, работающие на предприятии с разветвленной структурой, знают, что внедрить новые технологии не всегда легко. Реализовать на предприятии нечто новое вроде проекта приложения Universal Windows Platform (UWP) может оказаться трудной задачей, когда у вас нет групп, уверенных в своих возможностях создать этот тип приложения. Многие предприятия вложили значительные инвестиции в свои веб-приложения интрасети и группы, которые их поддерживают. Размещенные веб-приложения (hosted Web applications, HWA) создают мост для корпоративных веб-приложений интрасети, через который их можно включить в Windows Store for Business с минимальными усилиями.
В этой статье я преобразую существующее веб-приложение интрасети в UWP-приложение для Windows Store, а затем расширю его «родной» для Windows функциональностью. Как показано на рис. 1, это веб-приложение Gotcha для поиска по социальным сетям (social recognition app), позволяющее сотрудникам Contoso Corp. находить своих коллег и выражать им признательность за добрые дела. Gotcha предназначено для дружеской оценки любых сотрудников и сплочения команды. Это веб-приложение является отличным кандидатом для Windows Store в том смысле, что оно обеспечивает простоту интеграции с контактами, средствами обмена информацией и камерой.
Рис. 1. Веб-приложение Gotcha
Bridges и размещенные веб-приложения для предприятия
Для корпоративных разработчиков UWP Bridges и HWA имеют смысл, так как это позволяет им сохранить свои существующие наборы инструментов, процессы и системы развертывания приложений. Идея, лежащая в основе Bridges, — дать возможность разработчикам перенести существующие приложения для iOS, Android, Win32 или веб-приложения на UWP и в кросс-платформенный Windows Store. Благодаря этому разработчики смогут перенести свою существующую кодовую базу на UWP и оживить пользовательскую среду (UX) средствами, специфичными для Windows.
Bridges упрощают перенос кода на UWP, но корпоративные разработчики сталкиваются с другими трудными задачами, которые могут осложнить преобразование их кода. Разработчики в корпорации могут быть ограничены в выборе редакторов исходного кода или места развертывания кода в зависимости от степени конфиденциальности информации внутри приложения. Истинная ценность UWP Bridges для предприятия заключается не в простоте преобразования приложений, а в возможности сохранить существующие корпоративные инструменты разработки ПО, практики и систему управления изменениями при доставке UWP-приложений через Windows Store.
В качестве примера HWA (также известные под названием «Project Westminster») позволяют разработчикам встраивать веб-приложения в какое-либо UWP-приложение. Создав UWP-приложение с расчетом на использование контента HWA, разработчики могут применять существующие у них практики для сопровождения веб-приложения, которое будет автоматически обновлять соответствующую часть UWP-приложения. С помощью HWA Bridge разработчики могут сосредоточиться на своем веб-приложении и включать средства, специфичные для UWP, через распознавание таких средств (feature detection). Работа с имеющейся интрасетью — отличный вариант использования для UWP Bridges, но разработчики вне предприятия также могут задействовать HWA, чтобы сделать доступными собственные веб-приложения в Windows Store. Любой веб-сайт может быть HWA, если он проходит процесс сертификации в Windows Store.
Основы HWA исчерпывающе рассмотрены в статье Кирилла Сексенова «Project Westminster in a Nutshell» (bit.ly/1PTxxW4). Советую прочитать эту статью, чтобы получить более глубокое понимание идей, лежащих в основе HWA.
Приступаем к проекту Web HWA
Чтобы приступить к конвертации веб-приложения Gotcha в HWA, я создаю новый проект JavaScript UWP App в Visual Studio. Создав приложение, открываю манифест пакета и указываю URL веб-приложения в качестве начальной страницы UWP-приложения, как показано на рис. 2. В данном случае веб-приложение Gotcha запускается с localhost:6107. После этого приложение будет отображать веб-страницу по указанному адресу вместо своего локального контента.
Рис. 2. Настройка начальной страницы в манифесте пакета
Наконец, задайте в манифесте пакета URI-идентификаторы контента. Эти URI будут сообщать вашему приложению, какие страницы могут обращаться к библиотекам Windows Runtime (WinRT) и какой уровень доступа могут иметь эти URI. Я слышал, что этот процесс описывают как определение того, где заканчивается приложение и начинается Интернет, и, как мне кажется, это хороший умозрительный образ того, как используются URI контента. В существующем веб-приложении Gotcha есть четкое разделение между тем, что делает приложение и как оно может использовать для этого Интернет. Например, в Gotcha пользователи могут делиться своими оценками в социальных сетях вроде LinkedIn. Веб-сайт LinkedIn не является частью UWP-приложения Gotcha; это часть Интернета. Я включу только те URI, которые напрямую применяются в приложении, и лишь те из них, которым нужен доступ к UWP API.
Применение URI контента позволяет разработчику защищать пользователей приложения, предотвращая доступ к библиотекам WinRT по незарегистрированным URI. Для каждого URI указывайте необходимый уровень доступа к библиотекам WinRT.
- All JavaScript-код, выполняемый в веб-приложении (в данном случае — в Gotcha), может обращаться к любым UWP API, определенным через App Capabilities.
- Allow for Web Only JavaScript-код, выполняемый в веб-приложении, может запускать пользовательские WinRT-компоненты, включенные в пакет приложения, но не может обращаться ко всем UWP API.
- None JavaScript-код, выполняемый в веб-приложении, не может обращаться к локальным UWP API (настройка по умолчанию).
При задании URI контента помните, что это ключевой компонент защиты для пользователя UWP-приложения. Убедитесь, что вы выдаете URI лишь минимальные разрешения для необходимых функций UWP-приложения, как показано на рис. 3. Старайтесь избегать установки корневого URI WinRT Access в All, если только это действительно нужно в приложении.
Рис. 3. Выдача URI контента наименьшей привилегии, необходимой для работы приложения
Не рекомендую удалять существующий контент, который предоставляется вам в процессе создания проекта (например, папки .css, .js и WinJS). Этот контент дает разработчикам великолепную инфраструктуру, применимую для добавления локального контента в Web HWA. Далее в этой статье я задействую эти папки для локального контента, чтобы создать некоторые средства, дополняющие автономные (в отключенном от сети состоянии) возможности Web HWA.
Сконфигурировав манифест пакета, запустите UWP-приложение. Как видно на рис. 4, теперь веб-приложение будет появляться в окне приложения, как и любое другое UWP-приложение.
Рис. 4. Приложение Gotcha, готовое для Windows Store
Отладка размещенного веб-приложения
Отладка HWA несколько отличается от таковой для чисто «родных» приложений. Откройте UWP-приложение и нажмите F12. На экране появятся F12 Developer Tools для UWP-приложения. С помощью F12 Developer Tools я могу отлаживать, профилировать и тестировать веб-приложение точно так же, как в браузере. Хотя разработчикам HWA пригодятся все средства F12 Developer Tools, наиболее полезными компонентами я считаю поддержку отладки вне Visual Studio и профилирования сетевой активности. Я использую эти средства, чтобы разобраться в специфических поведениях приложения и понять источники любых проблем (вроде кеширования).
Как и при использовании F12 в браузере, разработчики могут изменять DOM и экспериментировать с разными UI в зависимости от размера экрана или окна. Это пригодится при исследовании изменений в разметке веб-приложения для адаптации к требованиям приложения. В качестве примера фиксация UWP-приложения для отображения как боковой панели должна приводить к пересчету размеров и позиций UI-элементов. Если изменение размера не вызывает такого пересчета в приложении, F12 Developer Tools помогут определить причину и поэкспериментировать с DOM, чтобы понять, что нужно для достижения правильного пересчета.
Добавление функциональности для UWP-приложения
Подготовив базовое HWA, я намерен заняться возможностями веб-приложения, чтобы включить некоторые UWP API и оживить пользовательскую среду (UX). Веб-приложения интрасети могут иметь ограничения, которых нет у HWA. Используя UWP API, HWA может обращаться ко многим локальным средствам UWP-устройства (например, к камере, определению местонахождения и различным датчикам). Для начала подумаем о случаях применения, которые стимулируют реализацию веб-приложения в виде размещенного веб-приложения. В Gotcha я хочу, чтобы у пользователей была возможность выбирать из своих контактов, кому присудить награду, а не просто набирать имя этой персоны и прикреплять какой-то снимок для узнавания.
Первым делом я создаю в веб-приложении удаленный файл GotchaNative.js (файл скриптов GotchaNative.js будет размещен на удаленном сервере веб-приложения), который будет распознавать пространства имен «родных» API и выполнять соответствующий код, чтобы инициировать наши случаи применения с использованием «родной» функциональности. Добавьте в файл NativeGotcha.js следующий код:
var GotchaNative = (function () {
if (typeof Windows != 'undefined') {
// Здесь добавляем нахождение контакта...
// Здесь добавляем снимок, сделанный камерой...
}});
Этот код создает объект GotchaNative, который будет хранить всю функциональность UWP API. Централизация этих API позволяет включать один файл в страницы, где требуется функциональность UWP API. Я изолирую этот файл, чтобы иметь возможность явным образом объявить URI контента, включающие этот специфический файл, как URI с доступом к необходимым UWP API. Тем самым я могу реализовать концепцию защиты «принцип наименьшей привилегии» и выдавать разрешения только URI, которым необходим доступ к UWP API.
Другое преимущество изоляции этого файла — подготовка и для других платформ. Об этом мы поговорим далее в этой статье, а пока рассматривайте этот файл как место хранения всей «родной» функциональности, которая будет включена в веб-приложение Gotcha.
Расширение существующей функциональности
Создав объект GotchaNative, можно добавить специфическую функциональность для подключения HWA к UWP API. В первом случае применения веб-приложение Gotcha дает возможность пользователям вводить персону для одобрения. В UWP у пользователей есть приложение People, которое хранит контакты и было бы гораздо проще для пользователей в выборе нужного человека, чем ввод его имени. Замените комментарий «Здесь добавляем нахождение контакта...» в файле GotchaNative.js на:
this.FindContact = function () {
var picker = new Windows.ApplicationModel.
Contacts.ContactPicker();
picker.desiredFieldsWithContactFieldType.append(
Windows.ApplicationModel.Contacts.ContactFieldType.email);
return picker.pickContactAsync();
}
Это базовый код для подключения к ContactPicker API, позволяющему выбирать контакт из списка контактов. Список UWP API, которые можно включать в Web HWA, находится на сайте rjs.azureWebsites.net. На этом веб-сайте перечислены некоторые из более популярных API с кодом, готовым для копирования и вставки, чтобы помочь вам в разработке проекта Web HWA.
Функциональность для добавления персоны можно найти в Person View Model для веб-сайта Gotcha. Добавьте в Person View Model код с рис. 5.
Рис. 5. Код для добавления в Person View Model
if (Windows != undefined) {
var nativeGotcha = new NativeGotcha();
nativeGotcha.FindContact().done(function (contact) {
if (contact !== null) {
$("#txtWho").val(contact.displayName);
} else {
// Никакие контакты не выбраны
}
});
}
else {
$('#add-person').on('shown.bs.modal', function () {
$("#txtWho").focus();
}
В коде на рис. 5 используется метод FindContact, если объект Windows определен благодаря скрипту, выполняемому как HWA. Если же объект Windows не определен, веб-приложение продолжит использовать существующее модальное окно Bootstrap для сбора информации о персоне для одобрения. Этот код позволяет веб-приложению применять один подход для ввода нужной персоны, а UWP-приложение может использовать другой подход, более адаптированный под «родную» среду.
Добавление новой функциональности
Иногда включение UWP API позволяет включать новую функциональность, которая обычно отсутствует в веб-приложении. В Gotcha HWA я хочу разрешить пользователям делать снимки и отправлять их для одобрения другим пользователям Gotcha. Эта функциональность будет новой для этого приложения, которой нет в веб-приложении. При создании HWA подумайте над возможностями, открываемыми UWP API для приложения.
В Gotcha HWA я хочу разрешить пользователям делать снимки и отправлять их для одобрения другим пользователям Gotcha.
Чтобы приступить к реализации этой новой функциональности, сначала замените комментарий «Здесь добавляем снимок, сделанный камерой...» в файле GotchaNative.js следующим кодом:
this.CapturePicture = function () {
var captureUI = new Windows.Media.Capture.CameraCaptureUI();
captureUI.photoSettings.format =
Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
return captureUI.captureFileAsync(
Windows.Media.Capture.CameraCaptureUIMode.photo);
}
В этом коде я открываю UI захвата снимка, позволяю сделать снимок, а затем возвращаю снимок вызвавшему коду. Эта новая функция должна быть разрешена в веб-приложении, если определен объект Windows. Используя распознавание функционала, как это делалось в Person View Model, я добавляю код с рис. 6 в Home View Model.
Рис. 6. Код распознавания функционала, добавляемый в Home View Model
$('#give-modal').on('shown.bs.modal', function () {
if (typeof Windows != 'undefined') {
var gotchaNative = new NativeGotcha();
$("#btnCamera").click(function () {
gotchaNative.CapturePicture().then(
function (capturedItem) {
// Что-то делаем с capturedItem;
});
}).show();
}
else {
$("#btnCamera").hide();
}
})
В коде на рис. 6 я скрываю btnCamera, если объект Windows не определен. А если он определен, тогда я настраиваю событие щелчка на запуск функции CapturePicture. Для краткости я оставил комментарий вместо операции над снимком. При включенной камере я должен учитывать, что это HWA все же является UWP-приложением, которому нужно разрешить использование функции Webcam, что делается через манифест пакета.
Корпоративные веб-приложения можно конвертировать в HWA и использовать UWP API магазина Windows Store. На основе существующих веб-приложений легко создавать UWP-приложения в Windows Store, но HWA предполагают наличие соединения с Интернетом. Далее я покажу, как обеспечить работу приложения даже в отсутствие доступа к Интернету.
Подключение в автономном режиме
UWP-приложение может иметь локальные файлы, которые позволяют работать в автономном, или локальном, режиме. Используя локальный контент, вы можете отключать некоторые из UWP API, вызываемых из размещенного веб-приложения. Как и для функции распознавания, которая уже создана, связывание с локальным контентом можно осуществлять через активацию ссылок. В случае Gotcha я добавлю функцию работы с картами, использующую локальные элементы управления картами.
В HWA можно использовать ту же функцию распознавания, которая ранее применялась в Home View Model. Правильная схема URI позволит HWA переходить между веб-контентом и локальным контентом. На начальный экран я добавлю такую ссылку:
<a href="ms-appx:///default.html" id="lnkMap">
<span class="glyphicon glyphicon-map-marker">
</span> Show Map
</a>
Эта ссылка связывает со схемой ms-appx:///, которая позволяет приложению подключаться к локальному контенту внутри пакета приложения. При работе со схемой ms-appx приложение может подключаться к необходимым UWP API. Это аналогично использованию URI контента для объявления уровня доступа страницы к API. Применение ms-appx подобно пометке URI как All. В этом случае страница default.html имеет доступ к UWP API. Когда в HWA появляется ссылка, пользователи могут щелкнуть ее, чтобы работать с контентом внутри пакета приложения.
Для корпоративных разработчиков такая функциональность дает возможность изолировать случаи применения, специфичные для UWP, и обойтись без обязательного подключения к веб-приложению. Подключение к контенту пакета также позволяет избегать предоставления веб-приложению доступа к UWP API и ограничить весь доступ рамками пакета.
Можно ли использовать более одного магазина?
В ряде организаций может существовать среда Bring Your Own Device (принеси свое устройство). А значит, такая организация может уже предусматривать работу с устройствами iOS или Android в существующих приложениях. Приложения Android и iOS имеют концепции, сходные с HWA и реализованные в элементе управления WebView. WebView позволяет разработчикам предоставлять какое-либо окно в своих приложениях для существующего веб-приложения и последующего взаимодействия с этим веб-приложением так, будто оно является частью «родного» приложения (звучит знакомо?). HWA можно создавать так, чтобы они хорошо взаимодействовали с другими приложениями, адаптируя функциональность существующего веб-приложения под платформу, доставляющую это веб-приложение. Я обновлю GotchaNative.js для поддержки Android и покажу, как код HWA будет сосуществовать бок о бок с JavaScript, ориентированным на другие платформы.
Ранее я подготовил GotchaNative.js, что означает хранение всего «родного» кода в приложении. ViewModel будут обрабатывать вывод «родных» методов. Использование API любой платформы аналогично HWA: сначала приложение должно определить, доступны ли «родные» API, а затем вызывать соответствующий API. Приступая к обновлению GotchaNative.js, я добавлю свойство, которое будет сообщать мне, какая «родная» платформа (если таковая есть) обнаружена. В следующих примерах я предполагаю, что приложение Android использует WebView, который объявляет «Android» как пространство имен локального скрипта:
this.Platform = function () {
if (Windows != 'undefined')
return "Windows";
else if (Android != 'undefined')
return "Android";
else
return "Web";
}
Эта функция позволяет моему коду определить, с какой платформой придется работать, поэтому я могу подстроить код под эту платформу. Отсюда каждый метод в GotchaNative.js может проверять платформу, чтобы выяснить, как действовать дальше (рис. 7).
Рис. 7. Методы в GotchaNative.js, проверяющие платформу
this.CapturePicture = function () {
switch (this.Platform()) {
case "Windows":
var captureUI =
new Windows.Media.Capture.CameraCaptureUI();
captureUI.photoSettings.format =
Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
return captureUI.captureFileAsync(
Windows.Media.Capture.CameraCaptureUIMode.photo);
break;
case "Android":
// Вызов Android-кода в «родном» приложении
Android.CaptureFile();
break;
default:
return null;
break;
}
Теперь во всех ViewModel код будет обновлен на использование функции распознавания платформы, чтобы знать, что делать с выводом методов GotchaNative. Ниже я обновляю код для события кнопки камеры из HomeViewModel:
$("#btnCamera").click(function () {
switch (gotchaNative.Platform()) {
case "Windows":
gotchaNative.CapturePicture().then(
function (capturedItem) {
// Что-то делаем с capturedItem;
});
break;
case "Android":
// Обрабатываем вывод для Android
break;
}
}).show();
Теперь, когда приложение поддерживает больше платформ, у меня есть единое место в коде для расширения возможностей под все платформы. Если завтра выйдет новая ОС, группа разработки сможет адаптировать код и под эту новую платформу.
Заключение
Корпоративные разработчики сталкиваются с множеством трудных задач в своей работе. Стандартизованные процессы и инструментарий могут оказаться барьером на пути к внедрению новых технологий вроде UWP-приложений. UWP Bridges позволяют корпоративным разработчикам размещать свои существующие внешние веб-приложения или веб-приложения для интрасетей в Windows Store (либо как общедоступные, либо как Windows Store for Business). Bridges для HWA могут превратить веб-приложение в кросс-платформенное UWP-приложение, используя UWP API для оживления пользовательской среды.
В этой статье я исследовал, как преобразовать существующее веб-приложение в HWA, в то же время добавляя специфичные для UWP-приложения средства вроде доступа к камере и контактам. На основе схемы ms-appx я показал, как переходить из размещенного веб-приложения к локальному контенту внутри пакета приложения. Наконец, я продемонстрировал, что при некоторой доле планирования HWA можно создавать с расчетом на множество разных платформ, позволяя предприятию не отставать от постоянно расширяющегося мира мобильных устройств. Благодаря этим подходам HWA могут задействовать существующие инвестиции в веб-приложения, помогая предприятиям присоединиться к экосистеме Windows Store.
Тим Кульп (Tim Kulp) — старший технический архитектор, живет в Балтиморе (штат Мериленд). Занимается разработкой для Web, мобильных устройств и UWP-приложений, а также является автором, художником и папой. Вы найдете его в Twitter (@seccode) или через LinkedIn (linkedin.com/in/timkulp).
Выражаю благодарность за рецензирование статьи экспертам Microsoft Джону-Дэвиду Дальтону (John-David Dalton) и Кириллу Сексенову (Kiril Seksenov).