Document interactive activity release and NowPlaying research [skip ci]
This commit is contained in:
@@ -46,7 +46,10 @@ Windows-агент — соседний проект `C:/Users/areso/MusicBridge
|
|||||||
- [x] Пользователь подтвердил работу 0.4.0 на iPhone: «всё вроде работает».
|
- [x] Пользователь подтвердил работу 0.4.0 на iPhone: «всё вроде работает».
|
||||||
- [x] Локальная Live Activity и Dynamic Island: реализация отображения трека в 0.5.0.
|
- [x] Локальная Live Activity и Dynamic Island: реализация отображения трека в 0.5.0.
|
||||||
- [ ] Проверить Live Activity на экране блокировки и Dynamic Island после подписи через iloader.
|
- [ ] Проверить Live Activity на экране блокировки и Dynamic Island после подписи через iloader.
|
||||||
- [ ] App Intents: прямые действия из Live Activity и команды Siri.
|
- [x] LiveActivityIntent: предыдущий/следующий трек, play/pause и обновление — 0.6.0.
|
||||||
|
- [ ] Проверить команды из Live Activity/Island при блокировке на физическом iPhone.
|
||||||
|
- [ ] Команды Siri.
|
||||||
|
- [ ] NowPlaying RemoteMediaSession (iOS 27+): перейти на SDK 27, добавить remote-media extension и проверить системный Control Center.
|
||||||
- [ ] APNs: отдельный проект обновлений при приостановленном приложении, если нужен постоянный актуальный трек в фоне.
|
- [ ] APNs: отдельный проект обновлений при приостановленном приложении, если нужен постоянный актуальный трек в фоне.
|
||||||
|
|
||||||
Ограничения: хранится один доверенный ПК; адрес при смене IP восстанавливается через
|
Ограничения: хранится один доверенный ПК; адрес при смене IP восстанавливается через
|
||||||
@@ -143,13 +146,51 @@ Bonjour, если доступны объявления того же агент
|
|||||||
раскрываемые ручные поля, крупная play/pause, процент громкости и меню ПК.
|
раскрываемые ручные поля, крупная play/pause, процент громкости и меню ПК.
|
||||||
Сборка и 23 XCTest прошли; просмотрены темы, компактный экран и крупный текст.
|
Сборка и 23 XCTest прошли; просмотрены темы, компактный экран и крупный текст.
|
||||||
Пользователь подтвердил работу обновления на телефоне перед началом этапа 3.
|
Пользователь подтвердил работу обновления на телефоне перед началом этапа 3.
|
||||||
3. **Системные интеграции — 0.5.0 (build 6).** Локальная Live Activity и Dynamic Island
|
3. **Системные интеграции — 0.6.0 (build 7).** Добавлены прямые действия LiveActivityIntent.
|
||||||
реализованы; 26 XCTest и Release archive прошли. Карточка показывает последний снимок
|
Убрана ошибка устаревания при обычном сворачивании; каждое нажатие перечитывает ПК.
|
||||||
с ПК, открывает плеер, помечает устаревшие данные. App Intents и APNs не реализованы.
|
32 XCTest и Release archive прошли. APNs и встроенный системный музыкальный пульт ещё не реализованы.
|
||||||
Не имитировать фоновое аудио. Не обещать постоянный WSS при блокировке.
|
Не имитировать фоновое аудио. Не обещать постоянный WSS при блокировке.
|
||||||
4. **Несколько сохранённых ПК** — последующее расширение, сейчас сохраняется один.
|
4. **Несколько сохранённых ПК** — последующее расширение, сейчас сохраняется один.
|
||||||
|
|
||||||
Изменения третьего этапа — Live Activities 0.5.0:
|
Продолжение третьего этапа — 0.6.0:
|
||||||
|
|
||||||
|
- Итоговый `43c78b2`: [Actions 34748340408](https://github.com/polskikh13/musicbridgeios/actions/runs/34748340408)
|
||||||
|
— 32 XCTest без отказов, успешный Release archive. IPA 0.6.0 (7) скачана в
|
||||||
|
`build/iPhone-0.6.0/MusicBridge-iPhone.ipa`; проверены ARM64 iPhoneOS приложения
|
||||||
|
и расширения, версии, метаданные интентов. Просмотрены светлая и тёмная карточки.
|
||||||
|
Работа системного запуска LiveActivityIntent и Keychain после блокировки требует
|
||||||
|
проверки на телефоне: обновить IPA, выключить/включить карточку, заблокировать,
|
||||||
|
проверить next/previous/toggle/refresh; затем повторить после перезагрузки и первого unlock.
|
||||||
|
- Пользователь сообщил, что карточка постоянно пишет об устаревших данных.
|
||||||
|
Причина: `PlayerStore.stop()` вызывал `unavailable()` при каждом уходе в фон.
|
||||||
|
Удалён этот вызов; реальные сетевые отказы продолжают отмечаться отдельно.
|
||||||
|
Карточка показывает время последнего снимка и отдельные ошибки запросов.
|
||||||
|
- Shared `MusicControlIntent` соответствует LiveActivityIntent. WidgetKit содержит
|
||||||
|
определение интента, выполнение сети компилируется только в основной app target;
|
||||||
|
iOS запускает процесс приложения без открытия UI. На компактном/минимальном Island
|
||||||
|
кнопок нет: нужно раскрыть долгим нажатием. Кнопки не отключаются из-за старого снимка.
|
||||||
|
- `LiveActivityCommands`: одно действие одновременно, проверка живой Activity и связи
|
||||||
|
её ID с fingerprint текущего сопряжения. После чтения состояния повторно проверяется
|
||||||
|
актуальность карточки, затем проверяются capabilities и отправляется максимум одна
|
||||||
|
команда. Refresh вообще не отправляет команду. Повторов команд нет.
|
||||||
|
- После успеха перечитывается трек и обновляется Activity. 401 завершает её;
|
||||||
|
неизвестный результат и неудача чтения после успеха имеют разные сообщения.
|
||||||
|
Нет бесконечного WSS/Bonjour в фоне; после смены IP сначала открыть приложение.
|
||||||
|
- Keychain: AfterFirstUnlockThisDeviceOnly вместо WhenUnlockedThisDeviceOnly,
|
||||||
|
чтобы команды работали при заблокированном iPhone. Существующий токен мигрирует
|
||||||
|
при повторном включении карточки. Он не покидает Keychain и не попадает в payload.
|
||||||
|
В UserDefaults сохраняется только соответствие ID активности и публичного pin.
|
||||||
|
После обновления с 0.5.0 карточку выключить и включить заново в приложении.
|
||||||
|
- HTTPS-тесты проверяют одну отправку next и новый трек, refresh без команды,
|
||||||
|
закрытую карточку, неподдерживаемую команду, отсутствие повторов отказавшей команды,
|
||||||
|
ошибку чтения после успешной команды. Физический запуск интента проверяется отдельно.
|
||||||
|
- Ответ на вопрос пользователя о встроенном музыкальном центре: официальный
|
||||||
|
[NowPlaying RemoteMediaSession](https://developer.apple.com/documentation/nowplaying/publishing-remote-media-sessions)
|
||||||
|
предназначен для внешнего воспроизведения. Metadata Apple указывает iOS 27.0.
|
||||||
|
Текущий runner собирает Xcode 16.4: следующий этап — SDK/Xcode 27 и отдельное
|
||||||
|
`com.apple.nowplaying.remote-media` расширение. Интеграция ещё не реализована.
|
||||||
|
|
||||||
|
История третьего этапа — Live Activities 0.5.0 (поведение фона изменено в 0.6.0):
|
||||||
|
|
||||||
- Итоговый `ddd44e8`: [Actions 34747772034](https://github.com/polskikh13/musicbridgeios/actions/runs/34747772034)
|
- Итоговый `ddd44e8`: [Actions 34747772034](https://github.com/polskikh13/musicbridgeios/actions/runs/34747772034)
|
||||||
— 26 XCTest без отказов, сборка приложения и WidgetKit-расширения, успешный Release archive.
|
— 26 XCTest без отказов, сборка приложения и WidgetKit-расширения, успешный Release archive.
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ Apple ID и сертификаты для этой проверки не тре
|
|||||||
## Установка на iPhone через Sideloadly
|
## Установка на iPhone через Sideloadly
|
||||||
|
|
||||||
Пользователь также подтвердил установку через iloader. Для повторной установки
|
Пользователь также подтвердил установку через iloader. Для повторной установки
|
||||||
с Live Activity используйте версию **0.5.0 (build 6)**:
|
с Live Activity используйте версию **0.6.0 (build 7)**:
|
||||||
`build/iPhone-0.5.0/MusicBridge-iPhone.ipa`. Выберите этот файл в iloader и
|
`build/iPhone-0.6.0/MusicBridge-iPhone.ipa`. Выберите этот файл в iloader и
|
||||||
подпишите тем же Apple Account, которым установлена первая версия.
|
подпишите тем же Apple Account, которым установлена первая версия.
|
||||||
|
|
||||||
В 0.4.0 добавлены иконка, карточка QR, раскрываемые ручные поля, крупная
|
В 0.4.0 добавлены иконка, карточка QR, раскрываемые ручные поля, крупная
|
||||||
@@ -106,34 +106,46 @@ Sideloadly (в том числе его функцией автоматичес
|
|||||||
[Sideloadly FAQ](https://sideloadly.io/faq) ·
|
[Sideloadly FAQ](https://sideloadly.io/faq) ·
|
||||||
[Apple: режим разработчика](https://developer.apple.com/documentation/Xcode/enabling-developer-mode-on-a-device)
|
[Apple: режим разработчика](https://developer.apple.com/documentation/Xcode/enabling-developer-mode-on-a-device)
|
||||||
|
|
||||||
## Live Activity и Dynamic Island
|
## Live Activity и Dynamic Island — 0.6.0
|
||||||
|
|
||||||
После подключения к ПК и появления трека нажмите под плеером
|
После обновления с 0.5.0 уберите старую карточку кнопкой в приложении и нажмите
|
||||||
«Показать на экране блокировки». Та же карточка появится в Dynamic Island
|
«Показать на экране блокировки» заново. Это связывает кнопки с текущим сопряжением
|
||||||
на моделях, где он доступен. Долгое нажатие на Island раскрывает представление;
|
и переводит запись Keychain в режим доступа после первого разблокирования.
|
||||||
нажатие на карточку или «Открыть плеер» возвращает в приложение.
|
Токен остаётся только на этом устройстве, не копируется в виджет или UserDefaults.
|
||||||
Кнопка «Убрать с экрана блокировки» завершает активность. Она также завершается,
|
|
||||||
когда ПК сообщает об отсутствии медиасессии, доступ отозван или компьютер забыт.
|
|
||||||
Удалённая пользователем карточка не создаётся снова автоматически.
|
|
||||||
|
|
||||||
Это **последний снимок состояния ПК**: название, исполнитель, состояние и прогресс.
|
На экране блокировки и в развёрнутом Dynamic Island доступны предыдущий трек,
|
||||||
В обычном режиме позиция обновляется не чаще раза в пять секунд; смена трека
|
play/pause, следующий трек и обновление. Компактный Island открывает приложение;
|
||||||
и play/pause отправляются сразу. Прогресс не выдумывает движение без связи с ПК.
|
для кнопок удерживайте Island. Каждое действие выполняет отдельные HTTPS-запросы
|
||||||
При уходе приложения в фон или потере связи отображается отметка устаревших данных;
|
с прежней проверкой сертификата. Оно работает через LiveActivityIntent в процессе
|
||||||
резервный `staleDate` — 15 секунд, если приложение было внезапно остановлено.
|
приложения, без открытия интерфейса; постоянного сетевого потока в фоне нет.
|
||||||
Для обновления нажмите карточку. Прямых кнопок управления внутри неё пока нет.
|
|
||||||
|
|
||||||
Live Activity не поддерживает постоянный сетевой поток сама по себе. Для обновления
|
Перед командой считываются возможности плеера, затем команда отправляется один раз
|
||||||
при приостановленном приложении нужен отдельный механизм ActivityKit push через
|
и перечитывается состояние. Повторы команд отключены; при неизвестном результате
|
||||||
APNs. В этой версии нет push-токенов, сервера APNs, фонового аудио и App Intents.
|
сначала используйте обновление. Одновременно выполняется одно действие карточки.
|
||||||
[Ограничения и жизненный цикл ActivityKit](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities).
|
После закрытия карточки или удаления её связи с ПК новые команды не отправляются.
|
||||||
|
Для нового адреса ПК сначала откройте приложение: Bonjour-перенос адреса остаётся
|
||||||
|
в основном приложении. При отзыве доступа карточка завершается.
|
||||||
|
|
||||||
В IPA включено расширение `MusicBridgeWidgets.appex`; при установке iloader должен
|
При обычном сворачивании показывается время последнего обновления, а не ошибка
|
||||||
сохранить и подписать его вместе с приложением. Если Live Activity не появилась,
|
«Данные устарели». Прогресс соответствует этому снимку. Реальная ошибка сети или
|
||||||
проверьте её разрешение в настройках MusicBridge и наличие расширения в логе установки.
|
команды выводится на карточке. Изменения, сделанные непосредственно на ПК, при
|
||||||
Автоматические снимки `live-card-*-screen.png` показывают общую SwiftUI-разметку
|
приостановленном приложении не появятся сами: нажмите обновление или откройте плеер.
|
||||||
карточки в Debug-предпросмотре: это не доказательство её регистрации на реальном
|
Для постоянных фоновых обновлений остаётся отдельная задача APNs.
|
||||||
экране блокировки или системного отображения Dynamic Island.
|
|
||||||
|
В IPA есть расширение `MusicBridgeWidgets.appex`: iloader должен сохранить и подписать
|
||||||
|
его вместе с приложением. Проверка работы интентов в заблокированном состоянии и
|
||||||
|
системного отображения Island выполняется на iPhone; CI проверяет сборку, сетевую
|
||||||
|
логику команд и разметку. После перезагрузки сначала один раз разблокируйте iPhone.
|
||||||
|
|
||||||
|
### Встроенный музыкальный пульт iOS
|
||||||
|
|
||||||
|
Apple предлагает `RemoteMediaSession` в новом NowPlaying framework (iOS 27+)
|
||||||
|
для отображения музыки внешнего устройства на экране блокировки и в Control Center.
|
||||||
|
Это подходит архитектуре MusicBridge. Нужны SDK/Xcode 27 и отдельное расширение
|
||||||
|
`com.apple.nowplaying.remote-media`; текущая сборка использует Xcode 16.4.
|
||||||
|
Эта интеграция исследована, но ещё не реализована. Для фоновых обновлений удалённых
|
||||||
|
сессий Apple также предоставляет push-механизм.
|
||||||
|
[Документация remote media sessions](https://developer.apple.com/documentation/nowplaying/publishing-remote-media-sessions).
|
||||||
|
|
||||||
## Источники
|
## Источники
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user