生成された iOS SDK を使用する

Firebase SQL Connect クライアント SDK を使用すると、Firebase アプリからサーバーサイドのクエリと ミューテーションを直接呼び出すことができます。SQL Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと並行して、カスタム クライアント SDK を 生成します。 SQL Connect次に、この SDK のメソッドをクライアント ロジックに統合します。

他の場所でも説明したように、SQL Connect クエリとミューテーションはクライアント コードによって送信され、 サーバーで実行されるわけではないことに注意してください。代わりに、デプロイされると、SQL Connect オペレーションは サーバーに Cloud Functions のように保存されます。つまり、既存のユーザー(古いアプリのバージョンなど)に影響を与えないようにするには、対応するクライアントサイドの変更をデプロイする必要があります。

そのため、SQL Connect には、サーバーにデプロイされたスキーマ、クエリ、ミューテーションのプロトタイプを作成できる開発環境と ツールが用意されています。 また、プロトタイプ作成時にクライアントサイド SDK が自動的に生成されます。

サービスとクライアント アプリの更新を繰り返したら、サーバーサイドとクライアントサイドの両方の更新をデプロイする準備が整います。

クライアント開発ワークフローとは

スタートガイドに沿って進めた場合は、スタートガイドに沿って進めた場合は、 全体的な開発フローについて説明しました。SQL Connectこのガイドでは、スキーマから Swift SDK を生成し、クライアントのクエリとミューテーションを操作する方法について詳しく説明します。

まとめると、生成された Swift SDK をクライアント アプリで使用するには、次の前提条件を満たす必要があります。

  1. iOS アプリに Firebase を追加します。
  2. 生成された SDK を使用するには、Xcode で依存関係として構成します。

    Xcode の上部のナビゲーション バーで、[File] > [Add Package Dependencies] > [Add Local] を選択し、生成された Package.swift を含むフォルダを選択します。

その後の操作は次のとおりです。

  1. アプリのスキーマを開発します。
  2. SDK の生成を設定します。

  3. クライアント コードを初期化し、ライブラリをインポートします

  4. クエリとミューテーションの呼び出しを実装します

  5. エミュレータSQL Connect設定して使用し、 反復処理を行います。

Swift SDK を生成する

Firebase CLI を使用して、アプリに SQL Connect で生成された SDK を設定します。 init コマンドは、現在のフォルダ内のすべてのアプリを検出し、生成された SDK を自動的にインストールします。

firebase init dataconnect:sdk

プロトタイプ作成中に SDK を更新する

SQL Connect VS Code 拡張機能がインストールされている場合、生成された SDK は常に最新の状態に保たれます。

SQL Connect VS Code 拡張機能を使用しない場合は、Firebase CLI を使用して、生成された SDK を最新の状態に保つことができます。

firebase dataconnect:sdk:generate --watch

ビルド パイプラインで SDK を生成する

Firebase CLI を使用して、CI/CD ビルドプロセスで SQL Connect SDK を生成できます。

firebase dataconnect:sdk:generate

SQL Connect iOS SDK を初期化する

SQL Connect インスタンスを、SQL Connect の設定に使用した情報(Firebase コンソールの SQL Connect タブで確認できます)を使用して初期化します。

コネクタ インスタンスを取得する

コネクタのコードは、 SQL Connect エミュレータによって生成されます。connector.yaml で指定されているように、コネクタ名が movies でパッケージが movies の場合は、次の呼び出しでコネクタ オブジェクトを取得します。

let connector = DataConnect.moviesConnector

クエリとミューテーションを実装する

コネクタ オブジェクトを使用すると、GraphQL ソースコードで定義されているクエリとミューテーションを実行できます。コネクタに次のオペレーションが定義されているとします。

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

次のようにムービーを作成できます。

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

ムービーを取得するには、クエリ参照を使用します。すべてのクエリ参照は Observable パブリッシャーです。構成されたパブリッシャーに応じて(connector.yaml)を参照)、 それらは@Observableマクロ(iOS 17 以降)をサポートするか、 ObservableObjectプロトコルを実装します。指定しない場合のデフォルトは、iOS 17 以降でサポートされている @Observable マクロです。

SwiftUI ビューでは、クエリ参照の公開された data 変数を使用してクエリ結果をバインドし、クエリの execute() メソッドを呼び出してデータを更新できます。data 変数は、GQL クエリ定義で定義されたデータの形状と一致します。

取得した結果はすべて Decodable プロトコルに準拠しています。オブジェクトの主キーを GQL フェッチに含めた場合、オブジェクトは Identifiable でもあるため、イテレータで使用できます。

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

クエリは 1 回限りの実行もサポートしています。

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

変更をサブスクライブする

からリアルタイム アップデートを取得するをご覧ください。SQL Connect

列挙型フィールドの変更を処理する

アプリのスキーマには列挙を含めることができ、 GraphQL クエリでアクセスできます

アプリのデザインが変更されたら、サポートされている新しい列挙値を追加できます。たとえば、アプリケーションのライフサイクルの後半で、AspectRatio 列挙に FULLSCREEN 値を追加するとします。

SQL Connect ワークフローでは、ローカル開発ツールを使用して クエリと SDK を更新できます。

ただし、クライアントの更新バージョンをリリースする前に、デプロイ済みの古いクライアントが破損する可能性があります。

復元力のある実装例

生成された列挙型には _UNKNOWN 値が含まれており、Swift では網羅的な switch ステートメントが強制されるため、生成された SDK では不明な値の処理が強制されます。

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
}

クライアントサイド キャッシュを有効にする

SQL Connect には、クライアントサイド キャッシュ機能(オプション)があります。この機能を有効にするには、connector.yaml ファイルを編集します。この機能を有効にすると、生成されたクライアント SDK はクエリ レスポンスをローカルにキャッシュします。これにより、アプリが行うデータベース リクエストの数を減らし、ネットワークが利用できない場合でもアプリのデータベース依存部分が動作するようにできます。

クライアントサイド キャッシュを有効にするには、コネクタ構成にクライアント キャッシュ構成を追加します。

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

この構成には 2 つのパラメータがあり、どちらも省略可能です。

  • maxAge: キャッシュされたレスポンスがクライアント SDK で新しい値を取得するまでの最大経過時間。例: 「0」、「30 秒」、「1 時間 30 分」。

    maxAge のデフォルト値は 0 です。これは、レスポンスがキャッシュされるものの、クライアント SDK は常に新しい値を取得することを意味します。キャッシュされた値は、execute()CACHE_ONLY が指定されている場合にのみ使用されます。

  • storage: クライアント SDK は、レスポンスを persistent ストレージまたは memory にキャッシュするように構成できます。persistent ストレージにキャッシュされた結果は、アプリの再起動後も保持されます。iOS SDK のデフォルトは persistent です。

コネクタのキャッシュ構成を更新したら、クライアント SDK を再生成してアプリを再ビルドします。これにより、execute() はキャッシュ レスポンスをキャッシュし、構成したポリシーに従ってキャッシュされた値を使用します。通常、この処理は自動的に行われるため、追加の操作は不要です。ただし、次の点に注意してください。

  • execute() のデフォルトの動作は上記のとおりです。クエリの結果がキャッシュされ、キャッシュされた値が maxAge より古くない場合は、キャッシュされた値を使用します。このデフォルトの動作は PREFER_CACHE ポリシーと呼ばれます。

    execute() の個々の呼び出しで、キャッシュされた値のみを処理する(CACHE_ONLY)か、サーバーから新しい値を無条件にフェッチする(SERVER_ONLY)かを指定することもできます。

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

    iOS アプリのプロトタイプを作成してテストする

    ローカル エミュレータを使用するようにクライアントをインストルメントする

    SQL Connect エミュレータは、 SQL Connect VS Code 拡張機能または CLI から使用できます。

    エミュレータに接続するようにアプリをインストルメントする方法は、どちらのシナリオでも同じです。

    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
    

    SQL Connect SDK のデータ型

    SQL Connect サーバーは、一般的な GraphQL データ型とカスタム GraphQL データ型を表します。これらは SDK で次のように表されます。

    SQL Connect の型 Swift
    文字列 文字列
    Int Int
    浮動小数点数 Double
    ブール値 Bool
    UUID UUID
    日付 FirebaseDataConnect.LocalDate
    タイムスタンプ FirebaseCore.Timestamp
    Int64 Int64
    すべて FirebaseDataConnect.AnyValue