Integrar reCAPTCHA en aplicaciones iOS

En esta página se explica cómo integrar reCAPTCHA en tu aplicación iOS.

Debido a la variación de los dispositivos móviles en cuanto al tamaño de la pantalla, el rendimiento y las interfaces de usuario de las aplicaciones, el desafío visual de reCAPTCHA con casilla (No soy un robot) no está disponible para las aplicaciones móviles iOS. En su lugar, puede implementar su propia estrategia de aplicación por niveles, como un flujo de MFA, para proporcionar una ruta de canje alternativa para el tráfico sospechoso.

El SDK usa la reflexión y el código dinámico para permitir la actualización y la optimización del sistema de detección en aplicaciones o SDKs ya implementados. Para evitar interferencias con la aplicación, el conjunto de clases disponibles en el sistema se limita a una lista cuidadosamente controlada.

Antes de empezar

  1. Defina el SDK mínimo de su aplicación como iOS 12 o cree una aplicación móvil.

  2. Prepara tu entorno para reCAPTCHA.

  3. Crea una clave de reCAPTCHA para la plataforma de aplicaciones iOS.

    También puede copiar el ID de una clave de reCAPTCHA para iOS siguiendo uno de estos pasos:

    • Para copiar el ID de una clave ya creada desde la consola deGoogle Cloud , sigue estos pasos:

      1. Ve a la página reCAPTCHA.

        Ir a reCAPTCHA

      2. En la lista de claves de reCAPTCHA, coloca el puntero sobre la clave que quieras copiar y, a continuación, haz clic en .
    • Para copiar el ID de una clave que ya tengas mediante la API REST, usa el método projects.keys.list.
    • Para copiar el ID de una clave que ya tengas con gcloud CLI, usa el comando gcloud recaptcha keys list.

  4. Tener una cuenta de GitHub.

  5. Consulta los detalles de privacidad de Apple.

Preparar el entorno de iOS

Para preparar tu entorno de desarrollo, haz lo siguiente:

  1. Descarga e instala la última versión de Xcode y crea una aplicación iOS de vista única en blanco.

  2. Descarga el SDK de una de las siguientes formas:

    CocoaPods

    1. Descarga e instala CocoaPods.
    2. Crea un archivo Podfile y añade las siguientes líneas:

      source "https://github.com/CocoaPods/Specs.git"
      
      target 'AppTarget' do
      
        # Podfiles must include use_frameworks! or
        # use_frameworks! :linkage => :static
        use_frameworks!
      
        pod "RecaptchaEnterprise", "18.8.0-beta02"
        ...
      
      end
      
    3. Instala las dependencias necesarias ejecutando pod update.

    Swift Package Manager

    1. En Xcode, selecciona File > Add Packages (Archivo > Añadir paquetes) e introduce la siguiente URL en el campo Search (Buscar) o Enter Package URL (Introducir URL del paquete): https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk
    2. En el cuadro de diálogo Xcode, introduce los siguientes datos:

      • Nombre de usuario de GitHub.
      • Un token de acceso personal que hayas creado siguiendo las instrucciones de GitHub. El token de acceso personal debe tener los ámbitos que se indican en el cuadro de diálogo Iniciar sesión en Xcode.

      Xcode instala el SDK y sus dependencias necesarias.

    Flutter

    Para obtener instrucciones detalladas sobre cómo usar reCAPTCHA a través de Flutter, consulta la documentación de Flutter.

    ReactNative

    Para obtener instrucciones detalladas sobre cómo usar reCAPTCHA a través de React Native, consulta la documentación de React Native.

    Descarga directa

    1. Si quieres descargar el SDK y sus dependencias como xcframeworks, descarga el cliente.

Integrar reCAPTCHA en una aplicación iOS

Para integrar reCAPTCHA en tu aplicación iOS, sigue estos pasos en Xcode:

  1. Para crear una instancia del SDK con la clave de reCAPTCHA (KEY_ID) que has creado, actualiza la aplicación con el siguiente código:

    Swift con Storyboard

    1. Actualiza ViewController.swift.

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Task {
            do {
              self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
            } catch let error as RecaptchaError {
               print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
            }
          }
        }
      }
      

      Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
            guard let client = client else {
                print("RecaptchaClient creation error: \(error).")
              return
            }
            self.recaptchaClient = client
          }
        }
      }
      

    Swift con SwiftUI

    1. Crea una clase ViewModel.

      import RecaptchaEnterprise
      
      @MainActor class ViewModel: ObservableObject {
        private var recaptchaClient: RecaptchaClient?
      
        init() {
           Task {
            do {
              self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
            } catch let error as RecaptchaError {
               print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
            }
          }
        }
      }
      

      Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
            guard let client = client else {
                print("RecaptchaClient creation error: \(error).")
              return
            }
            self.recaptchaClient = client
          }
        }
      }
      
    2. Crea una instancia de ViewModel en ContentView.swift.

      import SwiftUI
      import RecaptchaEnterprise
      
      struct ContentView: View {
        @StateObject private var viewModel = ViewModel()
      
        var body: some View {
        }
      }
      
      struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
          ContentView()
        }
      }
      

    Objective‑C

    1. Si tu aplicación está escrita en Objective-C, crea un archivo Swift ficticio e incluye la siguiente importación para asegurarte de que Xcode pueda encontrar y vincular las bibliotecas Swift.

      import Foundation
      
    2. Para asegurarte de que el código Swift esté vinculado correctamente, ve a Target > Build Settings > Always Embed Swift Standard Libraries y comprueba que la opción esté definida como Yes.

    3. Actualiza ViewController.h.

      #import <RecaptchaEnterprise/RecaptchaEnterprise.h>
      
      @interface ViewController : UIViewController
      @property (strong, atomic) RecaptchaClient *recaptchaClient;
      @end
      
    4. Actualiza ViewController.m.

      @implementation ViewController
      [Recaptcha fetchClientWithSiteKey:@"KEY_ID"
            completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
              if (!recaptchaClient) {
                NSLog(@"%@", (RecaptchaError *)error.errorMessage);
                return;
              }
              self->_recaptchaClient = recaptchaClient;
            }
      ];
      @end
      

    La inicialización del SDK puede tardar varios segundos en completarse. Para reducir esta latencia, inicializa el cliente lo antes posible, por ejemplo, durante la llamada onCreate() de una clase Application personalizada. No debes hacer que los elementos de la interfaz de usuario se bloqueen en el SDK de reCAPTCHA.

  2. Crea un botón para llamar a reCAPTCHA y activar execute().

    Swift con Storyboard

    1. En el guion gráfico, crea un botón.
    2. Crea una acción en ViewController vinculada al botón que has creado.
    3. Llama al método execute() y pasa una acción Login para devolver un token de reCAPTCHA mediante el siguiente fragmento de código:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      Task {
        do {
          let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login)
          print(token)
        } catch let error as RecaptchaError {
          print(error.errorMessage)
        }
      }
      

      Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
      

    Swift con SwiftUI

    1. Actualiza ViewModel.swift con el código de ejecución:

      import RecaptchaEnterprise
      
      @MainActor class ViewModel: ObservableObject {
      
        func execute() {
          guard let recaptchaClient = self.recaptchaClient else {
            print("Client not initialized correctly.")
            return
          }
      
          Task {
            do {
              let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login)
              print(token)
            } catch let error as RecaptchaError {
              print(error.errorMessage)
            }
          }
        }
      }
      

      Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
      
    2. Actualiza ContentView.swift.

      import SwiftUI
      import RecaptchaEnterprise
      
      struct ContentView: View {
        @StateObject private var viewModel = ViewModel()
      
        var body: some View {
      
          Button {
            viewModel.execute()
          } label: {
            Text("Execute")
          }.padding()
      
          Spacer()
        }
      }
      
      struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
          ContentView()
        }
      }
      

    Objective‑C

    1. En el guion gráfico, crea un botón.
    2. Crea una acción en ViewController vinculada al botón que has creado.
    3. Llama al método execute() pasando una acción Login para devolver un token de reCAPTCHA:

      if (!self->_recaptchaClient) {
        return;
      }
      
      [recaptchaClient execute:RecaptchaAction.login
          completion:^void(NSString* _Nullable  token, NSError* _Nullable error) {
        if (!token) {
          NSLog (@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        NSLog (@"%@", token);
      }];
      

    La API execute del cliente puede tardar varios segundos en completarse, por ejemplo, en condiciones de red lentas o si está esperando a que se complete la inicialización en segundo plano. Asegúrate de que las llamadas execute() no bloqueen un evento de la interfaz de usuario, como pulsar un botón.

  3. Prueba tu aplicación:

    1. reCAPTCHA usa App Attest de Apple como parte de su motor de detección. Si no tienes previsto usar una clave de prueba con una puntuación fija para el desarrollo local, haz lo siguiente:

      1. En Xcode, añade la función App Attest a tu aplicación.

      2. En el archivo .entitlements de tu proyecto, define el entorno de App Attest como production.

    2. Para limpiar el entorno de compilación de Xcode, en el menú Product (Producto), haz clic en Clean Build Folder (Limpiar carpeta de compilación).

    3. Para ejecutar la aplicación, en el menú Producto, haga clic en Ejecutar.

    4. En la aplicación cargada, haz clic en el botón que has creado antes.

    5. Observa la ventana de salida de depuración para ver un token de reCAPTCHA (cadena alfanumérica), que se devuelve si la integración se realiza correctamente.

Migrar del método de la API al método fetchClient

El método fetchClient devuelve un RecaptchaClient que vuelve a intentar la inicialización si se produce un fallo en la red. Si la aplicación no tiene acceso a la red cuando se crea el cliente, este sigue intentándolo y se inicializa correctamente cuando se adquiere una red.

Si llamas a execute(timeout) y el cliente aún no está listo, intenta inicializar antes de devolver un token o un RecaptchaErrorCode.

En el siguiente ejemplo se muestra cómo migrar de getClient a fetchClient.

Swift con Storyboard

// Migrate from getClient
func initializeWithGetClient() {
  Task {
    do {
      self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

// Migrate to fetchClient
func initializeWithFetchClient() {
  Task {
    do {
      self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

// Migrate from getClient
override func initializeWithGetClient() {
  Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

// Migrate to fetchClient
override func initializeWithFetchClient() {
  Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

Swift con SwiftUI

// Migrate from getClient
initializeWithGetClient() {
    Task {
    do {
      self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

// Migrate to fetchClient
initializeWithFetchClient() {
    Task {
    do {
      self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

// Migrate from getClient
func initializeWithGetClient() {
  super.viewDidLoad()
  Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

// Migrate to fetchClient
func initializeWithFetchClient() {
  super.viewDidLoad()
  Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

Objective‑C

// Migrate from getClient
@implementation ViewController
[Recaptcha getClientWithSiteKey:@"KEY_ID"
      completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
        if (!recaptchaClient) {
          NSLog(@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        self->_recaptchaClient = recaptchaClient;
      }
];
@end

// Migrate to fetchClient
@implementation ViewController
[Recaptcha fetchClientWithSiteKey:@"KEY_ID"
      completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
        if (!recaptchaClient) {
          NSLog(@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        self->_recaptchaClient = recaptchaClient;
      }
];
@end

Definir un tiempo de espera para las llamadas a la API

Puedes especificar un valor de tiempo de espera para las APIs execute mediante la propiedad withTimeout.

Swift

  1. Define el tiempo de espera al llamar a execute.

      Task {
        do {
          let token = try await recaptchaClient.execute(
            withAction: RecaptchaAction.login,
            withTimeout: 10000)
          print(token)
        } catch let error as RecaptchaError {
          print(error.errorMessage)
        }
      }
    

    Si la versión mínima del SO de tu aplicación es inferior a 13, usa un cierre final:

      recaptchaClient.execute(
        withAction: RecaptchaAction.login,
        withTimeout: 10000
      ) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
    

Objective‑C

  1. Define el tiempo de espera al llamar a execute.

      [recaptchaClient execute:RecaptchaAction.login
          witTimeout:10000.0
          completion:^void(NSString* _Nullable  token, NSError* _Nullable error) {
        if (!token) {
          NSLog (@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        NSLog (@"%@", token);
      }];
    

Gestionar errores

Si tu aplicación no puede comunicarse correctamente con el servicio reCAPTCHA, puede deberse a que la API ha detectado un error. Debes añadir lógica a tu aplicación para gestionar estos errores correctamente.

Para obtener más información sobre las mitigaciones de errores comunes de la API, consulta RecaptchaErrorCode.

Referencia de la API

Para consultar una referencia completa de la API de reCAPTCHA para iOS, consulta RecaptchaEnterprise.

Siguientes pasos

  • Para evaluar el token de respuesta de reCAPTCHA, crea una evaluación.