From fcc66aa328f89437e30f016d8ed8160fa6090828 Mon Sep 17 00:00:00 2001 From: ares Date: Sun, 13 Sep 2026 11:33:42 +0300 Subject: [PATCH] Document local Live Activity release and device validation [skip ci] --- PLAN.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++------ README.md | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/PLAN.md b/PLAN.md index 073b0af..5b6b9aa 100644 --- a/PLAN.md +++ b/PLAN.md @@ -43,8 +43,11 @@ Windows-агент — соседний проект `C:/Users/areso/MusicBridge - [x] Реализованы понятные ошибки сопряжения по кодам сервера, повтор загрузки обложки после 404 и ручной повтор. - [x] Иконка приложения и обновлённый интерфейс подключения/плеера. - [x] Просмотрены снимки 0.4.0: подключение, светлая/тёмная темы, iPhone SE и крупный текст. -- [ ] Проверить новый интерфейс и иконку 0.4.0 на физическом iPhone. -- [ ] Live Activities / Dynamic Island / App Intents — отдельный последующий этап. +- [x] Пользователь подтвердил работу 0.4.0 на iPhone: «всё вроде работает». +- [x] Локальная Live Activity и Dynamic Island: реализация отображения трека в 0.5.0. +- [ ] Проверить Live Activity на экране блокировки и Dynamic Island после подписи через iloader. +- [ ] App Intents: прямые действия из Live Activity и команды Siri. +- [ ] APNs: отдельный проект обновлений при приостановленном приложении, если нужен постоянный актуальный трек в фоне. Ограничения: хранится один доверенный ПК; адрес при смене IP восстанавливается через Bonjour, если доступны объявления того же агента. Новый адрес сохраняется только @@ -93,6 +96,9 @@ Bonjour, если доступны объявления того же агент - `QRScanner.swift`: камера AVFoundation, доступ, сканирование и жизненный цикл. - `DiscoveryStore.swift`: Bonjour, разрешение адресов, TXT и безопасный выбор адреса. - `ConnectionStorage.swift`: доступ к Keychain и подмена хранилища для изолированных тестов жизненного цикла. +- `LiveActivityManager.swift`: запуск, обновление, устаревание и завершение одной локальной Live Activity. +- `Shared/`: ограниченный публичный снимок трека и общие SwiftUI-компоненты карточки. +- `MusicBridgeWidgets/`: расширение WidgetKit, экран блокировки и все представления Dynamic Island. - `MusicBridgeTests/`: XCTest и пример Windows JSON. - `tools/`: генератор проекта, структурные проверки, выбор симулятора для CI. - `.github/workflows/ios.yml`: CI на macOS. @@ -136,12 +142,47 @@ Bonjour, если доступны объявления того же агент 2. **Интерфейс — версия 0.4.0 (build 5).** Добавлены иконка, компактный экран QR, раскрываемые ручные поля, крупная play/pause, процент громкости и меню ПК. Сборка и 23 XCTest прошли; просмотрены темы, компактный экран и крупный текст. - Сценарии QR и ручного подключения сохранены; нужна проверка на телефоне. -3. **Системные интеграции.** Сначала исследовать актуальные ограничения Live Activities, - Dynamic Island, App Intents и локальной связи в фоне; затем реализовать доступные - сценарии. Не имитировать фоновое аудио. Не обещать постоянный WSS при блокировке. + Пользователь подтвердил работу обновления на телефоне перед началом этапа 3. +3. **Системные интеграции — 0.5.0 (build 6).** Локальная Live Activity и Dynamic Island + реализованы; 26 XCTest и Release archive прошли. Карточка показывает последний снимок + с ПК, открывает плеер, помечает устаревшие данные. App Intents и APNs не реализованы. + Не имитировать фоновое аудио. Не обещать постоянный WSS при блокировке. 4. **Несколько сохранённых ПК** — последующее расширение, сейчас сохраняется один. +Изменения третьего этапа — Live Activities 0.5.0: + +- Итоговый `ddd44e8`: [Actions 34747772034](https://github.com/polskikh13/musicbridgeios/actions/runs/34747772034) + — 26 XCTest без отказов, сборка приложения и WidgetKit-расширения, успешный Release archive. + IPA скачана в `build/iPhone-0.5.0/MusicBridge-iPhone.ipa`; проверены оба ARM64 + iPhoneOS исполняемых файла, структура `.appex`, версии и NSSupportsLiveActivities. + Светлый/тёмный предпросмотр карточки просмотрен: текст и отметка устаревания читаемы. + Установка/регистрация Live Activity на физическом iPhone остаются ручной проверкой. +- ActivityKit без push: старт только кнопкой пользователя при активном приложении + и медиасессии. Восстанавливается существующая активность, дубли завершаются; + после удаления пользователем автоматического пересоздания нет. +- WidgetKit-расширение встроено в приложение. В attributes/content нет адреса ПК, + токена, fingerprint или обложки; только публичные данные трека, ограниченные + по UTF-8 (по 256 байт для названия и исполнителя). +- Обычные позиции объединяются до одного обновления в пять секунд; смена трека, + длительности или состояния воспроизведения отправляется сразу. Прогресс статический, + соответствует последнему снимку. В фоне/без сети помечается устаревшим; + `staleDate` через 15 секунд страхует внезапную остановку приложения. +- Нет медиасессии, отзыв доступа, «Забыть компьютер» или ручное выключение — завершение. + Нажатие карточки открывает `musicbridge://player`, не попадает в импорт QR. +- Новые XCTest: позиция относительно startSeconds, нулевая длительность/пауза, + чрезмерные Unicode-метаданные и размер Codable payload. Проверка IPA требует + встроенную ARM64 iPhoneOS `.appex`, совпадающие версии и поддержку Live Activities. +- CI-предпросмотр общей разметки карточки проверяет светлую/тёмную темы и устаревшие + данные. Это не проверка системной регистрации ActivityKit/Island. На физическом + iPhone проверить старт, блокировку, раскрытие Island, переход в плеер, возврат, + удаление карточки, отсутствие автопересоздания, окончание сессии и отзыв доступа. +- Следующие отдельные задачи: LiveActivityIntent с безопасным выполнением команды + (проверить доступность Keychain/локальной сети при блокировке); Siri; APNs, если + требуются актуальные данные после приостановки приложения. Постоянный WSS в фоне + не реализован и не обещается. Windows-протокол не менялся. +- Основание: [Apple ActivityKit](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities) + и [WidgetKit extension](https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension). + Изменения второго этапа: - Итоговый `aa0b0f0`: [Actions 34746477145](https://github.com/polskikh13/musicbridgeios/actions/runs/34746477145) diff --git a/README.md b/README.md index 73b341c..a4b011e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ **Статус:** пользователь подтвердил установку через iloader, рабочий пилот с Windows-агентом и подключение по QR. В 0.4.0 добавлены иконка и обновлённый -интерфейс. Автоматические проверки включают 23 XCTest и Release archive; +интерфейс, в 0.5.0 — локальная Live Activity и Dynamic Island. CI собирает +приложение и расширение WidgetKit, выполняет XCTest и Release archive; полная проверка устойчивости на физических устройствах остаётся в `PLAN.md`. ## Сборка на Mac @@ -67,8 +68,8 @@ Apple ID и сертификаты для этой проверки не тре ## Установка на iPhone через Sideloadly Пользователь также подтвердил установку через iloader. Для повторной установки -с новым интерфейсом используйте версию **0.4.0 (build 5)**: -`build/iPhone-0.4.0/MusicBridge-iPhone.ipa`. Выберите этот файл в iloader и +с Live Activity используйте версию **0.5.0 (build 6)**: +`build/iPhone-0.5.0/MusicBridge-iPhone.ipa`. Выберите этот файл в iloader и подпишите тем же Apple Account, которым установлена первая версия. В 0.4.0 добавлены иконка, карточка QR, раскрываемые ручные поля, крупная @@ -105,6 +106,35 @@ Sideloadly (в том числе его функцией автоматичес [Sideloadly FAQ](https://sideloadly.io/faq) · [Apple: режим разработчика](https://developer.apple.com/documentation/Xcode/enabling-developer-mode-on-a-device) +## Live Activity и Dynamic Island + +После подключения к ПК и появления трека нажмите под плеером +«Показать на экране блокировки». Та же карточка появится в Dynamic Island +на моделях, где он доступен. Долгое нажатие на Island раскрывает представление; +нажатие на карточку или «Открыть плеер» возвращает в приложение. +Кнопка «Убрать с экрана блокировки» завершает активность. Она также завершается, +когда ПК сообщает об отсутствии медиасессии, доступ отозван или компьютер забыт. +Удалённая пользователем карточка не создаётся снова автоматически. + +Это **последний снимок состояния ПК**: название, исполнитель, состояние и прогресс. +В обычном режиме позиция обновляется не чаще раза в пять секунд; смена трека +и play/pause отправляются сразу. Прогресс не выдумывает движение без связи с ПК. +При уходе приложения в фон или потере связи отображается отметка устаревших данных; +резервный `staleDate` — 15 секунд, если приложение было внезапно остановлено. +Для обновления нажмите карточку. Прямых кнопок управления внутри неё пока нет. + +Live Activity не поддерживает постоянный сетевой поток сама по себе. Для обновления +при приостановленном приложении нужен отдельный механизм ActivityKit push через +APNs. В этой версии нет push-токенов, сервера APNs, фонового аудио и App Intents. +[Ограничения и жизненный цикл ActivityKit](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities). + +В IPA включено расширение `MusicBridgeWidgets.appex`; при установке iloader должен +сохранить и подписать его вместе с приложением. Если Live Activity не появилась, +проверьте её разрешение в настройках MusicBridge и наличие расширения в логе установки. +Автоматические снимки `live-card-*-screen.png` показывают общую SwiftUI-разметку +карточки в Debug-предпросмотре: это не доказательство её регистрации на реальном +экране блокировки или системного отображения Dynamic Island. + ## Источники - [Apple: проверка доверия сервера](https://developer.apple.com/documentation/Foundation/performing-manual-server-trust-authentication)