Добавить объявление

Universal Links: что скрыто за простым AASA-файлом

Universal Links в iOS кажутся простой технологией: добавил AASA-файл на сервер, прописал домен в entitlements и глубокие ссылки работают. Эта иллюзия разбивается о реальность масштабных проектов, где десятки доменов, локализации и регулярные обновления превращают поддержку Universal Links в сложную инженерную задачу. Проблема не в том, чтобы «завести» ссылки, а в том, чтобы они стабильно работали для миллионов пользователей после каждого обновления.

Когда пользователь кликает на Universal Link, iOS проверяет не ваш сервер напрямую. Система обращается к CDN Apple (app-site-association.cdn-apple.com), где кешируются AASA-файлы со всего мира. Ваш файл на сервере - лишь источник для этого кеша. Обновление в CDN происходит с задержкой до нескольких часов, и пока изменения не распространятся, часть пользователей будет видеть старую конфигурацию.

Критическая проблема - неявные ошибки конфигурации:


AASA-файл - это JSON, но не любой JSON подойдет. Большинство валидаторов проверяют только базовый синтаксис и доступность файла. Однако файл может быть технически валидным JSON, но содержать логические ошибки:

  • Неправильные wildcard-паттерны (*, ?, ?*).

  • Ошибки в substitution variables для локализаций.

  • Конфликтующие правила исключений (exclude).

  • Некорректные пути для query-параметров или фрагментов.

iOS не сообщает об этих ошибках. Ссылки просто перестают открываться в приложении, падая в Safari.

Стратегия надежного деплоя - четыре уровня защиты:


  • Валидация схемы (JSON Schema) в CI. Прежде чем файл попадет на сервер, автоматика проверяет его структуру. Это отлавливает опечатки в названиях полей, неправильные типы данных, отсутствие обязательных секций. Схема описывает не только applinks, но и опциональные разделы вроде webcredentials.

  • Сравнение с CDN Apple. После деплоя скрипт сравнивает файл на вашем сервере с тем, что вернул CDN Apple. Расхождения означают, что обновление еще не применилось. Эта проверка должна быть частью мониторинга.

  • Регрессионное тестирование ссылок. Для каждого домена ведется файл-конфигурации, который нужно тщательно тестировать.

  • Стендинг-окружение с реальными доменами. Тестировать на локальном localhost или симуляторе недостаточно. Нужны настоящие домены с HTTPS, зеркалирующие прод. В debug-сборках приложения указываются эти тестовые домены, что позволяет проверять изменения без риска для пользователей.

Wildcard-паттерны - собственная математика Apple:


Синтаксис *, ? и ?* в AASA - это не стандартные regex. Нужно понимать их преобразование:

  • * -> .* (ноль или больше символов)

  • ? -> . (ровно один символ)

  • ?* -> .+ (один или больше символов)

Самый сложный случай - substitution variables для локализаций:

"substitutionVariables": {
"menu": ["speisekarte", "menu", "carte"]
}

Паттерн /$(lang)/$(menu)/* должен корректно матчиться на /de/speisekarte/restaurant и /en/menu/restaurant. Реализация собственного парсера, который раскрывает переменные и преобразует паттерны - необходимость для нетривиальных проектов.

Особые случаи поведения iOS:


  • Первая установка: если пользователь установил приложение по Universal Link, данные о ссылке могут не передаться в первый запуск.

  • Холодный vs теплый запуск: поведение может отличаться в зависимости от того, было ли приложение в памяти.

  • Developer Mode: для отладки можно добавить ?mode=developer к домену в entitlements, чтобы iOS брала файл напрямую с сервера, минуя CDN.

Вывод:


Работа с Universal Links в крупном проекте - это не про добавление файла на сервер, а про построение полного жизненного цикла конфигурации. От валидации схемы и тестирования паттернов до мониторинга расхождений с CDN Apple.

Проблемы Universal Links редко проявляются сразу. Они накапливаются. Единственный способ избежать этого - относиться к AASA не как к статическому файлу, а как к критическому компоненту инфраструктуры со своим пайплайном деплоя, тестирования и мониторинга.
06.02.2026 12 555