Ответ
Deep Link ("глубокая ссылка") — это специальный URL, который направляет пользователя не просто в приложение, а на конкретный экран или контент внутри него, часто с передачей контекста (параметров).
Типы Deep Links в iOS:
- Custom URL Schemes (
myapp://product/123):- Схема регистрируется в
Info.plist. - Работает только если приложение установлено.
- Может перехватываться другими приложениями.
- Схема регистрируется в
- Universal Links (
https://example.com/product/123):- Использует HTTPS и привязан к домену.
- Если приложение установлено — открывает его. Если нет — открывает запасную веб-страницу.
- Более безопасны и являются стандартом.
Базовая обработка Custom URL Scheme в SceneDelegate:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
// Парсинг URL: myapp://products/details?id=123&source=promo
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
components.scheme == "myapp",
components.host == "products",
components.path == "/details" else { return }
// Извлечение параметров
let queryItems = components.queryItems
let productId = queryItems?.first(where: { $0.name == "id" })?.value
let source = queryItems?.first(where: { $0.name == "source" })?.value
// Навигация к экрану продукта
navigateToProductScreen(id: productId, source: source)
}
Критические аспекты реализации:
- Валидация: Всегда проверяйте и санируйте входящие URL и параметры для безопасности.
- Состояние приложения: Обработка должна работать, когда приложение:
- Запущено и активно.
- Запущено в фоне.
- Полностью закрыто (обработка переносится в
AppDelegate).
- User Activity (для Universal Links): Также необходимо обрабатывать метод
scene(_:continue:). - Роутинг: Для сложных сценариев используйте роутеры или координаторы для централизованной навигации.
Настройка Universal Link:
- Добавить домен в Capabilities → Associated Domains.
- Разместить на сервере файл
apple-app-site-association(без расширения). - Обработать в
scene(_:continue:)илиapplication(_:continue:restorationHandler:).