Cómo manejar enlaces profundos en UIKit

Manejar enlaces profundos en UIKit implica dos mecanismos principales: **Esquemas de URL Personalizados** (Custom URL Schemes) y **Enlaces Universales** (Universal Links). Si bien ambos permiten a los usuarios navegar directamente a contenido específico dentro de su aplicación, los Enlaces Universal

Intermediate

Manejar enlaces profundos en UIKit implica dos mecanismos principales: Esquemas de URL Personalizados (Custom URL Schemes) y Enlaces Universales (Universal Links). Si bien ambos permiten a los usuarios navegar directamente a contenido específico dentro de su aplicación, los Enlaces Universales generalmente se prefieren por su experiencia de usuario fluida y un mejor comportamiento de respaldo.

1. Esquemas de URL Personalizados

Los esquemas de URL personalizados le permiten definir un prefijo único para las URL de su aplicación (por ejemplo, myapp://product/123). Cuando un usuario toca un enlace con este esquema, iOS lanza su aplicación.

Configuración:

  1. Registrar el Esquema de URL en Xcode:

    • Abra su proyecto en Xcode.
    • Seleccione su proyecto en el Navegador de Proyectos, luego seleccione su destino.
    • Vaya a la pestaña "Info".
    • En la sección "URL Types", haga clic en el botón "+" para agregar un nuevo tipo de URL.
    • Para "Identifier", puede usar el ID de paquete de su aplicación (por ejemplo, com.yourcompany.yourapp).
    • Para "URL Schemes", ingrese su esquema personalizado deseado (por ejemplo, myapp).
  2. Manejar la URL entrante en AppDelegate o SceneDelegate:

    • Para aplicaciones que usan AppDelegate (aplicaciones antiguas o que no usan Scene Delegates): Implemente el método application(_:open:options:).

      swift func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // Parse the URL and navigate to the appropriate content print("Received URL: \(url)") handleDeepLink(url) return true }

    • Para aplicaciones que usan SceneDelegate (iOS 13 y posterior): Implemente scene(_:openURLContexts:) o scene(_:continue:).

      ```swift func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } print("Received URL: (url)") handleDeepLink(url) }

      // For Universal Links, you'll also use this method func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return } print("Received Universal Link: (url)") handleDeepLink(url) } ```

2. Enlaces Universales

Los Enlaces Universales son enlaces HTTPS estándar que funcionan tanto para su sitio web como para su aplicación. Si su aplicación está instalada, el enlace se abre directamente en su aplicación; de lo contrario, se abre en Safari. Esto proporciona una experiencia de usuario mucho más fluida.

Configuración:

  1. Crear un archivo apple-app-site-association:

    • Este archivo JSON le dice a iOS qué URL puede manejar su aplicación.
    • Aloje este archivo en la raíz de su servidor web o en el subdirectorio .well-known (por ejemplo, https://yourdomain.com/apple-app-site-association).
    • Ejemplo de contenido: json { "applinks": { "apps": [], "details": [ { "appID": "TEAM_ID.com.yourcompany.yourapp", "paths": [ "/product/*", "/settings/*" ] } ] } } Reemplace TEAM_ID y com.yourcompany.yourapp con sus valores reales.
  2. Habilitar la Capacidad de Dominios Asociados en Xcode:

    • En Xcode, seleccione su proyecto y destino.
    • Vaya a la pestaña "Signing & Capabilities".
    • Haga clic en "+ Capability" y seleccione "Associated Domains".
    • Agregue una entrada para cada dominio que su aplicación deba manejar, prefijada con applinks: (por ejemplo, applinks:yourdomain.com).
  3. Manejar la URL entrante en AppDelegate o SceneDelegate:

    • Los Enlaces Universales se manejan utilizando el objeto NSUserActivity.
    • Para AppDelegate: Implemente application(_:continue:restorationHandler:).

      swift func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return false } print("Received Universal Link: \(url)") handleDeepLink(url) return true }

    • Para SceneDelegate: Use el método scene(_:continue:) como se muestra en la sección de Esquemas de URL Personalizados anterior.

3. Lógica General de Manejo de Enlaces Profundos (handleDeepLink función)

Independientemente de si utiliza esquemas de URL personalizados o Enlaces Universales, la lógica central para analizar la URL y navegar dentro de su aplicación es similar.

func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
        return
    }

    // Example: myapp://product/123?color=red
    // Example: https://yourdomain.com/product/123?color=red

    if components.host == "product" {
        // Extract product ID from path components or query parameters
        let productID = components.path.replacingOccurrences(of: "/", with: "")
        let color = components.queryItems?.first(where: { $0.name == "color" })?.value

        // Navigate to product detail screen
        // (e.g., using a UINavigationController or presenting a new view controller)
        if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
            let productViewController = ProductDetailViewController() // Your custom VC
            productViewController.productID = productID
            productViewController.selectedColor = color
            rootViewController.pushViewController(productViewController, animated: true)
        }
    } else if components.host == "settings" {
        // Navigate to settings screen
        if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
            let settingsViewController = SettingsViewController() // Your custom VC
            rootViewController.pushViewController(settingsViewController, animated: true)
        }
    }
    // Add more conditions for different paths/hosts
}

4. Consideraciones de Seguridad

Los enlaces profundos pueden ser un vector de ataque potencial. Siempre valide todos los parámetros de la URL y descarte cualquier URL mal formada. Limite las acciones disponibles a través de enlaces profundos a aquellas que no pongan en riesgo los datos del usuario, y nunca permita que eliminen contenido directamente o accedan a información confidencial.

5. Probar Enlaces Profundos

Puede probar enlaces profundos: * Ingresando el esquema de URL personalizado en Safari (por ejemplo, myapp://product/123). * Usando el comando xcrun simctl openurl booted <URL> en su terminal para abrir URL en el Simulador de iOS. * Tocando Enlaces Universales desde una página web en Safari.