Deep-Links
Приложение регистрирует одну или несколько URL-схем (см. CFBundleURLTypes в
AppInfo.plist). Основная схема для шаблонов в доке и внутренних QR —
sharx://. Полный перечень зарегистрированных схем, в том числе
совместимых alias, смотрите в приложении: Настройки → Поддерживаемые
URL-схемы (можно копировать шаблоны). Список в коде: DeepLinkParser.supportedSchemes.
Обработчик: RootTabView.handleDeepLink(_:), парсер: DeepLinkParser.
Ниже в примерах используется
sharx://. Любая зарегистрированная схема из этого списка ведёт себя так же: сверяются хост, путь и query; ниже задокументированы только эти пути.
URL-схемы (хедер)
| Схема | Роль в доке и QR |
|---|---|
sharx:// |
Основная — в этой документации и в QR внутри приложения. |
Остальные схемы, которые приложение зарегистрировало, используют те же
формы путей и query; в тексте везде sharx:// для краткости.
Поддерживаемые типы ссылок (обзор)
| Назначение | URL header (схема + путь) | Тело: query или path | Подробнее |
|---|---|---|---|
| Добавить подписку | sharx:// + путь add |
Query: url (обязателен), name (опционально) |
Добавление подписки |
| Импорт routing-профиля | sharx:// + путь routing/add/ |
Хвост пути после add/: Base64 JSON RoutingProfile (см. routing-profile-schema.md) |
Импорт профиля маршрутизации |
Любые другие комбинации host/path игнорируются (без сообщения об ошибке).
Добавление подписки
Хедер, body и структура (раздельно)
| Содержимое | |
|---|---|
| Header | sharx://add — в пути литерал add (действие «добавить подписку»). |
| Body (строка query) | url=<URL_подписки>&name=<имя>. URL подписки обязателен и должен стать валидным URL после percent-decode. name — предзаполнение формы. |
Полный вид URL
sharx://add?url=<URL_подписки>&name=<имя>
| Параметр | Обязателен | Описание |
|---|---|---|
url |
да | URL источника. Значение нужно percent-encode'ить, иначе :?/#& в целевом URL сломают deep-link. |
name |
нет | Имя подписки в форме (%20 для пробела, UTF-8). |
Поведение
DeepLinkParser.parseAddSubscriptionчитает query без учёта регистра (url,Urlи т.д.).- Открывается лист «Добавить подписку» (
AddSubscriptionForm) с предзаполнением. - Дальше — обычный конвейер подписки: subscription-http.md.
Примеры (полные URL: header + body)
| Сценарий | Полный URL |
|---|---|
| Только URL | sharx://add?url=https%3A%2F%2Fexample.com%2Fsub%2Fabc |
| URL + имя | sharx://add?url=https%3A%2F%2Fexample.com%2Fsub%2Fabc&name=Work%20VPN |
| Не-ASCII в имени (UTF-8) | sharx://add?url=https%3A%2F%2Fexample.com%2Fsub%2Fabc&name=%D0%A0%D0%B0%D0%B1%D0%BE%D1%87%D0%B8%D0%B9 |
Импорт профиля маршрутизации
Хедер, body и структура
| Содержимое | |
|---|---|
| Header | sharx://routing/add/ — фиксированный префикс. |
| Body | Всё после routing/add/ — payload (без ? в начале). Base64 (допустимы URL-safe - / _) JSON-объекта RoutingProfile (см. routing-profile-schema.md). Декодер: RoutingAnnounceDecoder. |
Полный вид URL
sharx://routing/add/<payload>
Ограничения
| Проверка | Лимит | Ошибка |
|---|---|---|
| Валидный Base64 | — | routing.error.base64 |
| Валидный JSON | — | routing.error.json |
| Размер после декодирования | 512 KiB | routing.error.large |
Поведение
DeepLinkParser.parseRoutingAddPayloadвыделяет подстроку послеrouting/add/и декодирует.- При успехе — лист подтверждения (
RoutingImportConfirmView). - После подтверждения —
RoutingProfileStore.upsertв App Group; расширение туннеля видит профиль. - Повтор с тем же
idперезаписывает существующий профиль.
Пример URL (payload)
sharx://routing/add/eyJpZCI6InJvdXRpbmctMDEiLCJuYW1lIjoi0JHQsNC30LAiLCJydWxlcyI6W119
(Base64 в JSON вида
{"id":"routing-01","name":"База","rules":[]}.)
Откуда приходят ссылки
| Источник | Механизм | Комментарий |
|---|---|---|
Системный onOpenURL |
WindowGroup { … }.onOpenURL в RootTabView |
Ссылка от iOS / macOS из другого приложения или Safari. |
| QR-сканер | QRCodeScannerView → NotificationCenter.post(.sharxInternalDeepLinkOpen) |
QR внутри приложения. |
| Буфер / внутренняя логика | NotificationCenter.post(.sharxInternalDeepLinkOpen) |
Любой внутренний URL. |
onOpenURL не срабатывает, если ссылка получена только внутри приложения
(например QR) — для этого и нужен NotificationCenter.
Что deep-link'и не делают
- Нет connect/disconnect VPN по ссылке — только через интерфейс приложения или стандартные средства ОС; по URL туннель не включается и не гасится.
- Нет прямого добавления одного сервера по
vless://,vmess://и т.д. — только через URL подписки:sharx://add?url=…. - Нет автообновления routing с удалённого
sourceURLв стилеautorouting/…— импорт одноразовый.
Если нужен другой сценарий — заведите issue.
Неподдерживаемые и устаревшие шаблоны
Подписка загружается только по HTTPS; тело читается как открытый текст после TLS. Обфусцированные пути URL для доставки подписки на стороне клиента не обрабатываются.
Нераспознанные пути и недокументированные форматы ссылок молча игнорируются.
См. subscription-http.md.