Generierte iOS-SDKs verwenden

Mit den Firebase Data Connect Client-SDKs können Sie Ihre serverseitigen Abfragen und Mutationen direkt über eine Firebase-App aufrufen. Sie generieren parallel ein benutzerdefiniertes Client-SDK, während Sie die Schemas, Abfragen und Mutationen entwerfen, die Sie in Ihrem Data Connect Dienst bereitstellen. Anschließend integrieren Sie Methoden aus diesem SDK in Ihre Clientlogik.

Wie bereits erwähnt, werden Data Connect Abfragen und ‑Mutationen nicht vom Clientcode gesendet und auf dem Server ausgeführt. Stattdessen werden nach der Bereitstellung Data Connect Vorgänge auf dem Server wie Cloud Functions gespeichert. Das bedeutet, dass Sie entsprechende clientseitige Änderungen bereitstellen müssen, um Probleme für bestehende Nutzer zu vermeiden (z. B. bei älteren App-Versionen).

Aus diesem Grund bietet Data Connect eine Entwicklungsumgebung und Tools, mit denen Sie Ihre auf dem Server bereitgestellten Schemas, Abfragen und Mutationen prototypisieren können. Außerdem werden während der Prototypenerstellung automatisch clientseitige SDKs generiert.

Nachdem Sie die Updates für Ihre Dienst- und Client-Apps durchlaufen haben, können sowohl serverseitige als auch clientseitige Updates bereitgestellt werden.

Wie sieht der Workflow für die Cliententwicklung aus?

Wenn Sie die Anleitung Erste Schritte befolgt haben, haben Sie bereits einen Überblick über den allgemeinen Entwicklungsablauf für Data Connect erhalten. In diesem Leitfaden finden Sie detailliertere Informationen zum Generieren von Swift-SDKs aus Ihrem Schema und zum Arbeiten mit Clientabfragen und ‑mutationen.

Zusammenfassend lässt sich sagen, dass Sie die folgenden Schritte ausführen müssen, um generierte Swift-SDKs in Ihren Client-Apps zu verwenden:

  1. Fügen Sie Ihrer iOS-App Firebase hinzu.
  2. Konfigurieren Sie das generierte SDK in Xcode als Abhängigkeit, um es zu verwenden.

    Wählen Sie in der oberen Navigationsleiste von Xcode File > Add Package Dependencies > Add Local (Datei > Paketabhängigkeiten hinzufügen > Lokal hinzufügen) aus und wählen Sie den Ordner mit der generierten Datei Package.swift aus.

Gehen Sie anschließend so vor:

  1. Entwickeln Sie Ihr App-Schema.
  2. Richten Sie die SDK-Generierung ein:

  3. Initialisieren Sie Ihren Clientcode und importieren Sie Bibliotheken.

  4. Implementieren Sie Aufrufe für Abfragen und Mutationen.

  5. Richten Sie den Data Connect Emulator ein und verwenden Sie ihn.

Swift-SDK generieren

Verwenden Sie die Firebase CLI, um Data Connect generierte SDKs in Ihren Apps einzurichten. Mit dem Befehl init sollten alle Apps im aktuellen Ordner erkannt und generierte SDKs automatisch installiert werden.

firebase init dataconnect:sdk

SDKs während der Prototypenerstellung aktualisieren

Wenn Sie die Data Connect VS Code-Erweiterung installiert haben, werden generierte SDKs immer auf dem neuesten Stand gehalten.

Wenn Sie die Data Connect VS Code-Erweiterung nicht verwenden, können Sie generierte SDKs mit der Firebase CLI auf dem neuesten Stand halten.

firebase dataconnect:sdk:generate --watch

SDKs in Build-Pipelines generieren

Sie können die Firebase CLI verwenden, um Data Connect SDKs in CI/CD-Build-Prozessen zu generieren.

firebase dataconnect:sdk:generate

Data Connect iOS SDK initialisieren

Initialisieren Sie Ihre Data Connect-Instanz mit den Informationen, die Sie zum Einrichten von Data Connect verwendet haben. Alle Informationen finden Sie in der Firebase Console auf dem Tab „Data Connect“.

Connector-Instanz abrufen

Der Code für Ihren Connector wird vom Data Connect Emulator generiert. Wenn der Name Ihres Connectors movies und das Paket movies ist, wie in connector.yaml angegeben, rufen Sie das Connector-Objekt mit dem folgenden Befehl ab:

let connector = DataConnect.moviesConnector

Abfragen und Mutationen implementieren

Mit dem Connector-Objekt können Sie Abfragen und Mutationen ausführen, wie im GraphQL-Quellcode definiert. Angenommen, für Ihren Connector sind die folgenden Vorgänge definiert:

mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

query getMovieByKey($key: Movie_Key!) {
  movie(key: $key) { id title }
}

query listMoviesByGenre($genre: String!) {
  movies(where: {genre: {eq: $genre}}) {
    id
    title
  }
}

Sie können dann einen Film so erstellen:

let mutationResult = try await connector.createMovieMutation.execute(
  title: "Empire Strikes Back",
  releaseYear: 1980,
  genre: "Sci-Fi",
  rating: 5)

print("Movie ID: \(mutationResult.data.movie_insert.id)")

Um einen Film abzurufen, verwenden Sie eine Abfragereferenz. Alle Abfragereferenzen sind Observable-Publisher. Je nach konfiguriertem Publisher (siehe connector.yaml), unterstützen sie entweder das @Observable Makro (iOS 17+) oder implementieren das ObservableObject Protokoll. Wenn nichts angegeben ist, wird standardmäßig das Makro @Observable verwendet, das unter iOS 17+ unterstützt wird.

In einer SwiftUI-Ansicht können Sie die Abfrageergebnisse mit der veröffentlichten Variablen data der Abfragereferenz verknüpfen und die Methode execute() der Abfrage aufrufen, um die Daten zu aktualisieren. Die Variable data entspricht der Form der Daten, die in Ihrer GQL-Abfragedefinition definiert wurden.

Alle abgerufenen Ergebnisse entsprechen dem Protokoll Decodable. Wenn Sie den Primärschlüssel des Objekts in Ihre GQL-Abfrage aufgenommen haben, sind die Objekte auch Identifiable, sodass Sie sie in Iteratoren verwenden können.

struct ListMovieView: View {
    @StateObject private var queryRef = connector.listMoviesByGenreQuery.ref(genre: "Sci-Fi")
    var body: some View {
        VStack {
            Button {
                Task {
                    do {
                        try await refresh()
                    } catch {
                        print("Failed to refresh: \(error)")
                    }
                }
            } label: {
                Text("Refresh")
            }
                // use the query results in a view
            ForEach(queryRef.data?.movies ?? [], id: \.self.id) { movie in
                    Text(movie.title)
                }
            }
    }
    @MainActor
    func refresh() async throws {
        _ = try await queryRef.execute()
    }
}

Abfragen unterstützen auch die einmalige Ausführung.

let resultData = try await DataConnect.moviesConnector.listMoviesByGenreQuery.execute(genre: "Sci-Fi")

Änderungen an Aufzählungsfeldern verarbeiten

Das Schema einer App kann Aufzählungen enthalten, auf die mit Ihren GraphQL-Abfragen zugegriffen werden kann.

Wenn sich das Design einer App ändert, können Sie neue unterstützte Aufzählungswerte hinzufügen. Angenommen, Sie entscheiden sich später im Lebenszyklus Ihrer Anwendung, der Aufzählung AspectRatio den Wert FULLSCREEN hinzuzufügen.

Im Data Connect Workflow können Sie lokale Entwicklungstools verwenden, um Ihre Abfragen und SDKs zu aktualisieren.

Bevor Sie jedoch eine aktualisierte Version Ihrer Clients veröffentlichen, können ältere bereitgestellte Clients Probleme verursachen.

Beispiel für eine robuste Implementierung

Das generierte SDK erzwingt die Verarbeitung unbekannter Werte, da die generierten Aufzählungen einen Wert _UNKNOWN enthalten und Swift umfassende Switch-Anweisungen erzwingt.

do {
    let result = try await DataConnect.moviesConnector.listMovies.execute()
    if let data = result.data {
        for movie in data.movies {
            switch movie.aspectratio {
                case .ACADEMY: print("academy")
                case .WIDESCREEN: print("widescreen")
                case .ANAMORPHIC: print("anamorphic")
                case ._UNKNOWN(let unknownAspect): print(unknownAspect)
            }
        }
    }
} catch {
    // handle error
}

Clientseitiges Caching aktivieren

Data Connect bietet eine optionale clientseitige Caching-Funktion, die Sie durch Bearbeiten der Datei connector.yaml aktivieren können. Wenn diese Funktion aktiviert ist, werden Abfrageantworten von den generierten Client-SDKs lokal im Cache gespeichert. Dadurch kann die Anzahl der Datenbankanfragen Ihrer App reduziert werden und die datenbankabhängigen Teile Ihrer App funktionieren auch dann, wenn die Netzwerkverfügbarkeit unterbrochen ist.

Fügen Sie der Connector-Konfiguration eine Client-Caching-Konfiguration hinzu, um das clientseitige Caching zu aktivieren:

generate:
  swiftSdk:
    outputDir: "../ios"
    package: "FirebaseDataConnectGenerated"
    clientCache:
      maxAge: 5s
      storage: persistent

Diese Konfiguration hat zwei Parameter, die beide optional sind:

  • maxAge: Das maximale Alter einer im Cache gespeicherten Antwort, bevor das Client-SDK neue Werte abruft. Beispiele: „0“, „30s“, „1h30m“.

    Der Standardwert für maxAge ist 0. Das bedeutet, dass Antworten im Cache gespeichert werden, das Client-SDK aber immer neue Werte abruft. Die im Cache gespeicherten Werte werden nur verwendet, wenn für execute() die Option CACHE_ONLY angegeben ist.

  • storage: Das Client-SDK kann so konfiguriert werden, dass Antworten entweder im persistent-Speicher oder im memory-Speicher im Cache gespeichert werden. Im persistent-Speicher im Cache gespeicherte Ergebnisse bleiben auch nach einem Neustart der App erhalten. In iOS-SDKs ist persistent die Standardeinstellung.

Nachdem Sie die Caching-Konfiguration Ihres Connectors aktualisiert haben, generieren Sie Ihre Client SDKs neu und erstellen Sie Ihre App neu. Anschließend werden mit execute() Antworten im Cache gespeichert und im Cache gespeicherte Werte gemäß der konfigurierten Richtlinie verwendet. Das geschieht in der Regel automatisch, ohne dass Sie weitere Schritte ausführen müssen. Beachten Sie jedoch Folgendes:

  • Das Standardverhalten von execute() ist wie oben beschrieben: Wenn ein Ergebnis für eine Abfrage im Cache gespeichert ist und der im Cache gespeicherte Wert nicht älter als maxAge ist, wird der im Cache gespeicherte Wert verwendet. Dieses Standardverhalten wird als PREFER_CACHE-Richtlinie bezeichnet.

    Sie können auch für einzelne Aufrufe von execute() angeben, dass entweder nur im Cache gespeicherte Werte bereitgestellt werden (CACHE_ONLY) oder dass bedingungslos neue Werte vom Server abgerufen werden (SERVER_ONLY).

    try await execute(fetchPolicy: .cacheOnly)
    
    try await execute(fetchPolicy: .serverOnly)
    

    iOS-Anwendung prototypisieren und testen

    Clients für die Verwendung eines lokalen Emulators instrumentieren

    Sie können den Data Connect Emulator entweder über die Data Connect VS Code-Erweiterung oder über die CLI verwenden.

    Die Instrumentierung der App für die Verbindung zum Emulator ist in beiden Fällen gleich.

    let connector = DataConnect.moviesConnector
    // Connect to the emulator on "127.0.0.1:9399"
    connector.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    connector.useEmulator(port: 9999)
    
    // Make calls from your app
    

    Datentypen in Data Connect SDKs

    Der Data Connect Server stellt allgemeine und benutzerdefinierte GraphQL-Daten typen dar. Diese werden im SDK so dargestellt:

    Data Connect Typ Swift
    String String
    Integer Int
    Float Double
    Boolesch Bool
    UUID UUID
    Datum FirebaseDataConnect.LocalDate
    Zeitstempel FirebaseCore.Timestamp
    INT64 Int64
    Beliebig FirebaseDataConnect.AnyValue