Einer iOS-App den Google Log-in hinzufügen

1. Hinweis

In diesem Codelab erfahren Sie, wie Sie eine iOS-Anwendung erstellen, in der „Mit Google anmelden“ implementiert ist und die in einem Simulator ausgeführt wird. Es werden Implementierungen mit SwiftUI und UIKit bereitgestellt.

SwiftUI ist das moderne UI-Framework von Apple für die Entwicklung neuer Apps. Damit lassen sich Benutzeroberflächen für alle Apple-Plattformen aus einer einzigen gemeinsamen Codebasis erstellen. Mindestens iOS 13 ist erforderlich.

UIKit ist das ursprüngliche und grundlegende UI-Framework von Apple für iOS. Sie bietet Abwärtskompatibilität für ältere iOS-Versionen. Daher ist es eine gute Wahl für etablierte Apps, die eine Vielzahl älterer Geräte unterstützen müssen.

Sie können dem Pfad für das Framework folgen, das Ihren Entwicklungsanforderungen am besten entspricht.

Vorbereitung

Lerninhalte

  • Google Cloud-Projekt erstellen
  • OAuth-Clients in der Google Cloud Console erstellen
  • „Über Google anmelden“ für Ihre iOS-App implementieren
  • Schaltfläche „Über Google anmelden“ anpassen
  • ID-Token decodieren
  • App Check für Ihre iOS-App aktivieren

Voraussetzungen

  • Eine aktuelle Version von Xcode
  • Ein Computer mit macOS, der die Systemanforderungen für die installierte Version von Xcode erfüllt

Dieses Codelab wurde mit Xcode 16.3 und dem iOS 18.3-Simulator erstellt. Sie sollten für die Entwicklung die aktuelle Version von Xcode verwenden.

2. Neues Xcode-Projekt erstellen

  1. Öffnen Sie Xcode und wählen Sie Create a new Xcode project (Neues Xcode-Projekt erstellen) aus.
  2. Wählen Sie den Tab iOS aus, wählen Sie die Vorlage App aus und klicken Sie auf Weiter.

Seite mit Vorlagen zum Erstellen von Xcode-Projekten

  1. In den Projektoptionen:
    • Geben Sie den Produktnamen ein.
    • Wählen Sie optional Ihr Team aus.
    • Geben Sie Ihre Organisations-ID ein.
    • Notieren Sie sich die generierte Bundle-ID. Sie benötigen sie später noch einmal.
    • Wählen Sie für die Schnittstelle eine der folgenden Optionen aus:
      • SwiftUI für eine SwiftUI-basierte App.
      • Storyboard für eine UIKit-basierte App.
    • Wählen Sie Swift als Sprache aus.
    • Klicken Sie auf Weiter und wählen Sie einen Speicherort für Ihr Projekt aus.

Seite „Xcode project options“

3. OAuth-Client erstellen

Damit Ihre App mit den Authentifizierungsdiensten von Google kommunizieren kann, müssen Sie eine OAuth-Client-ID erstellen. Dazu ist ein Google Cloud-Projekt erforderlich. In den folgenden Schritten wird beschrieben, wie Sie ein Projekt und eine OAuth-Client-ID erstellen.

Google Cloud-Projekt auswählen oder erstellen

  1. Rufen Sie die Google Cloud Console auf und wählen Sie ein Projekt aus oder erstellen Sie eines. Wenn Sie ein vorhandenes Projekt auswählen, werden Sie in der Console automatisch zum nächsten erforderlichen Schritt weitergeleitet.

Seite zur Projektauswahl in der Google Cloud Console

  1. Geben Sie einen Namen für Ihr neues Google Cloud-Projekt ein.
  2. Wählen Sie Erstellen aus.

Seite zur Projektauswahl in der Google Cloud Console

Wenn Sie bereits einen Zustimmungsbildschirm für das ausgewählte Projekt konfiguriert haben, werden Sie jetzt nicht dazu aufgefordert. In diesem Fall können Sie diesen Abschnitt überspringen und mit OAuth 2.0-Client erstellen fortfahren.

  1. Wählen Sie Zustimmungsbildschirm konfigurieren aus.

Google Cloud Console-Seite zum Erstellen von OAuth-Clients mit der Anforderung, den Zustimmungsbildschirm zu konfigurieren

  1. Wählen Sie auf der Branding-Seite Jetzt starten aus.

Seite „Branding in der Google Cloud Console“

  1. Füllen Sie auf der Seite „Projektkonfiguration“ die folgenden Felder aus:
    • App-Informationen: Geben Sie einen Namen und eine E-Mail-Adresse für den Nutzersupport für Ihre App ein. Diese E-Mail-Adresse wird öffentlich angezeigt, damit Nutzer Sie mit Fragen zu ihrer Einwilligung kontaktieren können.
    • Zielgruppe: Wählen Sie Extern aus.
    • Kontaktdaten: Geben Sie eine E‑Mail-Adresse ein, über die Google Sie bezüglich Ihres Projekts kontaktieren kann.
    • Lesen Sie die Richtlinie zu Nutzerdaten für Google API-Dienste.
    • Klicken Sie auf Erstellen.

Konfigurationsseite für das Client-Branding in der Google Cloud Console

  1. Wählen Sie im Navigationsmenü die Seite Clients aus.
  2. Klicken Sie auf Create Client.

Seite „Google Cloud-Projektclients“

OAuth 2.0-Client erstellen

  1. Wählen Sie als Anwendungstyp die Option iOS aus.
  2. Geben Sie einen Namen für den Client ein.
  3. Geben Sie die im letzten Schritt erstellte Bundle-ID ein.
  4. Geben Sie die Team-ID ein, die Ihrem Team von Apple zugewiesen wurde. Dieser Schritt ist vorerst optional. Eine Team-ID ist jedoch erforderlich, um App Check später in diesem Codelab zu aktivieren.
  5. Wählen Sie Erstellen aus.

Eingabeseite für OAuth-Clientdetails

  1. Kopieren Sie die Client-ID aus dem Dialogfeld. Sie benötigen sie später.
  2. Laden Sie die PLIST-Datei herunter, um später darauf zuzugreifen.

Dialogfeld „OAuth-Client-ID erstellt“

4. Xcode-Projekt konfigurieren

Im nächsten Schritt richten Sie Ihr Xcode-Projekt für die Verwendung des „Mit Google anmelden“-SDK ein. Dazu müssen Sie das SDK als Abhängigkeit in Ihr Projekt einbinden und Ihre Projekteinstellungen mit einer eindeutigen Client-ID konfigurieren. Mit dieser ID kann das SDK während des Anmeldevorgangs sicher mit dem Authentifizierungsdienst von Google kommunizieren.

Abhängigkeiten für „Über Google anmelden“ installieren

  1. Öffnen Sie Ihr Xcode-Projekt.
  2. Gehen Sie zu File > Add Package Dependencies (Datei > Paketabhängigkeiten hinzufügen).
  3. Geben Sie in die Suchleiste die URL für das Repository „Mit Google anmelden“ ein: https://github.com/google/GoogleSignIn-iOS.

„Mit Google anmelden“-Abhängigkeit in Swift Package Manager finden

  1. Wählen Sie Paket hinzufügen aus.
  2. Wählen Sie das primäre Anwendungsziel für das GoogleSignIn-Paket aus.
  3. Wenn Sie SwiftUI verwenden, wählen Sie das Hauptanwendungsziel für das Paket GoogleSignInSwift aus. Wenn Sie UIKit verwenden möchten, wählen Sie kein Ziel für dieses Paket aus.
  4. Wählen Sie Paket hinzufügen aus.

„Mit Google anmelden“-Abhängigkeit zu Ihrem Projekt hinzufügen

Anmeldedaten für Ihre App konfigurieren

  1. Klicken Sie im Projektnavigator auf das Stammverzeichnis Ihres Projekts.
  2. Wählen Sie im Hauptbearbeitungsbereich in der Liste ZIELE das Hauptanwendungsziel aus.
  3. Wählen Sie oben im Editorbereich den Tab Info aus.
  4. Bewegen Sie den Mauszeiger auf die letzte Zeile im Bereich Benutzerdefinierte iOS-Ziel-Properties und klicken Sie auf die Schaltfläche +.

Neuen Zielschlüssel zu iOS-Zieleigenschaften hinzufügen

  1. Geben Sie in der Spalte Schlüssel GIDClientID ein.
  2. Fügen Sie in der Spalte Wert die Client-ID ein, die Sie aus der Google Cloud Console kopiert haben.

GIDClientID dem Haupt-App-Ziel hinzufügen

  1. Öffnen Sie die plist-Datei, die Sie aus der Google Cloud Console heruntergeladen haben.
  2. Kopieren Sie den Wert für Reversed Client ID (Umgekehrte Client-ID).

Google Cloud Console-Plist-Datei

  1. Maximieren Sie unten auf dem Tab Info den Bereich URL-Typen.
  2. Wählen Sie die Schaltfläche + aus.
  3. Geben Sie die Reversed Client ID (umgekehrte Client-ID) in das Feld URL Schemes (URL-Schemas) ein.

Schlüssel „URLSchemes“ dem Hauptanwendungsziel hinzufügen

Jetzt können wir unserer App die Anmeldeschaltfläche hinzufügen.

5. Anmeldeschaltfläche hinzufügen

Nachdem das Xcode-Projekt konfiguriert wurde, können Sie der App die Schaltfläche „Über Google anmelden“ hinzufügen.

Die Kernlogik für diesen Schritt ist der Aufruf von GIDSignIn.sharedInstance.signIn. Mit dieser Methode wird der Authentifizierungsprozess gestartet und die Steuerung an das „Mit Google anmelden“-SDK übergeben, damit der „Mit Google anmelden“-Ablauf für den Nutzer präsentiert wird.

SwiftUI

  1. Suchen Sie im Xcode-Projektnavigator nach der Datei ContentView.swift.
  2. Ersetzen Sie den Inhalt dieser Datei durch den folgenden Text:
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()
}

SwiftUI-Framework: Schaltfläche „Über Google anmelden“ im iOS-Simulator

UIKit

  1. Suchen Sie im Xcode-Projektnavigator nach der Datei ViewController.swift.
  2. Ersetzen Sie den Inhalt dieser Datei durch den folgenden Text:
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 ?? "")")
    }
  }
}

UIKit-Framework: Schaltfläche „Über Google anmelden“ im iOS-Simulator

Anmeldeschaltfläche ansehen

Starten Sie die App im Simulator. Sie sehen die Schaltfläche „Mit Google anmelden“, aber sie funktioniert noch nicht richtig. Das ist normal, da Sie den Code noch implementieren müssen, um die Weiterleitung zurück zu Ihrer App nach der Authentifizierung des Nutzers zu verarbeiten.

6. Anmeldeschaltfläche anpassen

Sie können die Standardschaltfläche „Mit Google anmelden“ an das Design Ihrer App anpassen. Mit dem „Mit Google anmelden“-SDK können Sie das Farbschema und den Stil der Schaltfläche ändern.

SwiftUI

Die Standardschaltfläche wird mit dieser Codezeile auf der Seite eingefügt:

GoogleSignInButton(action: handleSignInButton)

Das GoogleSignInButton wird angepasst, indem Parameter an seinen Initialisierer übergeben werden. Mit dem folgenden Code wird die Schaltfläche „Anmelden“ im Dark Mode angezeigt.

  1. Öffnen Sie ContentView.swift.
  2. Aktualisieren Sie die Initialisierung für GoogleSignInButton, damit sie die folgenden Werte enthält:
GoogleSignInButton(
  scheme: .dark,  // Options: .light, .dark, .auto
  style: .standard,  // Options: .standard, .wide, .icon
  state: .normal,  // Options: .normal, .disabled
  action: handleSignInButton
).padding()

Dunkler Modus für das SwiftUI-Framework für die Schaltfläche „Über Google anmelden“ im iOS-Simulator

Weitere Informationen zu den Anpassungsoptionen finden Sie in der GoogleSignInSwift Framework Reference.

UIKit

Die Standardschaltfläche wird mit diesen Codezeilen erstellt:

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

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

Das GIDSignInButton wird angepasst, indem Eigenschaften für die Schaltflächeninstanz festgelegt werden. Mit dem folgenden Code wird die Schaltfläche „Anmelden“ im Dark Mode angezeigt.

  1. Öffnen Sie ViewController.swift.
  2. Fügen Sie die folgenden Codezeilen direkt vor dem Hinzufügen der Anmeldeschaltfläche zur Ansicht in der Funktion viewDidLoad ein:
// Set the width and color of the sign-in button
signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark  // Options: .dark, .light

Dunkler Modus des UIKit-Frameworks für die Schaltfläche „Über Google anmelden“ im iOS-Simulator

Weitere Informationen zur Anpassung finden Sie in der GoogleSignIn Framework Reference.

7. Authentifizierungs-Weiterleitungs-URL verarbeiten

Nachdem Sie die Anmeldeschaltfläche hinzugefügt haben, müssen Sie die Weiterleitung verarbeiten, die nach der Authentifizierung eines Nutzers erfolgt. Nach der Authentifizierung gibt Google eine URL mit einem temporären Autorisierungscode zurück. Damit der Anmeldevorgang abgeschlossen werden kann, fängt ein Handler diese URL ab und übergibt sie an das „Mit Google anmelden“-SDK, damit sie gegen ein signiertes ID-Token (JWT) eingetauscht wird.

SwiftUI

  1. Öffnen Sie die Datei, die Ihre App-Struktur enthält. Der Name dieser Datei basiert auf Ihrem Projekt, z. B. YourProjectNameApp.swift.
  2. Ersetzen Sie den Inhalt dieser Datei durch den folgenden Text:
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. Öffnen Sie AppDelegate.swift.
  2. Fügen Sie oben in der Datei den folgenden Import hinzu:
import GoogleSignIn
  1. Fügen Sie der Klasse AppDelegate die folgende Authentifizierungshandler-Funktion hinzu. Ein guter Ort dafür ist direkt nach der schließenden geschweiften Klammer der application(_:didFinishLaunchingWithOptions:)-Methode:
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
}

Nachdem Sie diese Änderungen vorgenommen haben, sollte die Datei AppDelegate.swift so aussehen:

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.
  }
}

Anmeldevorgang testen

Sie können den gesamten Anmeldevorgang jetzt testen.

Führen Sie Ihre App aus und tippen Sie auf die Anmeldeschaltfläche. Nach der Authentifizierung wird ein Einwilligungsbildschirm angezeigt, auf dem Sie der App die Berechtigung zum Zugriff auf Ihre Informationen erteilen können. Nach der Genehmigung wird die Anmeldung abgeschlossen und Sie werden zur App zurückgeleitet.

Wenn der Anmeldevorgang erfolgreich abgeschlossen ist, speichert das „Mit Google anmelden“-SDK die Anmeldedaten des Nutzers sicher im Schlüsselbund des Geräts. Diese Anmeldedaten können später verwendet werden, damit ein Nutzer bei nachfolgenden App-Starts angemeldet bleibt.

8. Abmeldeschaltfläche hinzufügen

Nachdem die Anmeldung funktioniert, besteht der nächste Schritt darin, eine Schaltfläche zum Abmelden hinzuzufügen und die Benutzeroberfläche so zu aktualisieren, dass der aktuelle Anmeldestatus des Nutzers angezeigt wird. Wenn die Anmeldung erfolgreich ist, stellt das SDK ein GIDGoogleUser-Objekt bereit. Dieses Objekt enthält die Eigenschaft profile mit grundlegenden Informationen wie dem Namen und der E-Mail-Adresse des Nutzers, die Sie zum Personalisieren der Benutzeroberfläche verwenden.

SwiftUI

  1. Öffnen Sie die Datei ContentView.swift.
  2. Fügen Sie oben in der ContentView-Struktur eine Statusvariable hinzu. Diese Variable enthält die Informationen des Nutzers nach der Anmeldung. Da es sich um eine @State-Variable handelt, aktualisiert SwiftUI die Benutzeroberfläche automatisch, wenn sich ihr Wert ändert:
struct ContentView: View {
  @State private var user: GIDGoogleUser?
}
  1. Ersetzen Sie die aktuelle body Ihrer ContentView-Struktur durch die folgende VStack. Damit wird geprüft, ob die Statusvariable user einen Nutzer enthält. Wenn ja, wird eine Willkommensnachricht und eine Schaltfläche zum Abmelden angezeigt. Andernfalls wird die ursprüngliche Schaltfläche „Über Google anmelden“ angezeigt:
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. Aktualisieren Sie den Vervollständigungsblock handleSignInButton, um signInResult.user Ihrer neuen user-Variablen zuzuweisen. Dadurch wird die Benutzeroberfläche in die Ansicht für angemeldete Nutzer umgeschaltet:
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. Fügen Sie am Ende Ihrer ContentView-Struktur eine neue signOut-Funktion hinzu, die von der Abmeldeschaltfläche aufgerufen werden soll:
func signOut() {
  GIDSignIn.sharedInstance.signOut()
  // After signing out, set the `user` state variable to `nil`.
  self.user = nil
}

Starte die App und melde dich an. Nach erfolgreicher Authentifizierung sollte sich die Benutzeroberfläche ändern.

Anmeldestatus des SwiftUI-Frameworks im iOS-Simulator

Nachdem Sie diese Änderungen vorgenommen haben, sollte die Datei ContentView.swift so aussehen:

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. Öffnen Sie ViewController.swift.
  2. Fügen Sie oben in der ViewController direkt unter der Deklaration von signInButton eine Abmeldeschaltfläche und ein Begrüßungslabel hinzu:
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
  1. Fügen Sie die folgende Funktion am Ende von ViewController hinzu. Je nach Anmeldestatus des Nutzers wird eine andere Benutzeroberfläche angezeigt:
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. Fügen Sie unten in der Funktion viewDidLoad den folgenden Code hinzu, um der Ansicht das Begrüßungslabel und die Schaltfläche zum Abmelden hinzuzufügen:
// --- 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. Aktualisieren Sie die Funktion signInButtonTapped so, dass die Methode UpdateUI bei erfolgreicher Anmeldung aufgerufen wird:
@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. Fügen Sie schließlich eine signOutButtonTapped-Funktion zum ViewController hinzu, um den Abmeldevorgang zu verarbeiten:
@objc func signOutButtonTapped() {
  GIDSignIn.sharedInstance.signOut()
  // Update the UI for the signed-out state.
  updateUI(for: nil)
}

Starte die App und melde dich an. Nach erfolgreicher Authentifizierung sollte sich die Benutzeroberfläche ändern.

Anmeldestatus des UIKit-Frameworks im iOS-Simulator

Nachdem Sie diese Änderungen vorgenommen haben, sollte Ihre ViewController.swift-Datei so aussehen:

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. Anmeldestatus eines Nutzers wiederherstellen

Um die Nutzerfreundlichkeit für wiederkehrende Nutzer zu verbessern, müssen Sie als Nächstes ihren Anmeldestatus beim Start der App wiederherstellen. Beim Aufrufen von restorePreviousSignIn werden die im Schlüsselbund gespeicherten Anmeldedaten verwendet, um den Nutzer automatisch wieder anzumelden. So muss er den Anmeldevorgang nicht jedes Mal durchlaufen.

SwiftUI

  1. Öffnen Sie ContentView.swift.
  2. Fügen Sie den folgenden Code direkt nach VStack in der Variablen body ein:
.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 ?? "")")
    }
  }
}

Ihre Datei ContentView.swift sollte so aussehen:

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. Öffnen Sie ViewController.swift.
  2. Fügen Sie am Ende der Methode viewDidLoad den folgenden restorePreviousSignIn-Aufruf hinzu:
// 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)
    }
  }
}

Die Datei ViewController.swift sollte so aussehen:

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)
  }
}

Stille Anmeldung testen

Nach der Anmeldung beenden Sie die App vollständig und starten Sie sie neu. Sie sollten jetzt automatisch angemeldet sein, ohne auf die Schaltfläche tippen zu müssen.

10. ID-Token verstehen

Das GIDGoogleUser-Objekt ist zwar praktisch, um die Benutzeroberfläche mit dem Namen und der E-Mail-Adresse des Nutzers zu personalisieren, die wichtigste vom SDK zurückgegebene Information ist jedoch das ID-Token.

In diesem Codelab wird ein Onlinetool verwendet, um den JWT-Inhalt zu prüfen. In einer Produktions-App sollten Sie dieses ID-Token an Ihren Back-End-Server senden. Ihr Server muss die Integrität des ID-Tokens überprüfen und das JWT für etwas Sinnvolleres verwenden, z. B. zum Erstellen eines neuen Kontos auf Ihrer Backend-Plattform oder zum Einrichten einer neuen Sitzung für den Nutzer.

Auf das JWT-Token zugreifen und es decodieren

  1. Starten Sie Ihre App.
  2. Öffnen Sie die Xcode-Konsole. Sie sollten ein ausgegebenes ID-Token sehen. Sie sollte etwa so eyJhbGciOiJSUzI1Ni ... Hecz6Wm4Q aussehen:
  3. Kopieren Sie das ID-Token und verwenden Sie ein Onlinetool wie jwt.io, um das JWT zu decodieren.

Das decodierte JWT sieht so aus:

{
  "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
}

Wichtige Tokenfelder

Das decodierte ID-Token enthält Felder mit unterschiedlichen Zwecken. Einige sind leicht zu verstehen, z. B. Name und E‑Mail-Adresse, andere werden von Ihrem Backend-Server zur Bestätigung verwendet.

Das folgende Feld ist besonders wichtig:

  • sub: Das Feld sub ist eine eindeutige, dauerhafte Kennung für das Google-Konto des Nutzers. Ein Nutzer kann seine primäre E-Mail-Adresse oder seinen Namen ändern, seine sub-ID ändert sich jedoch nie. Daher ist das Feld sub der perfekte Wert, der als Primärschlüssel für Ihre Backend-Nutzerkonten verwendet werden kann.

Unter Nutzerinformationen aus dem ID-Token abrufen finden Sie weitere Informationen zur Bedeutung der einzelnen Tokenfelder.

11. App mit App Check schützen

Es wird dringend empfohlen, App Check zu aktivieren, damit nur Ihre App im Namen Ihres Projekts auf die OAuth 2.0-Endpunkte von Google zugreifen kann. App Check prüft, ob Anfragen an Ihre Backend-Dienste von Ihrer authentischen App auf einem echten und nicht manipulierten Gerät stammen.

In diesem Abschnitt wird beschrieben, wie Sie App Check in Ihre App einbinden und für das Debugging in einem Simulator sowie für einen Produktions-Build auf einem echten Gerät konfigurieren.

Konsoleneinrichtung

Für die Einbindung von App Check in Ihre Anwendung ist eine einmalige Einrichtung in der Google Cloud Console und der Firebase Console erforderlich. Dazu müssen Sie App Check für Ihren iOS-OAuth-Client in der Google Cloud Console aktivieren, einen API-Schlüssel für die Verwendung mit dem App Check-Debug-Anbieter erstellen und Ihr Google Cloud-Projekt mit Firebase verknüpfen.

App Check in der Google Cloud Console aktivieren

  1. Rufen Sie die Liste der Clients auf, die mit Ihrem Google Cloud-Projekt verknüpft sind.
  2. Wählen Sie die OAuth 2.0-Client-ID aus, die Sie für Ihre iOS-App erstellt haben.
  3. Aktivieren Sie App Check unter Google Identity für iOS.

Bearbeitungsseite für OAuth-Clients mit App Check-Schaltfläche

  1. Klicken Sie auf Speichern.

API-Schlüssel erstellen

  1. Rufen Sie die Seite API-Bibliothek für Ihr Google Cloud-Projekt auf.
  2. Geben Sie in der Suchleiste Firebase App Check API ein.

Seite „API-Bibliothek“ der Google Cloud Console

  1. Wählen Sie die Firebase App Check API aus und aktivieren Sie sie.
  2. Rufen Sie APIs & Dienste auf und wählen Sie im Navigationsmenü Anmeldedaten aus.
  3. Wählen Sie oben auf der Seite Anmeldedaten erstellen aus.

Seite „API-Anmeldedaten“ in der Google Cloud Console

  1. Weisen Sie diesem API-Schlüssel einen Namen zu.
  2. Wählen Sie unter Anwendungseinschränkungen die Option „iOS-Apps“ aus.
  3. Fügen Sie den Paket-Identifikator für Ihre App als genehmigte Anwendung hinzu.
  4. Wählen Sie unter API-Einschränkungen die Option Schlüssel einschränken aus.
  5. Wählen Sie im Drop-down-Menü die Option Firebase App Check API aus.
  6. Wählen Sie Erstellen aus.

Seite zum Erstellen von API-Schlüsseln in der Google Cloud Console

  1. Kopieren Sie den erstellten API-Schlüssel. Sie benötigen sie in einem späteren Schritt.

Firebase zu Ihrem Google Cloud-Projekt hinzufügen

  1. Rufen Sie die Firebase Console auf.
  2. Wählen Sie Zuerst ein Firebase-Projekt einrichten aus.
  3. Wählen Sie Firebase zu Google Cloud-Projekt hinzufügen aus.

Firebase einem vorhandenen Google Cloud-Projekt hinzufügen

  1. Wählen Sie ein Google Cloud-Projekt aus dem Drop-down-Menü aus und fahren Sie mit der Registrierung fort.
  2. Wählen Sie Firebase hinzufügen aus.
  3. Wenn Ihr Firebase-Projekt bereit ist, wählen Sie Weiter aus, um das Projekt zu öffnen.

Clientseitige Code-Integration

Nachdem Sie das Google Cloud-Projekt für App Check konfiguriert haben, können Sie den clientseitigen Code schreiben, um die Funktion zu aktivieren. Der für die Attestierung verwendete Anbieter ist in Produktions- und Debugging-Umgebungen unterschiedlich. Eine Produktions-App auf einem echten Gerät verwendet den integrierten App Attest-Dienst von Apple, um ihre Authentizität zu beweisen. Da der iOS-Simulator diese Art von Attestierung jedoch nicht bereitstellen kann, ist für die Debugging-Umgebung ein spezieller Debugging-Anbieter erforderlich, dem ein API-Schlüssel übergeben wird.

Der folgende Code behandelt beide Szenarien, indem er eine Compiler-Anweisung verwendet, um den richtigen Anbieter zur Build-Zeit automatisch auszuwählen.

SwiftUI

  1. Öffnen Sie die Haupt-App-Datei.
  2. Definieren Sie die folgende AppDelegate-Klasse nach den Importen und vor dem @main-Attribut:
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. Ersetzen Sie "YOUR_API_KEY" im bereitgestellten Code durch den API-Schlüssel, den Sie aus der Google Cloud Console kopiert haben.
  2. Fügen Sie die folgende Zeile in Ihre App-Struktur direkt vor der Variablen body ein. Dadurch wird Ihre AppDelegate-Klasse für den App-Lebenszyklus registriert, sodass sie auf den App-Start und andere Systemereignisse reagieren kann:
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

Ihre Haupt-App-Datei sollte so aussehen:

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. Öffnen Sie AppDelegate.swift.
  2. Aktualisieren Sie die application(_:didFinishLaunchingWithOptions:)-Methode, damit sie die App Check-Initialisierung enthält:
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. Ersetzen Sie "YOUR_API_KEY" im bereitgestellten Code durch den API-Schlüssel, den Sie aus der Google Cloud Console kopiert haben.

Die Datei AppDelegate.swift sollte so aussehen:

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.
  }
}

App Check im Simulator testen

  1. Wählen Sie in der Xcode-Menüleiste Product > Scheme > Edit Scheme aus.
  2. Wählen Sie im Navigationsmenü Ausführen aus.
  3. Wählen Sie den Tab Argumente aus.
  4. Wählen Sie im Bereich Beim Start übergebene Argumente das Pluszeichen (+) aus und fügen Sie -FIRDebugEnabled hinzu. Mit diesem Startargument wird das Firebase-Debug-Logging aktiviert.
  5. Klicken Sie auf Schließen.

Seite „Xcode arguments editor“

  1. Starten Sie Ihre App im Simulator.
  2. Kopieren Sie das App Check-Debug-Token, das in der Xcode-Konsole ausgegeben wird.

App Check-Debug-Token in der Xcode-Konsole

  1. Rufen Sie Ihr Projekt in der Firebase Console auf.
  2. Maximieren Sie im Navigationsmenü den Bereich Erstellen.
  3. Wählen Sie App Check aus.
  4. Wählen Sie den Tab Apps aus.
  5. Bewegen Sie den Mauszeiger auf Ihre App und wählen Sie das Dreipunkt-Menü aus.

Firebase App Check-Einstellungen

  1. Wählen Sie Fehlerbehebungstokens verwalten aus.
  2. Wählen Sie Debug-Token hinzufügen aus.
  3. Geben Sie Ihrem Debug-Token einen Namen und fügen Sie das zuvor kopierte Debug-Token als Wert ein.
  4. Wählen Sie Speichern aus, um das Token zu registrieren.

Verwaltung von Firebase App Check-Debug-Tokens

  1. Kehren Sie zum Simulator zurück und melden Sie sich an.

Es kann einige Minuten dauern, bis Messwerte in der Console angezeigt werden. Sobald das geschehen ist, können Sie prüfen, ob App Check funktioniert. Suchen Sie dazu an einer der folgenden Stellen nach einem Anstieg der Verified-Anfragen:

  • Im Abschnitt „App Check“ der Firebase Console auf dem Tab „APIs“.

Firebase App Check-Messwerte

  • Auf der Bearbeitungsseite für Ihren OAuth-Client in der Google Cloud Console.

App Check-Messwerte in der Google Cloud Console

Nachdem Sie die App Check-Messwerte Ihrer App beobachtet und bestätigt haben, dass legitime Anfragen überprüft werden, sollten Sie die App Check-Durchsetzung aktivieren. Wenn die Funktion erzwungen wird, lehnt App Check alle nicht bestätigten Anfragen ab. So wird sichergestellt, dass nur Zugriffe von Ihrer authentischen App im Namen Ihres Projekts auf die OAuth 2.0-Endpunkte von Google zugreifen können.

12. Zusätzliche Ressourcen

Glückwunsch!

Sie haben einen OAuth 2.0-iOS-Client konfiguriert, einer iOS-App die Schaltfläche „Mit Google anmelden“ hinzugefügt, gelernt, wie Sie das Aussehen der Schaltfläche anpassen, ein JWT-ID-Token decodiert und App Check für Ihre App aktiviert.

Diese Links können Ihnen bei den nächsten Schritten helfen:

Häufig gestellte Fragen