2026-09-10 09:11:55 +03:00
|
|
|
|
# MusicBridge для iPhone
|
|
|
|
|
|
|
|
|
|
|
|
Нативный пульт на SwiftUI для MusicBridge.Agent на Windows. Звук играет на ПК.
|
|
|
|
|
|
Минимальная версия iOS — 17. Зависимостей Swift Package/CocoaPods нет.
|
|
|
|
|
|
|
2026-09-13 11:02:44 +03:00
|
|
|
|
## Возможности
|
2026-09-10 09:11:55 +03:00
|
|
|
|
|
|
|
|
|
|
- Сопряжение по HTTPS-адресу домашнего ПК, SHA-256 сертификата и коду.
|
2026-09-13 11:02:44 +03:00
|
|
|
|
- Сканирование QR агента камерой, открытие `musicbridge://pair?data=…` и ручной ввод.
|
|
|
|
|
|
- Поиск компьютера через Bonjour и восстановление адреса доверенного ПК.
|
2026-09-10 09:11:55 +03:00
|
|
|
|
- Проверка закреплённого DER-сертификата до отправки кода и при следующих соединениях.
|
|
|
|
|
|
- Хранение адреса, отпечатка и токена в Keychain только на этом устройстве.
|
|
|
|
|
|
- Название, исполнитель, обложка, позиция, play/pause, следующий/предыдущий трек,
|
|
|
|
|
|
перемотка ползунком, системная громкость и mute.
|
|
|
|
|
|
- WSS-состояние, переподключение с задержкой, остановка сети в фоне и восстановление
|
|
|
|
|
|
при возврате. Команды автоматически не повторяются.
|
|
|
|
|
|
|
2026-09-13 11:02:44 +03:00
|
|
|
|
**Статус:** пользователь подтвердил установку через iloader, рабочий пилот с
|
|
|
|
|
|
Windows-агентом и подключение по QR. В 0.4.0 добавлены иконка и обновлённый
|
2026-09-13 11:33:42 +03:00
|
|
|
|
интерфейс, в 0.5.0 — локальная Live Activity и Dynamic Island. CI собирает
|
|
|
|
|
|
приложение и расширение WidgetKit, выполняет XCTest и Release archive;
|
2026-09-13 11:02:44 +03:00
|
|
|
|
полная проверка устойчивости на физических устройствах остаётся в `PLAN.md`.
|
2026-09-10 09:11:55 +03:00
|
|
|
|
|
|
|
|
|
|
## Сборка на Mac
|
|
|
|
|
|
|
|
|
|
|
|
1. Открыть `MusicBridge.xcodeproj` в Xcode 16 или новее.
|
|
|
|
|
|
2. Выбрать схему MusicBridge и симулятор iPhone. Run запускает приложение,
|
|
|
|
|
|
Test выполняет `MusicBridgeTests`.
|
|
|
|
|
|
3. Для физического iPhone выбрать свою Team в Signing & Capabilities. Сертификаты
|
|
|
|
|
|
и provisioning profiles не хранить в Git. Bundle ID при необходимости сменить
|
|
|
|
|
|
в `tools/generate_project.py`, затем повторно сгенерировать проект.
|
|
|
|
|
|
4. На ПК запустить агент с `--tray --lan`, открыть сопряжение. В приложении
|
|
|
|
|
|
ввести адрес, отпечаток и код с экрана ПК. Разрешить доступ к локальной сети.
|
|
|
|
|
|
|
|
|
|
|
|
Проект уже сгенерирован и включён в Git; Python для обычной сборки не требуется.
|
|
|
|
|
|
После добавления Swift-файлов выполнить `python3 tools/generate_project.py`.
|
|
|
|
|
|
Структурная проверка на Windows/macOS: `python tools/validate_project.py`.
|
|
|
|
|
|
|
|
|
|
|
|
## GitHub Actions
|
|
|
|
|
|
|
|
|
|
|
|
`.github/workflows/ios.yml` собирает приложение и выполняет XCTest на `macos-15`
|
|
|
|
|
|
при push в main, pull request или ручном запуске. Сохраняет лог, `.xcresult`
|
|
|
|
|
|
и ZIP приложения **для симулятора**, который нельзя установить на физический iPhone.
|
2026-09-10 09:22:14 +03:00
|
|
|
|
Apple ID и сертификаты для этой проверки не требуются. GitHub remote подключён:
|
|
|
|
|
|
`git@github.com:polskikh13/musicbridgeios.git`. GitHub CLI установлен и авторизован;
|
|
|
|
|
|
результаты доступны через `gh run list --repo polskikh13/musicbridgeios` и
|
|
|
|
|
|
`gh run view <run-id> --repo polskikh13/musicbridgeios --log-failed`.
|
2026-09-10 09:11:55 +03:00
|
|
|
|
|
|
|
|
|
|
Основной origin: `ssh://git@dev.yukinoki.ru:2222/musicbridge/ios.git`.
|
2026-09-10 09:22:14 +03:00
|
|
|
|
Отдельный remote `github` используется для Actions, основной origin сохранён.
|
|
|
|
|
|
Отправка: `git push origin main` и `git push github main`.
|
|
|
|
|
|
Код автоматически не зеркалируется между серверами. Локальная регрессионная
|
|
|
|
|
|
проверка выбора симулятора: `python tools/test_select_simulator.py`.
|
2026-09-10 09:11:55 +03:00
|
|
|
|
|
2026-09-12 15:55:33 +03:00
|
|
|
|
## Подключение через QR и поиск ПК
|
|
|
|
|
|
|
2026-09-13 11:02:44 +03:00
|
|
|
|
Откройте окно сопряжения в Windows-агенте (`--tray --lan`),
|
|
|
|
|
|
на iPhone нажмите «Сканировать QR» и разрешите камеру. После сканирования
|
2026-09-12 15:55:33 +03:00
|
|
|
|
нажмите «Подключить компьютер». Ссылки `musicbridge://` также открываются
|
|
|
|
|
|
из стандартной камеры. Приглашение должно быть свежим.
|
|
|
|
|
|
|
2026-09-13 11:02:44 +03:00
|
|
|
|
В разделе «Найти компьютер» можно выбрать найденный адрес. Сверьте **весь**
|
2026-09-12 15:55:33 +03:00
|
|
|
|
предложенный отпечаток с экраном ПК и введите код. Если поиск не работает,
|
|
|
|
|
|
проверьте доступ к локальной сети в настройках MusicBridge; ручной ввод остаётся.
|
|
|
|
|
|
При смене адреса уже доверенного ПК приложение пробует объявления с тем же
|
|
|
|
|
|
отпечатком и сохраняет новый адрес только после успешной TLS-проверки и авторизации.
|
|
|
|
|
|
|
2026-09-10 20:09:18 +03:00
|
|
|
|
## Установка на iPhone через Sideloadly
|
|
|
|
|
|
|
2026-09-12 15:38:43 +03:00
|
|
|
|
Пользователь также подтвердил установку через iloader. Для повторной установки
|
2026-09-13 11:47:51 +03:00
|
|
|
|
с Live Activity используйте версию **0.6.0 (build 7)**:
|
|
|
|
|
|
`build/iPhone-0.6.0/MusicBridge-iPhone.ipa`. Выберите этот файл в iloader и
|
2026-09-12 15:38:43 +03:00
|
|
|
|
подпишите тем же Apple Account, которым установлена первая версия.
|
|
|
|
|
|
|
2026-09-13 11:02:44 +03:00
|
|
|
|
В 0.4.0 добавлены иконка, карточка QR, раскрываемые ручные поля, крупная
|
|
|
|
|
|
play/pause, процент громкости и меню компьютера. Размер обложки зависит от
|
|
|
|
|
|
доступной высоты окна; при крупном системном шрифте экран прокручивается.
|
|
|
|
|
|
|
|
|
|
|
|
Начиная с 0.3.0 обложка повторно загружается после временного сбоя, а после четырёх
|
2026-09-12 21:46:04 +03:00
|
|
|
|
неудачных попыток доступен ручной повтор. Отозванный доступ требует нового
|
|
|
|
|
|
сопряжения; автоматические попытки прекращаются. Если свернуть приложение во
|
|
|
|
|
|
время сопряжения, повторите его со свежим QR (удалив созданную запись на ПК,
|
|
|
|
|
|
если она уже успела появиться). При неизвестном результате команды проверьте
|
|
|
|
|
|
плеер перед повтором: приложение не повторяет команды автоматически.
|
|
|
|
|
|
|
2026-09-10 20:09:18 +03:00
|
|
|
|
Workflow также выполняет Release archive для `generic/platform=iOS` и создаёт
|
|
|
|
|
|
`MusicBridge-iPhone.ipa` в артефакте `MusicBridge-iPhone`. Это ARM64-сборка для
|
|
|
|
|
|
iOS 17+, без подписи. Подпись создаёт Sideloadly на вашем ПК с вашим Apple Account.
|
|
|
|
|
|
В Actions не передаются пароль Apple, сертификаты или provisioning profile.
|
|
|
|
|
|
|
|
|
|
|
|
1. Скачать артефакт MusicBridge-iPhone из успешного запуска Actions и распаковать
|
|
|
|
|
|
ZIP артефакта, чтобы получить файл `.ipa`.
|
|
|
|
|
|
2. Подключить разблокированный iPhone к Windows кабелем; подтвердить доверие ПК.
|
|
|
|
|
|
3. Открыть Sideloadly, выбрать свой iPhone и файл `MusicBridge-iPhone.ipa`.
|
|
|
|
|
|
4. Войти в Apple Account непосредственно в Sideloadly, нажать Start, дождаться Done.
|
|
|
|
|
|
5. Если iPhone сообщает о недоверенном разработчике, открыть «Настройки → Основные
|
|
|
|
|
|
→ VPN и управление устройством», выбрать свой аккаунт и подтвердить доверие.
|
|
|
|
|
|
6. Для запуска включить «Настройки → Конфиденциальность и безопасность → Режим
|
|
|
|
|
|
разработчика», затем выполнить предложенные iPhone перезагрузку и подтверждение.
|
|
|
|
|
|
7. Открыть MusicBridge, разрешить локальную сеть и выполнить сопряжение с ПК.
|
|
|
|
|
|
|
|
|
|
|
|
На бесплатном Apple Account подпись действует 7 дней; её нужно обновлять через
|
|
|
|
|
|
Sideloadly (в том числе его функцией автоматического обновления).
|
|
|
|
|
|
Файл MusicBridge-simulator.zip для установки на телефон не подходит.
|
|
|
|
|
|
|
|
|
|
|
|
[Sideloadly FAQ](https://sideloadly.io/faq) ·
|
|
|
|
|
|
[Apple: режим разработчика](https://developer.apple.com/documentation/Xcode/enabling-developer-mode-on-a-device)
|
|
|
|
|
|
|
2026-09-13 11:47:51 +03:00
|
|
|
|
## Live Activity и Dynamic Island — 0.6.0
|
|
|
|
|
|
|
|
|
|
|
|
После обновления с 0.5.0 уберите старую карточку кнопкой в приложении и нажмите
|
|
|
|
|
|
«Показать на экране блокировки» заново. Это связывает кнопки с текущим сопряжением
|
|
|
|
|
|
и переводит запись Keychain в режим доступа после первого разблокирования.
|
|
|
|
|
|
Токен остаётся только на этом устройстве, не копируется в виджет или UserDefaults.
|
|
|
|
|
|
|
|
|
|
|
|
На экране блокировки и в развёрнутом Dynamic Island доступны предыдущий трек,
|
|
|
|
|
|
play/pause, следующий трек и обновление. Компактный Island открывает приложение;
|
|
|
|
|
|
для кнопок удерживайте Island. Каждое действие выполняет отдельные HTTPS-запросы
|
|
|
|
|
|
с прежней проверкой сертификата. Оно работает через LiveActivityIntent в процессе
|
|
|
|
|
|
приложения, без открытия интерфейса; постоянного сетевого потока в фоне нет.
|
|
|
|
|
|
|
|
|
|
|
|
Перед командой считываются возможности плеера, затем команда отправляется один раз
|
|
|
|
|
|
и перечитывается состояние. Повторы команд отключены; при неизвестном результате
|
|
|
|
|
|
сначала используйте обновление. Одновременно выполняется одно действие карточки.
|
|
|
|
|
|
После закрытия карточки или удаления её связи с ПК новые команды не отправляются.
|
|
|
|
|
|
Для нового адреса ПК сначала откройте приложение: Bonjour-перенос адреса остаётся
|
|
|
|
|
|
в основном приложении. При отзыве доступа карточка завершается.
|
|
|
|
|
|
|
|
|
|
|
|
При обычном сворачивании показывается время последнего обновления, а не ошибка
|
|
|
|
|
|
«Данные устарели». Прогресс соответствует этому снимку. Реальная ошибка сети или
|
|
|
|
|
|
команды выводится на карточке. Изменения, сделанные непосредственно на ПК, при
|
|
|
|
|
|
приостановленном приложении не появятся сами: нажмите обновление или откройте плеер.
|
|
|
|
|
|
Для постоянных фоновых обновлений остаётся отдельная задача APNs.
|
|
|
|
|
|
|
|
|
|
|
|
В 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).
|
2026-09-13 11:33:42 +03:00
|
|
|
|
|
2026-09-10 09:11:55 +03:00
|
|
|
|
## Источники
|
|
|
|
|
|
|
|
|
|
|
|
- [Apple: проверка доверия сервера](https://developer.apple.com/documentation/Foundation/performing-manual-server-trust-authentication)
|
|
|
|
|
|
- [Apple: доступ к локальной сети](https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy)
|
|
|
|
|
|
- [GitHub: macOS runners](https://docs.github.com/en/actions/reference/runners/github-hosted-runners)
|
|
|
|
|
|
- [GitHub: лимиты и оплата Actions](https://docs.github.com/en/billing/concepts/product-billing/github-actions)
|
|
|
|
|
|
|
|
|
|
|
|
План и ограничения — в `PLAN.md`. Копия протокола агента — в `PROTOCOL.md`.
|