Cómo recibir Dynamic Links en iOS

Para recibir los Firebase Dynamic Links que creaste, debes incluir el SDK de Dynamic Links en tu app y llamar al handleUniversalLink: y al dynamicLinkFromCustomSchemeURL: cuando tu app se cargue para obtener los datos que se pasaron en el Dynamic Link.

Requisitos previos

Antes de comenzar, asegúrate de agregar Firebase a tu proyecto de iOS.

Usa Swift Package Manager para instalar y administrar las dependencias de Firebase.

  1. En Xcode, con tu proyecto de app abierto, navega a File > Add Packages.
  2. Cuando se te solicite, agrega el repositorio del SDK de Firebase para plataformas de Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Elige la biblioteca de Dynamic Links.
  5. Agrega la marca -ObjC a la sección Other Linker Flags de la configuración de compilación de tu destino.
  6. Para obtener una experiencia óptima con Dynamic Links, te recomendamos habilitar Google Analytics en tu proyecto de Firebase y agregar el SDK de Firebase para Google Analytics a la app. Puedes seleccionar la biblioteca sin la colección de IDFA o con la colección de IDFA.
  7. Cuando termines, Xcode comenzará a resolver y descargar automáticamente tus dependencias en segundo plano.

Ahora, debes realizar los siguientes pasos de configuración:

  1. En la consola de Firebase, abre la sección Dynamic Links. . Si se te solicita, acepta las Condiciones del Servicio.
  2. Asegúrate de que el ID de App Store y el prefijo de ID de la app estén especificados en la configuración de la app. Para ver y editar la configuración de tu app, ve a la página de configuración del proyecto de Firebase y selecciona tu app para iOS.

    Para confirmar que el proyecto de Firebase tenga la configuración correcta para usar Dynamic Links en la app para iOS, visita la siguiente URL:

    https://your_dynamic_links_domain/apple-app-site-association

    Si tu app está conectada, el archivo apple-app-site-association contiene una referencia al prefijo de ID de la app y del paquete. Por ejemplo:

    {"applinks":{"apps":[],"details":[{"appID":"1234567890.com.example.ios","paths":["NOT /_/*","/*"]}]}}

    Si el campo details está vacío, vuelve a verificar que hayas especificado el prefijo de ID de la app. Ten en cuenta que el prefijo de ID de la app puede no coincidir con el ID del equipo.

  3. Opcional: Impide que el SDK de Dynamic Links use el portapapeles de iOS.

    De forma predeterminada, el SDK de Dynamic Links usa el portapapeles para mejorar la confiabilidad de los vínculos directos posteriores a la instalación. De esta manera Dynamic Links puede garantizar que, cuando un usuario abra un Dynamic Link, pero deba instalar tu app primero, pueda ir de inmediato al contenido vinculado original después de abrir la app por primera vez.

    La desventaja de esta opción es que el uso del portapapeles activa una notificación en iOS 14 y versiones posteriores. Por lo tanto, si el portapapeles contiene la URL y los usuarios abren tu app por primera vez, verán una notificación de que la app accedió al portapapeles, lo que puede causar confusión.

    Para inhabilitar este comportamiento, edita el archivo Info.plist del proyecto de Xcode y configura la clave FirebaseDeepLinkPasteboardRetrievalEnabled como NO.

  1. En la pestaña Información del proyecto de Xcode de la app, crea un tipo de URL nuevo para usarlo con Dynamic Links. Asigna un valor único al Identificador y establece el campo Esquema de URL como el identificador de paquete, que es el esquema de URL predeterminado que usa Dynamic Links.
  2. En la pestaña Funciones del proyecto de Xcode de la app, habilita los dominios asociados y agrega lo siguiente a la lista de Dominios asociados:
    applinks:your_dynamic_links_domain
  3. Si quieres recibir Dynamic Links con un dominio completamente personalizado, en el archivo Info.plist de tu proyecto de Xcode, crea una clave llamada FirebaseDynamicLinksCustomDomains y establécela en los prefijos de la URL de Dynamic Links de la app. Por ejemplo:
    FirebaseDynamicLinksCustomDomains
    
      https://example.com/promos
      https://example.com/links/share
    
  4. Importa el módulo FirebaseCore en tu UIApplicationDelegate, así como cualquier otro módulo de Firebase que use el delegado de la app. Por ejemplo, para usar Cloud Firestore y Authentication:

    SwiftUI

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Swift

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objective-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  5. Configura una instancia compartida de FirebaseApp en el método application(_:didFinishLaunchingWithOptions:) del delegado de la app:

    SwiftUI

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  6. Si usas SwiftUI, debes crear un delegado de la aplicación y adjuntarlo al struct de tu App a través de UIApplicationDelegateAdaptor o NSApplicationDelegateAdaptor. También debes inhabilitar el swizzling del delegado de la app. Para obtener más información, consulta las instrucciones de SwiftUI.

    SwiftUI

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          
  7. A continuación, en el método application:continueUserActivity:restorationHandler: , controla los vínculos recibidos como vínculos universales cuando la app ya esté instalada:

    Swift

    Nota: Este producto no se encuentra disponible en objetivos de macOS, Mac Catalyst, tvOS ni watchOS.
    func application(_ application: UIApplication, continue userActivity: NSUserActivity,
                     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
      let handled = DynamicLinks.dynamicLinks()
        .handleUniversalLink(userActivity.webpageURL!) { dynamiclink, error in
          // ...
        }
    
      return handled
    }

    Objective-C

    Nota: Este producto no se encuentra disponible en objetivos de macOS, Mac Catalyst, tvOS ni watchOS.
    - (BOOL)application:(UIApplication *)application
    continueUserActivity:(nonnull NSUserActivity *)userActivity
     restorationHandler:
    #if defined(__IPHONE_12_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0)
    (nonnull void (^)(NSArray<id<UIUserActivityRestoring>> *_Nullable))restorationHandler {
    #else
        (nonnull void (^)(NSArray *_Nullable))restorationHandler {
    #endif  // __IPHONE_12_0
      BOOL handled = [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL
                                                              completion:^(FIRDynamicLink * _Nullable dynamicLink,
                                                                           NSError * _Nullable error) {
                                                                // ...
                                                              }];
      return handled;
    }
  8. Por último, en application:openURL:options: controla los vínculos recibidos a través del esquema de URL personalizada de tu app. Este método se llama cuando la app se abre por primera vez después de la instalación.

    Si no se encuentra Dynamic Link en el primer inicio de la app, se llamará a este método con el url de DynamicLink establecido en nil, lo que indica que el SDK no pudo encontrar un Dynamic Link pendiente que coincida.

    Swift

    Nota: Este producto no se encuentra disponible en objetivos de macOS, Mac Catalyst, tvOS ni watchOS.
    @available(iOS 9.0, *)
    func application(_ app: UIApplication, open url: URL,
                     options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
      return application(app, open: url,
                         sourceApplication: options[UIApplication.OpenURLOptionsKey
                           .sourceApplication] as? String,
                         annotation: "")
    }
    
    func application(_ application: UIApplication, open url: URL, sourceApplication: String?,
                     annotation: Any) -> Bool {
      if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
        // Handle the deep link. For example, show the deep-linked content or
        // apply a promotional offer to the user's account.
        // ...
        return true
      }
      return false
    }

    Objective-C

    Nota: Este producto no se encuentra disponible en objetivos de macOS, Mac Catalyst, tvOS ni watchOS.
    - (BOOL)application:(UIApplication *)app
                openURL:(NSURL *)url
                options:(NSDictionary<NSString *, id> *)options {
      return [self application:app
                       openURL:url
             sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                    annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
    }
    
    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
      FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
    
      if (dynamicLink) {
        if (dynamicLink.url) {
          // Handle the deep link. For example, show the deep-linked content,
          // apply a promotional offer to the user's account or show customized onboarding view.
          // ...
        } else {
          // Dynamic link has empty deep link. This situation will happens if
          // Firebase Dynamic Links iOS SDK tried to retrieve pending dynamic link,
          // but pending link is not available for this device/App combination.
          // At this point you may display default onboarding view.
        }
        return YES;
      }
      return NO;
    }