Integra reCAPTCHA en apps para iOS

En esta página, se explica cómo integrar reCAPTCHA en tu app para iOS.

Debido a la variación en los dispositivos móviles en términos de tamaño de pantalla, rendimiento y IU de las apps, el desafío visual de reCAPTCHA con casilla de verificación (No soy un robot) no está disponible para las apps para dispositivos móviles de iOS. En su lugar, puedes implementar tu 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 reflexión y código dinámico para permitir la actualización y el perfeccionamiento 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 restringe a una lista controlada con cuidado.

Antes de comenzar

  1. Establece el SDK mínimo de tu app en iOS 12 o crea una app para dispositivos móviles nueva.

  2. Prepara tu entorno para reCAPTCHA.

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

    Como alternativa, puedes copiar el ID de una clave reCAPTCHA existente para iOS si realizas uno de los siguientes pasos:

    • Para copiar el ID de una clave existente desde la consola de Google Cloud, haz lo siguiente:

      1. Ve a la página de reCAPTCHA.

        Ve a reCAPTCHA

      2. En la lista de claves de reCAPTCHA, mantén el puntero sobre la clave que deseas copiar y, luego, haz clic en .
    • Para copiar el ID de una clave existente con la API de REST, usa el método projects.keys.list.
    • Para copiar el ID de una clave existente con la CLI de gcloud, usa el comando gcloud recaptcha keys list.

  4. Tener una cuenta de GitHub

  5. Lee los detalles de privacidad de Apple.

Prepara tu entorno de iOS

Para preparar el entorno de desarrollo, haz lo siguiente:

  1. Descarga e instala la versión más reciente de Xcode y crea una nueva aplicación de vista única para iOS en blanco.

  2. Descarga el SDK con una de las siguientes opciones:

    CocoaPods

    1. Descarga e instala CocoaPods.
    2. Crea un Podfile y agrega las siguientes líneas a él:

      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.6.0"
        ...
      
      end
      
    3. Ejecuta pod update para instalar las dependencias necesarias.

    Swift Package Manager

    1. En Xcode, selecciona File > Add Packages y, luego, ingresa la siguiente URL en el campo Search o Enter Package URL: https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk
    2. En el diálogo Xcode, ingresa los siguientes detalles:

      • Nombre de usuario de GitHub
      • Un token de acceso personal que creaste con las instrucciones de GitHub El token de acceso personal debe tener los permisos que se indican en el diálogo XCode Sign In.

      Xcode instala el SDK y sus dependencias necesarias.

    Flutter

    Para obtener instrucciones detalladas sobre el uso de reCAPTCHA a través de Flutter, consulta la documentación de Flutter.

    ReactNative

    Para obtener instrucciones detalladas sobre el uso de 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.

Configura la app

Puedes escribir tus apps en Swift o Objective-C.

Para configurar tu app, agrega los siguientes archivos:

Swift

  1. Si tu app está escrita en Swift, incluye la siguiente importación:

     import RecaptchaEnterprise
    

Objective-C

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

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

Integra reCAPTCHA en tu app para iOS

Para integrar reCAPTCHA en tu app para iOS, sigue estos pasos en Xcode:

  1. Para crear una instancia del SDK con la clave de reCAPTCHA (KEY_ID) que creaste, actualiza la app 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 en su lugar:

      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 en su lugar:

      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. Actualiza ViewController.h.

      #import <RecaptchaEnterprise/RecaptchaEnterprise.h>
      
      @interface ViewController : UIViewController
      @property (strong, atomic) RecaptchaClient *recaptchaClient;
      @end
      
    2. 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 mitigar 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 IU 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 storyboard, crea un botón.
    2. Crea una acción en ViewController vinculada al botón que creaste.
    3. Llama al método execute() pasando una acción Login para mostrar un token de reCAPTCHA con 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 en su lugar:

      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 creaste.
    3. Llama al método execute() y pasa una acción Login para mostrar 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 de execute del cliente puede tardar varios segundos en completarse, por ejemplo, en condiciones de red lentas o si está esperando que se complete la inicialización en segundo plano. Asegúrate de que las llamadas a execute() no bloqueen un evento de IU, como presionar un botón.

  3. Prueba tu aplicación:

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

      1. En Xcode, agrega la función de App Attest a la app.

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

    2. Para limpiar el entorno de compilación de Xcode, en el menú Producto, haz clic en Limpiar la carpeta de compilación.

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

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

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

Cómo migrar de la API del método al método fetchClient

El método fetchClient muestra un RecaptchaClient que vuelve a intentar la inicialización en caso de fallas de red. Si la app no tiene acceso a la red cuando se crea el cliente, este sigue reintentando y se inicializa correctamente cuando se adquiere una red.

Si llamas a execute(timeout) y el cliente aún no está listo, intentará inicializarse antes de mostrar 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 en su lugar:

// 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 en su lugar:

// 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

Establece un tiempo de espera para las llamadas a la API

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

Swift

  1. Establece el tiempo de espera cuando llames 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. Establece el tiempo de espera cuando llames 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);
      }];
    

Soluciona errores

Si la app no se puede comunicar con el servicio de reCAPTCHA correctamente, es posible que la API haya detectado un error. Debes agregar lógica en tu app para controlar estos errores.

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

Referencia de API

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

¿Qué sigue?

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