Universal Link — это механизм Apple (iOS 9+), который позволяет открывать веб-ссылки непосредственно в приложении, минуя Safari. Если приложение не установлено, ссылка бесшовно открывается в браузере. Термин ввёл Apple в 2015 году на WWDC как часть Handoff и экосистемы Continuity. По данным Apple Developer, Universal Link обеспечивает единый пользовательский опыт между вебом и нативным приложением без диалогов выбора.
Главное
Universal Link — это стандартная HTTPS-ссылка вида https://example.com/page, которая при переходе с iOS-устройства открывает установленное приложение вместо Safari. Главное отличие от Custom URL Scheme: Universal Link не требует регистрации кастомной схемы (myapp://) — используется обычный домен. Это устраняет проблему URL Scheme hijacking, когда любое приложение может зарегистрировать ту же схему.
Apple представила Universal Link на WWDC 2015 в рамках iOS 9. Механизм стал частью экосистемы Handoff и Spotlight: Universal Link работает не только в браузере, но и в результатах поиска Spotlight, в Mail, Messages и других системных приложениях. Кроме того, Universal Link поддерживается в watchOS и macOS — пользователь может открыть приложение на iPhone через ссылку на Mac.
Ключевое преимущество: единый URL. Разработчик не управляет двумя разными ссылками (одной для веба, другой для приложения). Universal Link — это одна и та же https-ссылка. Если приложение установлено — открывается оно. Если нет — та же ссылка открывается в Safari как обычная веб-страница. Это даёт идеальный fallback без потери трафика.
Механизм Universal Link состоит из трёх этапов: проверка ассоциации, обработка ссылки и fallback в браузер. Каждый этап критичен для корректной работы. Если ассоциация не настроена, iOS обрабатывает ссылку как обычный переход в Safari. Рассмотрим каждый этап подробно.
При первом переходе по ссылке iOS загружает файл apple-app-site-association с сервера по адресу https://example.com/.well-known/apple-app-site-association. Файл содержит JSON с идентификатором Team ID и Bundle ID приложения, а также список путей, которые должно открывать приложение. iOS кэширует этот файл и периодически проверяет его актуальность (при обновлении приложения, перезагрузке устройства).
JSON-файл apple-app-site-association должен быть доступен по HTTPS без редиректов. Сервер должен отдавать Content-Type: application/json. Важно: файл не имеет расширения .json — iOS ищет его строго по пути /.well-known/apple-app-site-association. Apple рекомендует также добавить поддержку для Universal Link в CDN и проверить, что файл не блокируется robots.txt.
// apple-app-site-association — минимальная конфигурация
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.app",
"paths": ["/product/*", "/profile/*", "/search"]
}
]
}
}
appID формируется как Team ID + Bundle ID (TEAMID.com.example.app). paths — массив шаблонов URL, которые должно обрабатывать приложение. Можно использовать *, ? и нотацию NOT: ["NOT /admin/*", "/product/*"]. Пути проверяются в порядке перечисления: первое совпадение определяет поведение. Если путь не совпал — ссылка открывается в Safari.
После успешной верификации ассоциации iOS передаёт ссылку приложению. Обработка выполняется в AppDelegate через метод application(_:continue:restorationHandler:) для NSUserActivity, или в SceneDelegate через scene(_:continue:). Разработчик получает объект NSUserActivity с типом NSUserActivityTypeBrowsingWeb, извлекает URL и навигирует на соответствующий экран.
// Обработка Universal Link в AppDelegate
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping UIUserActivityRestorationHandler
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL
else { return false }
// Навигация на экран согласно URL
DeepLinkRouter.navigate(to: url)
return true
}
DeepLinkRouter в примере выше — кастомный класс, который парсит URL и вызывает соответствующий координатор навигации. Для SwiftUI обработка выполняется через метод onOpenURL или модификатор environment(\.openURL). Важно обрабатывать не только foreground-запуск, но и случай, когда приложение не запущено (cold start): Universal Link в этом случае открывает приложение через launch options.
Если приложение не установлено, iOS автоматически открывает Universal Link в Safari. Это ключевое отличие от Custom URL Scheme: пользователь не видит ошибку. Fallback — это стандартная веб-страница того же домена. Разработчик может разместить на этой странице ссылку на App Store, информацию о продукте или альтернативный контент.
Важно: fallback нельзя кастомизировать на уровне iOS. iOS просто открывает URL в Safari. Чтобы показывать разный контент для пользователей с установленным и неустановленным приложением, используйте Smart App Banner (meta-тег для Safari, предлагающий открыть приложение) или JavaScript-детекцию установки приложения. Apple также предоставляет SKAdNetwork для атрибуции установок через Universal Link.
Universal Link и традиционный Deep Link (Custom URL Scheme) решают одну задачу, но принципиально различаются по архитектуре и безопасности. Custom URL Scheme — кастомный протокол (myapp://), который регистрируется в Info.plist. Любое приложение может зарегистрировать ту же схему (myapp://), и iOS не может определить, какое из них «настоящее». Это называется URL Scheme hijacking.
Universal Link решает проблему hijacking через верификацию домена. Только владелец домена может разместить apple-app-site-association на своём сервере, подтвердив связь с конкретным Bundle ID. Два приложения не могут зарегистрировать один Universal Link: если confict возникает, iOS отдаёт приоритет приложению, установленному последним, или открывает Safari.
Другое отличие: Fallback. Custom URL Scheme не имеет fallback — если приложение не установлено, браузер показывает ошибку. Universal Link открывает сайт. Единый URL означает, что SEO-ценность ссылки сохраняется (ссылку индексирует Google), а пользователь с любым устройством получает релевантный контент. Universal Link — эволюционный шаг от deep link к unified link.
| Характеристика | Custom URL Scheme | Universal Link |
|---|---|---|
| Формат | myapp://path | https://domain/path |
| Верификация | Нет | apple-app-site-association |
| Безопасность | Уязвим к hijacking | Только владелец домена |
| Fallback | Ошибка | Сайт в Safari |
| iOS версия | iOS 3+ | iOS 9+ |
Настройка Universal Link включает серверную и клиентскую части. Серверная — размещение файла apple-app-site-association по адресу https://domain/.well-known/apple-app-site-association. Клиентская — регистрация домена в Associated Domains в Xcode (Capabilities → Associated Domains → applinks:example.com). После этого приложение автоматически получает все Universal Link для указанного домена.
Шаги настройки:
Отладка Universal Link — частая головная боль iOS-разработчиков. Основные причины неработающих ссылок: файл apple-app-site-association недоступен по HTTPS, неверный appID, Content-Type не application/json, редирект с /.well-known пути, кэширование старой версии файла (сброс через Settings → Developer → Associated Domains Development). Apple предоставляет инструмент «Validation Checker» в Apple Developer Console для тестирования ассоциации.
Branch и другие MMP-платформы упрощают настройку Universal Link: они генерируют apple-app-site-association автоматически и хостингят его на своём домене. Разработчику достаточно добавить Branch домен в Associated Domains и интегрировать SDK. Это особенно удобно для стартапов, у которых нет своей серверной инфраструктуры для хостинга AASA-файла.
Universal Link имеет несколько ограничений. Первое: файл apple-app-site-association должен быть доступен строго по HTTPS (HTTP не поддерживается). Второе: ссылка должна вести на тот же домен, который указан в Associated Domains. Междоменные Universal Link не работают — для каждого домена нужна отдельная запись в Capabilities и отдельный AASA-файл. Третье: Universal Link не работает в WKWebView — только в Safari и системных компонентах.
Совместимость: iOS 9.0+ (Universal Link), watchOS 6.0+ (Handoff Universal Link), macOS 10.15+ (Catalyst и Mac приложения). В более старых версиях iOS ссылка открывается в Safari. Это значит, что на iOS 8 (менее 1% устройств) Universal Link не сработает. Рекомендуется поддерживать и Custom URL Scheme как fallback для старых устройств, если аудитория включает пользователей с устаревшими версиями.
iOS 16+ изменения: Apple улучшила обработку Universal Link для SwiftUI. Появился новый модификатор environment(\.openURL) с возможностью отложенной обработки. iOS 16 также позволяет открывать Universal Link в приложении даже через SFSafariViewController. Для пользователей iOS 16 рекомендуется полностью переходить на SwiftUI-обработку Universal Link, оставив AppDelegate-код только для обратной совместимости.
Часто задаваемые вопросы
Universal Link использует стандартный HTTPS-URL и верифицируется через файл на сервере. Custom URL Scheme использует кастомный протокол (myapp://) без верификации, что делает его уязвимым к перехвату другим приложением, зарегистрировавшим ту же схему.
Файл размещается в корне HTTPS-сервера по пути /.well-known/apple-app-site-association (без расширения .json). Сервер должен отдавать Content-Type: application/json. Важно: никаких редиректов, файл должен быть доступен напрямую.
Основные причины: неверный Team ID или Bundle ID в AASA-файле, файл недоступен по HTTPS, редирект, неправильный Content-Type, кэширование старой версии. Проверьте через Developer → Associated Domains Development и сбросьте кэш перезагрузкой устройства.
Нет — для Universal Link требуется HTTPS-сервер, на котором размещён apple-app-site-association. Без домена Universal Link не работает. Альтернатива: Custom URL Scheme (менее безопасно) или сторонние сервисы (Branch, Firebase) с собственным доменом.
Нет — Universal Link эксклюзивная технология Apple для iOS, iPadOS, watchOS и macOS. На Android аналог называется App Link (Android 6.0+), который использует Digital Asset Links (assetlinks.json) вместо apple-app-site-association.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также