Создание мини-приложений на основе PWA
В различных операционных системах есть панели мониторинга мини-приложений, которые позволяют пользователям читать содержимое и выполнять задачи. Примерами этого являются мини-приложения "Начальный экран Android", мини-приложения панели мониторинга macOS и панели "Сегодня", панель Apple Touch Bar, Ежедневные карточки Samsung, мини-приложения мини-приложения и компаньоны приложений для смарт-часов.
В Windows 11 мини-приложения отображаются на доске мини-приложений, которая открывается слева от панели задач:
В Windows 11 прогрессивные веб-приложения (PWA) могут определять мини-приложения, обновлять их и обрабатывать взаимодействие с пользователем в них.
Требуется создание пользовательского мини-приложения для PWA
Существующий PWA нельзя просто поместить на панель мониторинга мини-приложения "как есть", как это можно сделать с помощью боковой панели Microsoft Edge. Вместо этого необходимо создать пользовательский интерфейс мини-приложения, подходящий для узла мини-приложения, который в настоящее время является доской мини-приложений Windows 11. (В будущем могут появиться другие узлы мини-приложений.) Доска мини-приложений Windows 11 требует создания мини-приложений с использованием шаблонов адаптивных карточек вместо HTML и JavaScript, поэтому мини-приложение должно разрабатываться отдельно от остального пользовательского интерфейса приложения.
См. также:
Чтобы создать мини-приложение на основе PWA и доставить его через Microsoft Store, код C++/C# не требуется. После создания мини-приложения и успешной установки и запуска мини-приложения из общедоступной конечной точки вы можете упаковать приложение с помощью PWABuilder.com и отправить приложение в Microsoft Store, не требуя дополнительного кода. Поддержка мини-приложения PWA должна быть установлена из общедоступной конечной точки, так как PWABuilder.com не поддерживает упаковку приложений из localhost.
См. также:
Установка WinAppSDK и включение режима разработчика
Чтобы включить разработку и тестирование мини-приложений на локальном компьютере, выполните приведенные ниже действия.
Установите WinAppSDK 1.2.
Включение режима разработчика в Windows 11:
Откройте раздел Параметры.
В текстовом поле Найти параметр введите
developer
и нажмите кнопку Использовать функции разработчика.Включить режим разработчика:
Определение мини-приложений
Мини-приложения определяются в файле манифеста PWA с помощью элемента манифеста widgets
. Этот элемент манифеста представляет собой массив, который может содержать несколько определений мини-приложений.
{
"name": "PWAmp",
"description": "A music player app",
"icons": [
{ "src": "img/icon-96.png", "sizes": "96x96" },
{ "src": "img/icon-128.png", "sizes": "128x128" },
{ "src": "img/icon-256.png", "sizes": "256x256" },
{ "src": "img/icon-512.png", "sizes": "512x512" }
],
"widgets": [
/* widget definitions go here */
]
}
Каждая запись в массиве widgets
содержит несколько полей, как показано ниже:
{
...
"widgets": [
{
"name": "PWAmp mini player",
"description": "widget to control the PWAmp music player",
"tag": "pwamp",
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player-template.json",
"data": "widgets/mini-player-data.json",
"type": "application/json",
"screenshots": [
{
"src": "./screenshot-widget.png",
"sizes": "600x400",
"label": "The PWAmp mini-player widget"
}
],
"icons": [
{
"src": "./favicon-16.png",
"sizes": "16x16"
}
],
"auth": false,
"update": 86400
}
]
}
В приведенном выше примере приложение музыкального проигрывателя определяет мини-приложение мини-проигрывателя. Определение мини-приложения в манифесте веб-приложения содержит следующие обязательные и необязательные поля:
Поле | Описание | Обязательный |
---|---|---|
name |
Название мини-приложения, представленное пользователям. | Да |
short_name |
Альтернативная краткая версия имени. | Нет |
description |
Описание того, что делает мини-приложение. | Да |
icons |
Массив значков, используемых для мини-приложения. Если элемент отсутствует, icons вместо него используется элемент манифеста. Значки размером более 1024x1024 игнорируются. |
Нет |
screenshots |
Массив снимков экрана, показывающих, как выглядит мини-приложение. Аналогично члену манифестаscreenshot . Поле platform элемента снимка экрана поддерживает Windows значения и any . Изображения размером более 1024 x 1024 пикселей игнорируются. Требования к снимку экрана, характерные для доски мини-приложений Windows 11, см. в разделе Требования к изображению снимка экранастатьи Интеграция с элементом выбора мини-приложений. |
Да |
tag |
Строка, используемая для ссылки на мини-приложение в рабочей роли службы PWA. | Да |
template |
Шаблон, используемый для отображения мини-приложения на панели мониторинга мини-приложений операционной системы. Примечание. В настоящее время это свойство является только информационным и не используется. См. ms_ac_template ниже. |
Нет |
ms_ac_template |
URL-адрес пользовательского шаблона адаптивных карточек для отображения мини-приложения на панели мониторинга мини-приложений операционной системы. См . раздел Определение шаблона мини-приложения ниже. | Да |
data |
URL-адрес, где можно найти данные для заполнения шаблона. Если этот URL-адрес существует, этот URL-адрес необходим для возврата допустимого JSON. | Нет |
type |
Тип MIME для данных мини-приложения. | Нет |
auth |
Логическое значение, указывающее, требуется ли для мини-приложения проверка подлинности. | Нет |
update |
Частота обновления мини-приложения (в секундах). Код в рабочей роли службы должен выполнять обновление; мини-приложение не обновляется автоматически. См. статью Доступ к экземплярам мини-приложений во время выполнения. | Нет |
multiple |
Логическое значение, указывающее, следует ли разрешать несколько экземпляров мини-приложения. Значение по умолчанию — true . |
Нет |
Определение шаблона мини-приложения
Чтобы упростить создание и адаптацию мини-приложений к различным панелям мониторинга мини-приложений операционной системы, они отображаются с помощью шаблонов. Существует два типа шаблонов:
- Универсальные шаблоны, определяемые именами с помощью
template
поля. - Пользовательские шаблоны, определяемые url-адресами с помощью поля пользовательского шаблона.
В настоящее время поддерживаются только пользовательские шаблоны адаптивных карточек. Адаптивные карточки — это открытый формат обмена карточками, который можно использовать для обмена содержимым пользовательского интерфейса общим и согласованным способом. См. раздел Общие сведения об адаптивных карточках.
Чтобы определить настраиваемый шаблон адаптивных карточек в Windows 11, используйте ms_ac_template
поле в определении мини-приложения, которое находится в манифесте веб-приложения. Хотя template
в настоящее время не используется, это обязательное поле.
{
...
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player.json",
...
}
Значение ms_ac_template
поля должно быть допустимым URL-адресом файла шаблона.
Ниже приведен пример шаблона адаптивных карточек:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Дополнительные сведения см. в разделе Шаблон адаптивных карточек.
Затем необходимо привязать данные к шаблону.
Привязка данных к шаблону
Шаблон объявляет пользовательский интерфейс мини-приложения. Затем данные заполняют этот пользовательский интерфейс.
Чтобы привязать данные к шаблону, используйте поле в определении data
мини-приложения. В этом поле должен быть задан URL-адрес, возвращающий допустимые данные JSON.
Шаблон, определенный в предыдущем разделе, содержит две переменные: song
и artist
, которые заключены в синтаксис выражения привязки: ${}
. Данные, возвращаемые URL-адресом в определении data
мини-приложения, должны содержать значения для этих переменных.
Ниже приведен пример того, что data
может возвращать URL-адрес:
{
"song": "I Will Always Love You",
"artist": "Whitney Houston"
}
Определение действий мини-приложения
Если вы хотите, чтобы мини-приложение позволяло пользователям выполнять задачи, определите шаблон, поддерживающий действия.
Ниже приведен пример действия, определенного в пользовательском шаблоне адаптивных карточек:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"actions": [
{
"type": "Action.Execute",
"title": "Previous",
"verb": "previous-song"
},
{
"type": "Action.Execute",
"title": "Next",
"verb": "next-song"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Обратите внимание на verb
поле в приведенном выше шаблоне JSON. Он будет использоваться при обработке действий мини-приложения в коде рабочей роли службы. См . раздел Обработка действий мини-приложения.
Доступ к экземплярам мини-приложений во время выполнения
Вы можете получить доступ к мини-приложениям и обновить их из кода рабочей роли службы PWA. Доступ к мини-приложениям во время выполнения полезен в таких случаях, как:
- Отрисовка мини-приложений при установке.
- Обновление мини-приложений в обновлениях рабочей роли службы.
- Обработка действий пользователей в мини-приложениях.
- Обновление мини-приложений при изменении приложения.
Рабочая роль службы имеет доступ к объекту self.widgets
и нескольким событиям мини-приложения, которые вместе составляют API, который используется для реагирования на изменения и доступа к мини-приложениям во время выполнения.
В следующих разделах приведены примеры кода. Справочник по API см. в справочнике по API рабочей роли службы.
Отрисовка мини-приложений при установке
При установке PWA мини-приложения, определенные приложением в своем манифесте, добавляются на панель мониторинга мини-приложений, но еще не установлены. Мини-приложение устанавливается только в том случае, если пользователь хочет добавить его на панели мониторинга.
Когда мини-приложение установлено, оно не отображается автоматически с помощью ms_ac_template
полей и data
определения мини-приложения.
Чтобы отобразить мини-приложение, прослушайте widgetinstall
событие в рабочей роли службы и обновите мини-приложение с помощью widgets.updateByTag
функции :
// Listen to the widgetinstall event.
self.addEventListener("widgetinstall", event => {
// The widget just got installed, render it using renderWidget.
// Pass the event.widget object to the function.
event.waitUntil(renderWidget(event.widget));
});
async function renderWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Обновление мини-приложений в обновлениях рабочей роли службы
При изменении кода рабочей роли службы в PWA браузер обнаруживает это изменение, устанавливает новую рабочую роль службы, а затем активирует рабочую роль службы.
В этом случае важно обновить все экземпляры мини-приложений, которые уже могут быть запущены. Мини-приложения, возможно, были установлены до того, как будет создано событие рабочей роли activate
службы. Чтобы избежать отображения пустых мини-приложений, обновите мини-приложения при возникновении события.activate
// Update the widgets to their initial states
// when the service worker is activated.
self.addEventListener("activate", event => {
event.waitUntil(updateWidgets());
});
async function updateWidgets() {
// Get the widget that match the tag defined in the web app manifest.
const widget = await self.widgets.getByTag("pwamp");
if (!widget) {
return;
}
// Using the widget definition, get the template and data.
const template = await (await fetch(widget.definition.msAcTemplate)).text();
const data = await (await fetch(widget.definition.data)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Обработка действий мини-приложения
Если шаблон мини-приложения содержит действия, пользователи могут выполнять эти действия, нажимая кнопки в отображаемом мини-приложении. Сведения об определении действий в шаблоне см. в разделе Определение действий мини-приложения.
Когда пользователь запускает действие мини-приложения, widgetclick
событие активируется в рабочей роли службы PWA. Чтобы обработать действие пользователя, прослушайте событие:
self.addEventListener('widgetclick', (event) => {
switch (event.action) {
case 'previous-song':
// Application logic to play the previous song...
break;
case 'next-song':
// Application logic to play the next song...
break;
}
});
Для краткости фактический код приложения не отображается в приведенном выше фрагменте кода.
previous-song
При получении действий или next-song
сообщение, вероятно, потребуется отправить в приложение с помощью Client.postMessage, чтобы сообщить приложению, что оно должно начать воспроизведение предыдущих или следующих песен.
Обратите внимание, что action
свойство объекта, widgetEvent
переданного прослушивателю событий выше, соответствует строке, определенной action.verb
в поле шаблона мини-приложения.
Дополнительные сведения о событии widgetclick
и о том, какие сведения можно получить из него, см. в справочнике по API рабочей роли службы ниже.
Обновление мини-приложений при изменении приложения
В предыдущих разделах вы узнали, как обновлять мини-приложения при возникновении определенных событий мини-приложения, действий мини-приложений и обновлений рабочей роли службы. Также может быть полезно обновлять мини-приложения, когда что-то происходит в приложении, когда происходит push-уведомление или периодически.
В этом разделе вы узнаете, как использовать API периодической фоновой синхронизации для периодического обновления мини-приложений. Дополнительные сведения об API периодической фоновой синхронизации см. в статье Использование API периодической фоновой синхронизации для регулярного получения нового содержимого.
В следующем фрагменте кода прослушиватель событий используется для реагирования на различные события жизненного цикла мини-приложения. При обнаружении установки мини-приложения регистрируется периодическая синхронизация, а при обнаружении удаления мини-приложения периодическая синхронизация отменяется.
При возникновении периодических событий синхронизации экземпляры мини-приложений widgets.updateByTag
обновляются с помощью функции .
self.addEventListener("widgetinstall", event => {
event.waitUntil(onWidgetInstall(event.widget));
});
self.addEventListener("widgetuninstall", event => {
event.waitUntil(onWidgetUninstall(event.widget));
});
async function onWidgetInstall(widget) {
// Register a periodic sync, if this wasn't done already.
// We use the same tag for the sync registration and the widget to
// avoid registering several periodic syncs for the same widget.
const tags = await self.registration.periodicSync.getTags();
if (!tags.includes(widget.definition.tag)) {
await self.registration.periodicSync.register(widget.definition.tag, {
minInterval: widget.definition.update
});
}
// And also update the instance.
await updateWidget(widget);
}
async function onWidgetUninstall(widget) {
// On uninstall, unregister the periodic sync.
// If this was the last widget instance, then unregister the periodic sync.
if (widget.instances.length === 1 && "update" in widget.definition) {
await self.registration.periodicSync.unregister(widget.definition.tag);
}
}
// Listen to periodicsync events to update all widget instances
// periodically.
self.addEventListener("periodicsync", async event => {
const widget = await self.widgets.getByTag(event.tag);
if (widget && "update" in widget.definition) {
event.waitUntil(updateWidget(widget));
}
});
async function updateWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Демонстрационная версия приложения
PWAmp — это демонстрационное приложение PWA для музыкального проигрывателя, определяющее мини-приложение. Мини-приложение PWAmp позволяет пользователям визуализировать текущую песню и воспроизводить предыдущие или следующие песни.
Если это еще не сделано, установите WinAppSDK 1.2 и включите режим разработчика в Windows 11.
Перейдите на страницу PWAmp и установите приложение в Windows 11.
Откройте доску мини-приложений Windows 11, нажав клавишу с логотипом Windows + W.
Нажмите кнопку Добавить мини-приложения , чтобы открыть экран параметров мини-приложений , прокрутите страницу мини-приложения PWAmp и добавьте его.
Закройте экран параметров мини-приложений . Мини-проигрыватель PWAmp теперь отображается на доске мини-приложений.
Мини-приложение PWAmp отображает текущую песню и кнопки для воспроизведения предыдущей или следующей песни.
Справочник по API рабочей роли службы
Глобальный объект service worker (или ServiceWorkerGlobalScope) содержит widgets
атрибут, предоставляющий следующие методы на основе Promise:
Метод | Описание | Параметры | Возвращаемое значение |
---|---|---|---|
getByTag(tag) |
Возвращает мини-приложение по тегу. | Тег мини-приложения | Объект Promise, который разрешается в объект мини-приложения , соответствующий тегу или undefined . |
getByInstanceId(id) |
Возвращает мини-приложение по идентификатору экземпляра. | Идентификатор экземпляра мини-приложения | Объект Promise, который разрешается в соответствующий объект мини-приложения, или undefined . |
getByHostId(id) |
Возвращает мини-приложения по идентификатору узла. | Идентификатор узла | Массив объектов мини-приложений , найденных в этом узле. |
matchAll(options) |
Возвращает мини-приложения путем сопоставления параметров. | Объект widgetOptions | Объект Promise, который разрешается в массив объектов мини-приложений , соответствующих options условиям. |
updateByInstanceId(id, payload) |
Обновляет мини-приложение по идентификатору экземпляра. | Идентификатор экземпляра и объект widgetPayload | Обещание, разрешающееся в undefined или Error . |
updateByTag(tag, payload) |
Обновляет мини-приложение по тегу. | Тег мини-приложения и объект widgetPayload | Обещание, разрешающееся в undefined или Error . |
Глобальный объект рабочей роли службы также определяет следующие события:
-
widgetinstall
: срабатывает, когда узел мини-приложения устанавливает мини-приложение. -
widgetuninstall
: срабатывает, когда узел мини-приложения удаляет мини-приложение. -
widgetresume
: срабатывает, когда узел мини-приложения возобновляет отрисовку установленных мини-приложений, что может произойти после того, как узел приостановил отрисовку мини-приложений для сохранения ресурсов. -
widgetclick
: срабатывает, когда пользователь выполняет одно из действий мини-приложения.
Дополнительные сведения об объектах, которые предоставляются с этими событиями, см. в разделах объект widgetEvent и объект widgetClickEvent ниже.
объект widget
Каждое мини-приложение представлено в виде widget
объекта, который содержит следующие свойства:
-
installable
: логическое значение, указывающее, является ли мини-приложение устанавливаемым. -
definition
: объект widgetDefinition. -
instances
: массив объектов widgetInstance , представляющих текущее состояние каждого экземпляра мини-приложения.
Объект widgetOptions
При использовании matchAll(options)
для получения нескольких мини-приложений widgetOptions
объект необходим для фильтрации возвращаемых мини-приложений. Объект widgetOptions
содержит следующие свойства, все из которых являются необязательными:
-
installable
: логическое значение, указывающее, следует ли устанавливать возвращаемые мини-приложения. -
installed
: логическое значение, указывающее, установлены ли возвращенные мини-приложения в узле мини-приложения. -
tag
: строка, используемая для фильтрации возвращаемых мини-приложений по тегу. -
instanceId
: строка, используемая для фильтрации возвращаемых мини-приложений по идентификатору экземпляра. -
hostId
: строка, используемая для фильтрации возвращаемых мини-приложений по идентификатору узла мини-приложения.
объект widgetPayload
При создании или обновлении экземпляра мини-приложения рабочая роль службы должна отправить шаблон и данные, необходимые для заполнения мини-приложения. Шаблон и данные называются полезными данными. Объект widgetPayload
содержит следующие свойства:
-
template
: шаблон в виде строки, используемый для отображения мини-приложения. Это будет строкифицированный КОД JSON шаблона адаптивной карточки. -
data
: данные в виде строки для использования с шаблоном мини-приложения. Эти данные могут быть строкифицированными данными JSON.
Объект widgetInstance
Этот объект представляет данный экземпляр мини-приложения в узле мини-приложения и содержит следующие свойства:
-
id
: внутренняя строка GUID, используемая для ссылки на экземпляр. -
host
: внутренний указатель на узел мини-приложения, на котором установлен этот экземпляр. -
updated
Date
: объект , представляющий время последней отправки данных в экземпляр. -
payload
: объект widgetPayload , представляющий последние полезные данные, отправленные этому экземпляру.
Объект widgetDefinition
Этот объект представляет исходное определение мини-приложения, найденного в файле манифеста PWA. Свойства этого объекта соответствуют свойствам, перечисленным в разделе Определение мини-приложений выше.
объект widgetEvent
Этот объект передается в качестве аргумента прослушивателям событий мини-приложения рабочей роли службы с типом widgetinstall
, widgetuninstall
и widgetresume
.
widgetinstall
Для типов widgetEvent
событий , widgetuninstall
и widgetresume
объект имеет следующие свойства:
Свойство | Описание | Тип |
---|---|---|
widget |
Экземпляр мини-приложения, активировав событие. | виджет |
instanceId |
Идентификатор экземпляра мини-приложения. | String |
hostId |
Идентификатор узла мини-приложения. | String |
объект widgetClickEvent
Этот объект передается в качестве аргумента прослушивателям событий мини-приложения рабочей роли службы типа widgetclick
. Вы можете открыть окно приложения в ответ на widgetclick
событие с помощью clients.openWindow()
.
Объект widgetClickEvent
имеет следующие свойства:
Свойство | Описание | Тип |
---|---|---|
action |
Действие, активировающее событие, как определено в actions.verb полях шаблона мини-приложения. См . раздел Определение действий мини-приложения. |
String |
widget |
Экземпляр мини-приложения, активировав событие. | widgetInstance |
hostId |
Идентификатор узла мини-приложения. | String |
instanceId |
Идентификатор экземпляра мини-приложения. | String |