Как можно реализовать DeepLink?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Реализация DeepLink в iOS
DeepLink (или глубокое связывание) — это техника, позволяющая открывать конкретные разделы или выполнять определенные действия внутри приложения через специальные URL. В iOS это реализуется через Universal Links (для веб-сайтов) и Custom URL Schemes (для внутренних ссылок).
Основные подходы
1. Custom URL Schemes
Это собственные схемы URL, которые ваше приложение регистрирует в системе. Они используются для открытия приложения из других приложений или системных компонентов.
Регистрация схемы в Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
<key>CFBundleURLName</key>
<string>com.example.MyApp</string>
</dict>
</array>
Обработка ссылки в AppDelegate:
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return false
}
// Пример: myapp://product?id=123
if url.scheme == "myapp" && url.host == "product" {
let productId = queryItems.first(where: { $0.name == "id" })?.value
if let id = productId {
navigateToProductDetail(id: id)
}
return true
}
return false
}
2. Universal Links
Это более современный и безопасный подход, использующий HTTPS-ссылки для открытия приложения. Они требуют конфигурации на стороне сервера и в приложении.
Конфигурация в Info.plist:
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:example.com</string>
</array>
Создание файла apple-app-site-association на сервере:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.MyApp",
"paths": ["/products/*", "/profile"]
}
]
}
}
Обработка в SceneDelegate или AppDelegate:
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let urlContext = connectionOptions.urlContexts.first {
handleUniversalLink(url: urlContext.url)
}
}
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
guard let url = userActivity.webpageURL else { return false }
return handleUniversalLink(url: url)
}
return false
}
private func handleUniversalLink(url: URL) -> Bool {
// Пример: https://example.com/products/123
if url.pathComponents.contains("products") {
let productId = url.lastPathComponent
navigateToProductDetail(id: productId)
return true
}
return false
}
Ключевые этапы реализации
Подготовка
- Определите схему ссылок: продумайте структуру URL (например,
myapp://section/item?id=123илиhttps://domain.com/path). - Настройте проекты: добавьте необходимые записи в
Info.plist, конфигурационные файлы на сервере.
Обработка
- Разберите URL: используйте
URLComponentsдля декомпозиции ссылки на компоненты (scheme, host, path, query). - Валидация: проверьте соответствие схемы/домена вашим ожиданиям.
- Маршрутизация: на основе параметров URL выполните переход к нужному экрану или действию.
Навигация
private func navigateToProductDetail(id: String) {
guard let window = UIApplication.shared.windows.first,
let rootVC = window.rootViewController as? UINavigationController else {
return
}
let productVC = ProductDetailViewController(productId: id)
rootVC.pushViewController(productVC, animated: true)
}
Рекомендации и best practices
- Используйте Universal Links для внешних ссылок: они более безопасны и предоставляют лучший пользовательский опыт (переход напрямую в приложение без промежуточных диалогов).
- Custom URL Schemes для внутренних коммуникаций: например, для открытия из других ваших приложений или обработки специфических команд.
- Всегда проверяйте параметры: DeepLink может быть потенциальным вектором атак, поэтому валидируйте все входные данные.
- Обрабатывайте edge cases: предусмотрите случаи, когда приложение еще не полностью запущено или нужный экран не готов.
- Логирование: добавляйте логи для отслеживания успешных и неудачных открытий через DeepLink — это поможет в диагностике проблем.
- Тестирование: создайте unit-тесты для парсинга URL и интеграционные тесты для проверки полного цикла открытия приложения.
Пример комплексной обработки
class DeepLinkRouter {
enum DeepLinkType {
case productDetail(id: String)
case userProfile(userId: String)
case settings(section: String)
}
func parse(url: URL) -> DeepLinkType? {
let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
// Обработка Universal Link
if url.scheme == "https" && url.host == "example.com" {
if url.path.hasPrefix("/products/") {
let productId = url.lastPathComponent
return .productDetail(id: productId)
}
}
// Обработка Custom URL Scheme
if url.scheme == "myapp" {
switch url.host {
case "product":
let queryItems = components?.queryItems
let productId = queryItems?.first(where: { $0.name == "id" })?.value
if let id = productId {
return .productDetail(id: id)
}
case "profile":
// аналогичная обработка
break
}
}
return nil
}
func navigate(to linkType: DeepLinkType) {
switch linkType {
case .productDetail(let id):
presentProductDetail(id: id)
// обработка других случаев
}
}
}
Реализация DeepLink требует внимательности к деталям, но значительно улучшает интеграцию приложения с экосистемой iOS и внешними сервисами, предоставляя пользователям seamless опыт перехода между web и app контентом.