Agrega Acceder con Google a una app para iOS

1. Antes de comenzar

En este codelab, se te guiará para que compiles una aplicación para iOS que implemente el acceso con Google y se ejecute en un simulador. Se proporcionan implementaciones con SwiftUI y UIKit.

SwiftUI es el framework de IU moderno de Apple para el desarrollo de apps nuevas. Permite compilar interfaces de usuario para todas las plataformas de Apple desde una sola base de código compartida. Requiere una versión mínima de iOS 13.

UIKit es el marco de trabajo de IU original y fundamental de Apple para iOS. Proporciona retrocompatibilidad para versiones anteriores de iOS. Esto la convierte en una buena opción para las apps establecidas que necesitan admitir una variedad de dispositivos más antiguos.

Puedes seguir la ruta del framework que mejor se alinee con tus necesidades de desarrollo.

Requisitos previos

Qué aprenderás

  • Cómo crear un proyecto de Google Cloud
  • Cómo crear clientes de OAuth en la consola de Google Cloud
  • Cómo implementar Acceder con Google en tu app para iOS
  • Cómo personalizar el botón de Acceder con Google
  • Cómo decodificar un token de ID
  • Cómo habilitar la Verificación de aplicaciones para tu app para iOS

Requisitos

  • Una versión actual de Xcode
  • Una computadora que ejecute macOS y cumpla con los requisitos del sistema para la versión de Xcode que instalaste

Este codelab se creó con Xcode 16.3 y el simulador de iOS 18.3. Debes usar la versión más reciente de Xcode para el desarrollo.

2. Crea un proyecto nuevo de Xcode

  1. Abre Xcode y selecciona Create a new Xcode project.
  2. Elige la pestaña iOS, selecciona la plantilla App y haz clic en Next.

Página de plantilla de creación de proyectos de Xcode

  1. En las opciones del proyecto:
    • Ingresa el nombre del producto.
    • De manera opcional, selecciona tu equipo.
    • Ingresa tu identificador de organización.
    • Toma nota del identificador del paquete generado. La necesitarás más tarde.
    • En Interfaz, elige una de las siguientes opciones:
      • SwiftUI para una app basada en SwiftUI
      • Guion gráfico para una app basada en UIKit
    • Elige Swift para el lenguaje.
    • Haz clic en Siguiente y elige una ubicación para guardar tu proyecto.

Página de opciones del proyecto de Xcode

3. Crea un cliente de OAuth

Para permitir que tu app se comunique con los servicios de autenticación de Google, debes crear un ID de cliente de OAuth. Esto requiere un proyecto de Google Cloud. Los siguientes pasos te guiarán en el proceso de creación de un proyecto y un ID de cliente de OAuth.

Selecciona o crea un proyecto de Google Cloud

  1. Ve a la consola de Google Cloud y selecciona o crea un proyecto. Si seleccionas un proyecto preexistente, la consola te dirigirá automáticamente al siguiente paso obligatorio.

Página del selector de proyectos de la consola de Google Cloud

  1. Ingresa un nombre para tu nuevo proyecto de Google Cloud.
  2. Selecciona Crear.

Página del selector de proyectos de la consola de Google Cloud

Si ya configuraste una pantalla de consentimiento para el proyecto seleccionado, no se te solicitará que la configures ahora. En ese caso, puedes omitir esta sección y pasar a Crea un cliente de OAuth 2.0.

  1. Selecciona Configurar pantalla de consentimiento.

Página de creación de clientes de OAuth de la consola de Google Cloud con el requisito de configurar la pantalla de consentimiento

  1. Selecciona Comenzar en la página de desarrollo de la marca.

Página de inicio de la marca de la consola de Google Cloud

  1. En la página de configuración del proyecto, completa los siguientes campos:
    • Información de la app: Ingresa un nombre y un correo electrónico de asistencia al usuario para tu app. Este correo electrónico de asistencia se mostrará públicamente para que los usuarios se comuniquen contigo si tienen preguntas sobre su consentimiento.
    • Público: Selecciona Externo.
    • Información de contacto: Ingresa una dirección de correo electrónico para que Google se comunique contigo sobre tu proyecto.
    • Revisa la Política de Datos del Usuario de los Servicios de las APIs de Google.
    • Haz clic en Crear.

Página de configuración de la marca del cliente de la consola de Google Cloud

  1. Selecciona la página Clientes en el menú de navegación.
  2. Haz clic en Crear cliente.

Página de clientes del proyecto de Google Cloud

Crea un cliente de OAuth 2.0

  1. Selecciona iOS en Tipo de aplicación.
  2. Ingresa un nombre para tu cliente.
  3. Ingresa el identificador de paquete que creaste en el paso anterior.
  4. Ingresa el ID del equipo que Apple le asignó a tu equipo. Por el momento, este paso es opcional, pero se requiere un ID de equipo para habilitar App Check más adelante en este codelab.
  5. Selecciona Crear.

Página de entrada de detalles del cliente de OAuth

  1. Copia el ID de cliente de la ventana de diálogo, ya que lo necesitarás más adelante.
  2. Descarga el archivo plist para consultarlo más adelante.

Diálogo de ID de cliente de OAuth creado

4. Configura tu proyecto de Xcode

El siguiente paso es configurar tu proyecto de Xcode para que funcione con el SDK de Sign in with Google. Este proceso implica agregar el SDK a tu proyecto como una dependencia y configurar los parámetros del proyecto con un ID de cliente único. Este ID permite que el SDK se comunique de forma segura con el servicio de autenticación de Google durante el proceso de acceso.

Instala las dependencias de Acceder con Google

  1. Abre tu proyecto de Xcode.
  2. Navega a File > Add Package Dependencies.
  3. En la barra de búsqueda, ingresa la URL del repositorio de Acceder con Google: https://github.com/google/GoogleSignIn-iOS

Busca la dependencia de Acceder con Google en Swift Package Manager

  1. Selecciona Add Package.
  2. Selecciona el objetivo principal de la aplicación para el paquete GoogleSignIn.
  3. Si usas SwiftUI, selecciona el destino principal de la aplicación para el paquete GoogleSignInSwift. Si planeas usar UIKit, no selecciones un destino para este paquete.
  4. Selecciona Add Package.

Agrega la dependencia de Acceder con Google a tu proyecto

Configura las credenciales de tu app

  1. En el navegador de proyectos, haz clic en la raíz de tu proyecto.
  2. En el área principal del editor, selecciona el destino principal de la aplicación en la lista TARGETS.
  3. Selecciona la pestaña Info en la parte superior del área del editor.
  4. Coloca el cursor sobre la última fila de la sección Propiedades de destino personalizadas de iOS y haz clic en el botón + que aparece.

Agrega una clave de segmentación nueva a las propiedades de segmentación de iOS

  1. En la columna Clave, escribe GIDClientID.
  2. En la columna Value, pega el ID de cliente que copiaste de Google Cloud Console.

Agrega GIDClientID al destino principal de la app

  1. Abre el archivo plist que descargaste de la consola de Google Cloud.
  2. Copia el valor de Reversed Client ID.

Archivo plist de la consola de Google Cloud

  1. Expande URL Types en la parte inferior de la pestaña Info.
  2. Selecciona el botón +.
  3. Ingresa el ID de cliente revertido en el cuadro URL Schemes.

Agrega la clave URLSchemes al destino de la aplicación principal

Ahora sí podemos comenzar a agregar el botón de acceso a nuestra app.

5. Agrega el botón de acceso

Con el proyecto de Xcode configurado, es hora de comenzar a agregar el botón de acceso con Google a la app.

La lógica principal de este paso es la llamada a GIDSignIn.sharedInstance.signIn. Este método inicia el proceso de autenticación y le entrega el control al SDK de Sign in with Google para que le presente el flujo de Sign in with Google al usuario.

SwiftUI

  1. Busca el archivo ContentView.swift en el navegador del proyecto de Xcode.
  2. Reemplaza el contenido de este archivo por el siguiente texto:
import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack {
      GoogleSignInButton(action: handleSignInButton).padding()
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }
      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }
}

#Preview {
  ContentView()
}

Botón de Acceder con Google del framework de SwiftUI en el simulador de iOS

UIKit

  1. Busca el archivo ViewController.swift en el navegador del proyecto de Xcode.
  2. Reemplaza el contenido de este archivo por el siguiente texto:
import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }
}

Botón de Acceder con Google del framework de UIKit en el simulador de iOS

Cómo ver el botón de acceso

Inicia tu app en el simulador. Verás el botón Acceder con Google, pero aún no funcionará correctamente. Esto es normal, ya que aún debes implementar el código para controlar el redireccionamiento a tu app después de que el usuario se autentique.

6. Personaliza el botón de acceso

Puedes personalizar el botón predeterminado de Acceder con Google para que se adapte mejor al tema de tu app. El SDK de Sign in with Google te permite modificar el esquema de colores y el estilo del botón.

SwiftUI

El botón predeterminado se agrega a la página con esta línea de código:

GoogleSignInButton(action: handleSignInButton)

El GoogleSignInButton se personaliza pasando parámetros a su inicializador. El siguiente código hará que el botón de acceso se muestre en modo oscuro.

  1. Abre ContentView.swift.
  2. Actualiza el inicializador de GoogleSignInButton para que contenga los siguientes valores:
GoogleSignInButton(
  scheme: .dark,  // Options: .light, .dark, .auto
  style: .standard,  // Options: .standard, .wide, .icon
  state: .normal,  // Options: .normal, .disabled
  action: handleSignInButton
).padding()

Botón de acceso con Google en modo oscuro del framework de SwiftUI en el simulador de iOS

Para obtener más información sobre las opciones de personalización, consulta la Referencia del framework de GoogleSignInSwift.

UIKit

El botón predeterminado se crea con estas líneas de código:

// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()

// Add the button to your view
view.addSubview(signInButton)

El GIDSignInButton se personaliza configurando propiedades en la instancia del botón. El siguiente código hará que el botón de acceso se muestre en modo oscuro.

  1. Abre ViewController.swift.
  2. Agrega las siguientes líneas de código inmediatamente antes de agregar el botón de acceso a la vista en la función viewDidLoad:
// Set the width and color of the sign-in button
signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark  // Options: .dark, .light

Botón de acceso con Google en modo oscuro del framework de UIKit en el simulador de iOS

Para obtener más información sobre la personalización, consulta la Referencia del framework de GoogleSignIn.

7. Controla la URL de redireccionamiento de autenticación

Con el botón de acceso agregado, el siguiente paso es controlar el redireccionamiento que se produce después de que un usuario se autentica. Después de la autenticación, Google devuelve una URL con un código de autorización temporal. Para completar el proceso de acceso, un controlador intercepta esta URL y la pasa al SDK de Acceder con Google para que se intercambie por un token de ID firmado (JWT).

SwiftUI

  1. Abre el archivo que contiene tu struct App. El nombre de este archivo se basa en tu proyecto, por lo que será algo como YourProjectNameApp.swift.
  2. Reemplaza el contenido de este archivo por el siguiente texto:
import GoogleSignIn
import SwiftUI

@main
struct iOS_Sign_in_with_Google_App: App {
  var body: some Scene {
    WindowGroup {
      ContentView()

        .onOpenURL { url in
          GIDSignIn.sharedInstance.handle(url)
        }
    }
  }
}

UIKit

  1. Abre AppDelegate.swift.
  2. Agrega la siguiente importación en la parte superior del archivo:
import GoogleSignIn
  1. Agrega la siguiente función de controlador de autenticación dentro de la clase AppDelegate. Un buen lugar para colocarlo es inmediatamente después de la llave de cierre del método application(_:didFinishLaunchingWithOptions:):
func application(
  _ app: UIApplication,
  open url: URL,
  options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
  var handled: Bool

  handled = GIDSignIn.sharedInstance.handle(url)
  if handled {
    return true
  }
  // If not handled by this app, return false.
  return false
}

Después de realizar estos cambios, tu archivo AppDelegate.swift debería verse así:

import GoogleSignIn
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // Override point for customization after application launch.
    return true
  }

  func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
    var handled: Bool

    handled = GIDSignIn.sharedInstance.handle(url)
    if handled {
      return true
    }
    // If not handled by this app, return false.
    return false
  }

  // MARK: UISceneSession Lifecycle

  func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(
      name: "Default Configuration",
      sessionRole: connectingSceneSession.role
    )
  }

  func application(
    _ application: UIApplication,
    didDiscardSceneSessions sceneSessions: Set<UISceneSession>
  ) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
  }
}

Prueba el flujo de acceso

Ahora puedes probar el flujo de acceso completo.

Ejecuta la app y presiona el botón de acceso. Después de que te autentiques, Google mostrará una pantalla de consentimiento en la que podrás otorgar permiso a la app para que acceda a tu información. Una vez que apruebes el acceso, se completará el ingreso y volverás a la app.

Cuando el flujo de acceso se completa correctamente, el SDK de Sign in with Google almacena de forma segura las credenciales del usuario en el llavero del dispositivo. Estas credenciales se pueden usar más adelante para permitir que un usuario permanezca conectado en los inicios posteriores de la app.

8. Agrega un botón para salir

Ahora que el acceso funciona, el siguiente paso es agregar un botón para salir y actualizar la IU para que refleje el estado de acceso actual del usuario. Cuando se accede correctamente, el SDK proporciona un objeto GIDGoogleUser. Este objeto contiene una propiedad profile con información básica, como el nombre y el correo electrónico del usuario, que usarás para personalizar la IU.

SwiftUI

  1. Abre el archivo ContentView.swift.
  2. Agrega una variable de estado en la parte superior de tu struct ContentView. Esta variable contendrá la información del usuario después de que acceda. Como es una variable @State, SwiftUI actualizará automáticamente tu IU cada vez que cambie su valor:
struct ContentView: View {
  @State private var user: GIDGoogleUser?
}
  1. Reemplaza el body actual de tu struct ContentView por el siguiente VStack. Esto verificará si la variable de estado user contiene un usuario. Si es así, se mostrará un mensaje de bienvenida y un botón para salir de la cuenta. Si no es así, se mostrará el botón original de Acceder con Google:
var body: some View {
  VStack {
    // Check if the user is signed in.
    if let user = user {
      // If signed in, show a welcome message and the sign-out button.
      Text("Hello, \(user.profile?.givenName ?? "User")!")
        .font(.title)
        .padding()

      Button("Sign Out", action: signOut)
        .buttonStyle(.borderedProminent)

    } else {
      // If not signed in, show the "Sign in with Google" button.
      GoogleSignInButton(
        scheme: .dark,  // Options: .light, .dark, .auto
        style: .standard,  // Options: .standard, .wide, .icon
        state: .normal,  // Options: .normal, .disabled
        action: handleSignInButton
      ).padding()
    }
  }
}
  1. Actualiza el bloque de finalización handleSignInButton para asignar signInResult.user a tu nueva variable user. Esto es lo que activa la IU para cambiar a la vista de acceso:
func handleSignInButton() {
  // Find the current window scene.
  guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
    print("There is no active window scene")
    return
  }

  // Get the root view controller from the window scene.
  guard
    let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
      .rootViewController
  else {
    print("There is no key window or root view controller")
    return
  }

  // Start the sign-in process.
  GIDSignIn.sharedInstance.signIn(
    withPresenting: rootViewController
  ) { signInResult, error in
    guard let result = signInResult else {
      // Inspect error
      print("Error signing in: \(error?.localizedDescription ?? "No error description")")
      return
    }

    DispatchQueue.main.async {
      self.user = result.user
    }

    // If sign in succeeded, display the app's main content View.
    print("ID Token: \(result.user.idToken?.tokenString ?? "")")
  }
}
  1. Agrega una nueva función signOut a la parte inferior de tu struct ContentView para que la llame el botón de cierre de sesión:
func signOut() {
  GIDSignIn.sharedInstance.signOut()
  // After signing out, set the `user` state variable to `nil`.
  self.user = nil
}

Inicia la app y accede. Deberías ver el cambio en la IU después de una autenticación exitosa.

Estado de acceso del framework de SwiftUI en el simulador de iOS

Después de realizar estos cambios, tu archivo ContentView.swift debería verse así:

import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {

  @State private var user: GIDGoogleUser?

  var body: some View {
    VStack {
      // Check if the user is signed in.
      if let user = user {
        // If signed in, show a welcome message and the sign-out button.
        Text("Hello, \(user.profile?.givenName ?? "User")!")
          .font(.title)
          .padding()

        Button("Sign Out", action: signOut)
          .buttonStyle(.borderedProminent)

      } else {
        // If not signed in, show the "Sign in with Google" button.
        GoogleSignInButton(
          scheme: .dark,  // Options: .light, .dark, .auto
          style: .standard,  // Options: .standard, .wide, .icon
          state: .normal,  // Options: .normal, .disabled
          action: handleSignInButton
        ).padding()
      }
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      DispatchQueue.main.async {
        self.user = result.user
      }

      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }

  func signOut() {
    GIDSignIn.sharedInstance.signOut()
    // After signing out, set the `user` state variable to `nil`.
    self.user = nil
  }
}

#Preview {
  ContentView()
}

UIKit

  1. Abre ViewController.swift.
  2. En la parte superior de ViewController, justo debajo de donde declaraste signInButton, agrega un botón de cierre de sesión y una etiqueta de bienvenida:
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
  1. Agrega la siguiente función a la parte inferior de ViewController. Esta función mostrará una IU diferente al usuario según su estado de acceso:
private func updateUI(for user: GIDGoogleUser?) {
  if let user = user {
    // User is signed in.
    signInButton.isHidden = true
    signOutButton.isHidden = false
    welcomeLabel.isHidden = false
    welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
  } else {
    // User is signed out.
    signInButton.isHidden = false
    signOutButton.isHidden = true
    welcomeLabel.isHidden = true
  }
}
  1. En la parte inferior de la función viewDidLoad, agrega el siguiente código para agregar la etiqueta de bienvenida y el botón de cierre de sesión a la vista:
// --- Set up the Welcome Label ---
welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
welcomeLabel.textAlignment = .center
welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
view.addSubview(welcomeLabel)

NSLayoutConstraint.activate([
  welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
])

// --- Set up the Sign-Out Button ---
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
view.addSubview(signOutButton)

NSLayoutConstraint.activate([
  signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
])

signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

// --- Set Initial UI State ---
updateUI(for: nil)
  1. Actualiza la función signInButtonTapped para llamar al método UpdateUI cuando se acceda correctamente:
@objc func signInButtonTapped() {
  // Start the sign-in process.
  GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
    guard let result = signInResult else {
      // Inspect error
      print("Error signing in: \(error?.localizedDescription ?? "No error description")")
      return
    }

    // If sign in succeeded, print the ID token.
    print("ID Token: \(result.user.idToken?.tokenString ?? "")")

    DispatchQueue.main.async {
      self.updateUI(for: result.user)
    }
  }
}
  1. Por último, agrega una función signOutButtonTapped al ViewController para controlar el proceso de cierre de sesión:
@objc func signOutButtonTapped() {
  GIDSignIn.sharedInstance.signOut()
  // Update the UI for the signed-out state.
  updateUI(for: nil)
}

Inicia la app y accede. Deberías ver el cambio en la IU después de una autenticación exitosa.

Estado de acceso del framework de UIKit en el simulador de iOS

Después de realizar estos cambios, tu archivo ViewController.swift debería verse así:

import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()
  let signOutButton = UIButton(type: .system)
  let welcomeLabel = UILabel()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the width and color of the sign-in button
    signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
    signInButton.colorScheme = .dark  // Options: .dark, .light

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)

    // --- Set up the Welcome Label ---
    welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
    welcomeLabel.textAlignment = .center
    welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
    view.addSubview(welcomeLabel)

    NSLayoutConstraint.activate([
      welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
    ])

    // --- Set up the Sign-Out Button ---
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.setTitle("Sign Out", for: .normal)
    view.addSubview(signOutButton)

    NSLayoutConstraint.activate([
      signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
    ])

    signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

    // --- Set Initial UI State ---
    updateUI(for: nil)
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")

      DispatchQueue.main.async {
        self.updateUI(for: result.user)
      }
    }
  }

  private func updateUI(for user: GIDGoogleUser?) {
    if let user = user {
      // User is signed in.
      signInButton.isHidden = true
      signOutButton.isHidden = false
      welcomeLabel.isHidden = false
      welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
    } else {
      // User is signed out.
      signInButton.isHidden = false
      signOutButton.isHidden = true
      welcomeLabel.isHidden = true
    }
  }

  @objc func signOutButtonTapped() {
    GIDSignIn.sharedInstance.signOut()
    // Update the UI for the signed-out state.
    updateUI(for: nil)
  }
}

9. Restablece el estado de acceso de un usuario

Para mejorar la experiencia de los usuarios recurrentes, el siguiente paso es restablecer su estado de acceso cuando se inicie la app. La llamada a restorePreviousSignIn usa las credenciales guardadas en el llavero para volver a acceder de forma silenciosa, lo que garantiza que el usuario no tenga que completar el flujo de acceso cada vez.

SwiftUI

  1. Abre ContentView.swift.
  2. Agrega el siguiente código directamente después de VStack dentro de la variable body:
.onAppear {
  // On appear, try to restore a previous sign-in.
  GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
    // This closure is called when the restoration is complete.
    if let user = user {
      // If a user was restored, update the `user` state variable.
      DispatchQueue.main.async {
        self.user = user
      }

      // Print the ID token to the console when restored.
      print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
    }
  }
}

Tu archivo ContentView.swift debería verse así:

import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {

  @State private var user: GIDGoogleUser?

  var body: some View {
    VStack {
      // Check if the user is signed in.
      if let user = user {
        // If signed in, show a welcome message and the sign-out button.
        Text("Hello, \(user.profile?.givenName ?? "User")!")
          .font(.title)
          .padding()

        Button("Sign Out", action: signOut)
          .buttonStyle(.borderedProminent)

      } else {
        // If not signed in, show the "Sign in with Google" button.
        GoogleSignInButton(
          scheme: .dark,  // Options: .light, .dark, .auto
          style: .standard,  // Options: .standard, .wide, .icon
          state: .normal,  // Options: .normal, .disabled
          action: handleSignInButton
        ).padding()
      }
    }

    .onAppear {
      // On appear, try to restore a previous sign-in.
      GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
        // This closure is called when the restoration is complete.
        if let user = user {
          // If a user was restored, update the `user` state variable.
          DispatchQueue.main.async {
            self.user = user
          }

          // Print the ID token to the console when restored.
          print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
        }
      }
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      DispatchQueue.main.async {
        self.user = result.user
      }

      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }

  func signOut() {
    GIDSignIn.sharedInstance.signOut()
    // After signing out, set the `user` state variable to `nil`.
    self.user = nil
  }
}

#Preview {
  ContentView()
}

UIKit

  1. Abre ViewController.swift.
  2. Agrega la siguiente llamada restorePreviousSignIn al final del método viewDidLoad:
// Attempt to restore a previous sign-in session
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
  if let user = user {
    print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")

    // Print the ID token when a session is restored.
    print("Restored ID Token: \(user.idToken?.tokenString ?? "")")

    // On success, update the UI for the signed-in state on the main thread.
    DispatchQueue.main.async {
      self.updateUI(for: user)
    }
  }
}

Tu archivo ViewController.swift debería verse de la siguiente manera:

import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()
  let signOutButton = UIButton(type: .system)
  let welcomeLabel = UILabel()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the width and color of the sign-in button
    signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
    signInButton.colorScheme = .dark  // Options: .dark, .light

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)

    // --- Set up the Welcome Label ---
    welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
    welcomeLabel.textAlignment = .center
    welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
    view.addSubview(welcomeLabel)

    NSLayoutConstraint.activate([
      welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
    ])

    // --- Set up the Sign-Out Button ---
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.setTitle("Sign Out", for: .normal)
    view.addSubview(signOutButton)

    NSLayoutConstraint.activate([
      signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
    ])

    signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

    // --- Set Initial UI State ---
    updateUI(for: nil)

    // Attempt to restore a previous sign-in session
    GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
      if let user = user {
        print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")

        // Print the ID token when a session is restored.
        print("Restored ID Token: \(user.idToken?.tokenString ?? "")")

        // On success, update the UI for the signed-in state on the main thread.
        DispatchQueue.main.async {
          self.updateUI(for: user)
        }
      }
    }
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")

      DispatchQueue.main.async {
        self.updateUI(for: result.user)
      }
    }
  }

  private func updateUI(for user: GIDGoogleUser?) {
    if let user = user {
      // User is signed in.
      signInButton.isHidden = true
      signOutButton.isHidden = false
      welcomeLabel.isHidden = false
      welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
    } else {
      // User is signed out.
      signInButton.isHidden = false
      signOutButton.isHidden = true
      welcomeLabel.isHidden = true
    }
  }

  @objc func signOutButtonTapped() {
    GIDSignIn.sharedInstance.signOut()
    // Update the UI for the signed-out state.
    updateUI(for: nil)
  }
}

Prueba el acceso silencioso

Después de acceder, cierra la app por completo y vuelve a iniciarla. Deberías ver que ahora accediste automáticamente sin necesidad de presionar el botón.

10. Comprende el token de ID

Si bien el objeto GIDGoogleUser es conveniente para personalizar la IU con el nombre y el correo electrónico del usuario, el dato más importante que devuelve el SDK es el token de ID.

En este codelab, se usa una herramienta en línea para inspeccionar el contenido del JWT. En una app de producción, debes enviar este token de ID a tu servidor de backend. Tu servidor debe verificar la integridad del token de ID y usar el JWT para hacer algo más significativo, como crear una cuenta nueva en tu plataforma de backend o establecer una nueva sesión para el usuario.

Accede al token JWT y decodifícalo

  1. Inicia tu app.
  2. Abre la consola de Xcode. Deberías ver un ID de token impreso. Se verá de la siguiente manera: eyJhbGciOiJSUzI1Ni ... Hecz6Wm4Q
  3. Copia el token de ID y usa una herramienta en línea, como jwt.io, para decodificar el JWT.

El JWT decodificado se verá de la siguiente manera:

{
  "alg": "RS256",
  "kid": "c8ab71530972bba20b49f78a09c9852c43ff9118",
  "typ": "JWT"
}
{
  "iss": "https://accounts.google.com",
  "azp": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
  "aud": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "email": "example@example.com",
  "email_verified": true,
  "at_hash": "JyCYDmHtzhjkb0-qJhKsMg",
  "name": "Kimya",
  "picture": "https://lh3.googleusercontent.com/a/ACg8ocIyy4VoR31t_n0biPVcScBHwZOCRaKVDb_MoaMYep65fyqoAw=s96-c",
  "given_name": "Kimya",
  "iat": 1758645896,
  "exp": 1758649496
}

Campos de token destacados

El token de ID decodificado contiene campos con diferentes propósitos. Si bien algunos son fáciles de entender, como el nombre y el correo electrónico, otros los usa tu servidor de backend para la verificación.

Es especialmente importante comprender el siguiente campo:

  • sub: El campo sub es un identificador único y permanente para la Cuenta de Google del usuario. Un usuario puede cambiar su correo electrónico o nombre principal, pero su ID de sub nunca cambiará. Esto hace que el campo sub sea el valor perfecto para usar como clave principal de las cuentas de usuario de tu backend.

En Obtén información del usuario a partir del token de ID, encontrarás más información sobre el significado de todos los campos del token.

11. Protege tu app con la Verificación de aplicaciones

Te recomendamos que habilites la Verificación de aplicaciones para garantizar que solo tu app pueda acceder a los extremos de OAuth 2.0 de Google en nombre de tu proyecto. La Verificación de aplicaciones funciona verificando que las solicitudes a tus servicios de backend provengan de tu app auténtica en un dispositivo real y no adulterado.

En esta sección, se muestra cómo integrar la Verificación de aplicaciones en tu app y configurarla para la depuración en un simulador y para una compilación de producción que se ejecute en un dispositivo real.

Configuración de la consola

Para integrar App Check en tu aplicación, debes realizar una configuración única en las consolas de Google Cloud y Firebase. Esto implica habilitar la Verificación de aplicaciones para tu cliente de OAuth de iOS en Google Cloud Console, crear una clave de API para usarla con el proveedor de depuración de la Verificación de aplicaciones y vincular tu proyecto de Google Cloud a Firebase.

Habilita App Check en la consola de Google Cloud

  1. Navega a la lista de Clientes asociados con tu proyecto de Google Cloud.
  2. Selecciona el ID de cliente de OAuth 2.0 que creaste para tu app para iOS.
  3. Activa la Verificación de aplicaciones en Google Identity para iOS.

Página de edición del cliente de OAuth con el botón de activación de App Check

  1. Haz clic en Guardar.

Crea una clave de API

  1. Navega a la página Biblioteca de APIs de tu proyecto de Google Cloud.
  2. Ingresa API de Firebase App Check en la barra de búsqueda.

Página de la biblioteca de API de la consola de Google Cloud

  1. Selecciona y habilita la API de Firebase App Check.
  2. Navega a APIs & Services y selecciona Credentials en el menú de navegación.
  3. Selecciona Crear credenciales en la parte superior de la página.

Página de credenciales de API de Google Cloud Console

  1. Asigna un nombre a esta clave de API.
  2. Selecciona Apps para iOS en Restricciones de aplicaciones.
  3. Agrega el identificador del paquete de tu app como una aplicación aprobada.
  4. Selecciona Restringir clave en Restricciones de API.
  5. Selecciona API de Firebase App Check en el menú desplegable.
  6. Selecciona Crear.

Página de creación de la clave de API de la consola de Google Cloud

  1. Copia la clave de API que se creó. La necesitarás en un paso posterior.

Agrega Firebase a tu proyecto de Google Cloud

  1. Ve a Firebase console.
  2. Selecciona Para comenzar, configura un proyecto de Firebase.
  3. Selecciona Agregar Firebase al proyecto de Google Cloud.

Agrega Firebase a un proyecto de Google Cloud existente

  1. Selecciona un proyecto de Google Cloud en el menú desplegable y continúa con el flujo de registro.
  2. Selecciona Agregar Firebase.
  3. Cuando tu proyecto de Firebase esté listo, selecciona Continuar para abrirlo.

Integración de código del cliente

Una vez que el proyecto de Google Cloud esté configurado para App Check, es hora de escribir el código del cliente para habilitarlo. El proveedor que se usa para la certificación es diferente en los entornos de producción y de depuración. Una app de producción en un dispositivo real usa el servicio integrado App Attest de Apple para demostrar su autenticidad. Sin embargo, como el simulador de iOS no puede proporcionar este tipo de certificación, el entorno de depuración requiere un proveedor de depuración especial al que se le pasa una clave de API.

El siguiente código controla ambas situaciones usando una directiva del compilador para seleccionar automáticamente el proveedor correcto en el momento de la compilación.

SwiftUI

  1. Abre el archivo principal de la app.
  2. Define la siguiente clase AppDelegate después de las importaciones y antes del atributo @main:
class AppDelegate: NSObject, UIApplicationDelegate {
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        } else {
          print("GIDSignIn configured for App Check.")
        }
      }
    #endif

    return true
  }
}
  1. Reemplaza "YOUR_API_KEY" en el código proporcionado por la clave de API que copiaste de la consola de Google Cloud.
  2. Agrega la siguiente línea dentro de tu struct App, justo antes de la variable body. Esto registra tu clase AppDelegate con el ciclo de vida de la app, lo que le permite responder al inicio de la app y a otros eventos del sistema:
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

Tu archivo principal de la app debería verse así:

import GoogleSignIn
import SwiftUI

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        } else {
          print("GIDSignIn configured for App Check.")
        }
      }
    #endif

    return true
  }
}

@main
struct iOS_Sign_in_with_Google_App: App {

  @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

  var body: some Scene {
    WindowGroup {
      ContentView()

        .onOpenURL { url in
          GIDSignIn.sharedInstance.handle(url)
        }
    }
  }
}

UIKit

  1. Abre AppDelegate.swift.
  2. Actualiza el método application(_:didFinishLaunchingWithOptions:) para que contenga la inicialización de Verificación de aplicaciones:
func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

  #if targetEnvironment(simulator)
    // Configure for debugging on a simulator.
    // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
    let apiKey = "YOUR_API_KEY"
    GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
      if let error {
        print("Error configuring GIDSignIn debug provider: \(error)")
      }
    }
  #else
    // Configure GIDSignIn for App Check on a real device.
    GIDSignIn.sharedInstance.configure { error in
      if let error {
        print("Error configuring GIDSignIn for App Check: \(error)")
      }
    }
  #endif

  return true
}
  1. Reemplaza "YOUR_API_KEY" en el código proporcionado por la clave de API que copiaste de la consola de Google Cloud.

Tu archivo AppDelegate.swift debería verse de la siguiente manera:

import GoogleSignIn
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        }
      }
    #endif

    return true
  }

  func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
    var handled: Bool

    handled = GIDSignIn.sharedInstance.handle(url)
    if handled {
      return true
    }
    // If not handled by this app, return false.
    return false
  }

  // MARK: UISceneSession Lifecycle

  func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(
      name: "Default Configuration",
      sessionRole: connectingSceneSession.role
    )
  }

  func application(
    _ application: UIApplication,
    didDiscardSceneSessions sceneSessions: Set<UISceneSession>
  ) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
  }
}

Prueba la Verificación de aplicaciones en el simulador

  1. En la barra de menú de Xcode, navega a Product > Scheme > Edit Scheme.
  2. Selecciona Ejecutar en el menú de navegación.
  3. Selecciona la pestaña Arguments.
  4. En la sección Arguments Passed on Launch, selecciona + y agrega -FIRDebugEnabled. Este argumento de inicio habilita el registro de depuración de Firebase.
  5. Selecciona Cerrar.

Página del editor de argumentos de Xcode

  1. Inicia tu app en el simulador.
  2. Copia el token de depuración de App Check que se imprimió en la consola de Xcode.

Token de depuración de App Check en la consola de Xcode

  1. Navega a tu proyecto en Firebase console.
  2. Expande la sección Compilar en el menú de navegación.
  3. Selecciona Verificación de aplicaciones.
  4. Selecciona la pestaña Apps.
  5. Coloca el cursor sobre la app y selecciona el ícono de menú de tres puntos.

Configuración de la Verificación de aplicaciones de Firebase

  1. Selecciona Administrar tokens de depuración.
  2. Selecciona Agregar token de depuración.
  3. Asigna un nombre a tu token de depuración y pega el token de depuración que copiaste antes para el valor.
  4. Selecciona Guardar para registrar tu token.

Administración de tokens de depuración de la Verificación de aplicaciones de Firebase

  1. Regresa al simulador y accede.

Las métricas pueden tardar varios minutos en aparecer en la consola. Una vez que lo hagan, puedes confirmar que App Check funciona buscando un aumento en las solicitudes Verificadas en uno de los siguientes dos lugares:

  • En la sección App Check de Firebase console, en la pestaña APIs

Métricas de la Verificación de aplicaciones de Firebase

  • En la página de edición de tu cliente de OAuth en la consola de Google Cloud

Métricas de App Check de la consola de Google Cloud

Después de supervisar las métricas de la Verificación de aplicaciones de tu app y confirmar que se verifican las solicitudes legítimas, debes habilitar la aplicación de la Verificación de aplicaciones. Una vez que se aplique, la Verificación de aplicaciones rechazará todas las solicitudes no verificadas, lo que garantizará que solo el tráfico de tu app auténtica pueda acceder a los extremos de OAuth 2.0 de Google en nombre de tu proyecto.

12. Recursos adicionales

¡Felicitaciones!

Configuraste un cliente de OAuth 2.0 para iOS, agregaste un botón de Acceder con Google a una app para iOS, aprendiste a personalizar la apariencia del botón, decodificaste un token de ID de JWT y habilitaste App Check para tu app.

Estos vínculos pueden ayudarte con los próximos pasos:

Preguntas frecuentes