Usar SDKs do iOS gerados

Os SDKs de cliente Firebase SQL Connect permitem chamar consultas e mutações do lado do servidor diretamente de um app do Firebase. Você gera um SDK de cliente personalizado em paralelo ao criar os esquemas, consultas e mutações que implanta no seu SQL Connect serviço. Em seguida, integre métodos desse SDK à lógica do cliente.

Como já mencionamos, é importante observar que SQL Connect consultas e mutações não são enviadas pelo código do cliente e executadas no servidor. Em vez disso, quando implantadas, as operações SQL Connect são armazenadas no servidor, como o Cloud Functions. Isso significa que você precisa implantar mudanças correspondentes no lado do cliente para evitar quebrar usuários atuais (por exemplo, em versões mais antigas do app).

É por isso que SQL Connect oferece um ambiente de desenvolvedor e ferramentas que permitem criar protótipos de esquemas, consultas e mutações implantados no servidor. Ele também gera SDKs do lado do cliente automaticamente durante a criação do protótipo.

Quando você tiver atualizações iteradas para seus apps de serviço e cliente, as atualizações do servidor e do lado do cliente estarão prontas para implantação.

Qual é o fluxo de trabalho de desenvolvimento do cliente?

Se você seguiu o guia de introdução, conheceu o fluxo de desenvolvimento geral do SQL Connect. Neste guia, você encontrará informações mais detalhadas sobre como gerar SDKs do Swift no seu esquema e trabalhar com consultas e mutações do cliente.

Para resumir, para usar SDKs do Swift gerados nos apps do cliente, siga estas etapas de pré-requisito:

  1. Adicione o Firebase ao seu app iOS.
  2. Para usar o SDK gerado, configure-o como uma dependência no Xcode.

    Na barra de navegação superior do Xcode, selecione File > Add Package Dependencies > Add Local e escolha a pasta que contém o Package.swift gerado.

Em seguida:

  1. Desenvolva o esquema do app.
  2. Configure a geração do SDK:

  3. Inicialize o código do cliente e importe bibliotecas.

  4. Implemente chamadas para consultas e mutações.

  5. Configure e use o emulador SQL Connect e faça iterações.

Gerar o SDK do Swift

Use a Firebase CLI para configurar SQL Connect gerados nos seus apps. O comando init detecta todos os apps na pasta atual e instala SDKs gerados automaticamente.

firebase init dataconnect:sdk

Atualizar SDKs durante a criação de protótipos

Se você tiver a extensão do SQL Connect VS Code instalada, ela sempre manterá os SDKs gerados atualizados.

Se você não usar a extensão do SQL Connect VS Code, poderá usar a CLI do Firebase para manter os SDKs gerados atualizados.

firebase dataconnect:sdk:generate --watch

Gerar SDKs em pipelines de build

Você pode usar a CLI do Firebase para gerar SQL Connect SDKs em processos de build de CI/CD.

firebase dataconnect:sdk:generate

Inicializar o SDK para iOS SQL Connect

Inicialize a instância do SQL Connect usando as informações que você usou para configurar o SQL Connect (tudo disponível na guia SQL Connect do console Firebase).

Como conseguir uma instância do conector

O código do conector será gerado pelo SQL Connect emulador. Se o nome do conector for movies e o pacote for movies, conforme especificado em connector.yaml, recupere o objeto do conector chamando:

let connector = DataConnect.moviesConnector

Implementar consultas e mutações

Com o objeto do conector, é possível executar consultas e mutações conforme definido no código-fonte do GraphQL. Suponha que o conector tenha estas operações definidas:

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

Em seguida, você pode criar um filme da seguinte maneira:

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

Para recuperar um filme, use uma referência de consulta. Todas as referências de consulta são editores observáveis. Dependendo do editor configurado (consulte connector.yaml), eles oferecem suporte à @Observable macro (iOS 17 e versões mais recentes) ou implementam o ObservableObject protocolo. O padrão, se nenhum for especificado, é a macro @Observable com suporte no iOS 17 e versões mais recentes.

Em uma visualização do SwiftUI, é possível vincular os resultados da consulta usando a variável data publicada da referência da consulta e chamar o método execute() da consulta para atualizar os dados. A variável data vai corresponder ao formato dos dados definidos na definição da consulta GQL.

Todos os resultados recuperados estão em conformidade com o protocolo Decodable. Se você incluiu a chave primária do objeto na busca do GQL, os objetos também são Identifiable, permitindo que você os use em iteradores.

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

As consultas também oferecem suporte à execução única.

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

Processar mudanças nos campos de enumeração

O esquema de um app pode conter enumerações, que podem ser acessadas pelas suas consultas do GraphQL.

À medida que o design de um app muda, você pode adicionar novos valores com suporte para enumeração. Por exemplo, imagine que, mais tarde no ciclo de vida do aplicativo, você decida adicionar um valor FULLSCREEN à enumeração AspectRatio.

No fluxo de trabalho SQL Connect, é possível usar ferramentas de desenvolvimento local para atualizar consultas e SDKs.

No entanto, antes de lançar uma versão atualizada dos clientes, os clientes implantados mais antigos podem ser interrompidos.

Exemplo de implementação resiliente

O SDK gerado força o processamento de valores desconhecidos, já que as enumerações geradas contêm um valor _UNKNOWN, e o Swift aplica instruções de troca exaustivas.

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
}

Ativar o armazenamento em cache do lado do cliente

SQL Connect tem um recurso opcional de armazenamento em cache do lado do cliente, que você pode ativar editando o arquivo connector.yaml. Quando esse recurso está ativado, os SDKs de cliente gerados armazenam em cache localmente as respostas de consulta, o que pode reduzir o número de solicitações de banco de dados feitas pelo app e permite que as partes dependentes do banco de dados do app funcionem quando a disponibilidade da rede é interrompida.

Para ativar o armazenamento em cache do lado do cliente, adicione uma configuração de armazenamento em cache do cliente à configuração do conector:

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

Essa configuração tem dois parâmetros, ambos opcionais:

  • maxAge: a idade máxima que uma resposta armazenada em cache pode ter antes que o SDK do cliente busque novos valores. Exemplos: "0", "30s", "1h30m".

    O valor padrão de maxAge é 0, o que significa que as respostas são armazenadas em cache, mas o SDK do cliente sempre vai buscar novos valores. Os valores armazenados em cache só serão usados quando CACHE_ONLY for especificado para execute().

  • storage: o SDK do cliente pode ser configurado para armazenar respostas em cache no armazenamento persistent ou na memory. Os resultados armazenados em cache no armazenamento persistent vão persistir nas reinicializações do app. Nos SDKs do iOS, o padrão é persistent.

Depois de atualizar a configuração de armazenamento em cache do conector, regenere os SDKs do cliente e recrie o app. Depois disso, execute() vai armazenar respostas em cache e usar valores armazenados em cache de acordo com a política configurada. Isso geralmente acontece automaticamente, sem etapas adicionais da sua parte. No entanto, observe o seguinte:

  • O comportamento padrão de execute() é descrito acima: se um resultado for armazenado em cache para uma consulta e o valor armazenado em cache não for mais antigo que maxAge, use o valor armazenado em cache. Esse comportamento padrão é chamado de política PREFER_CACHE.

    Também é possível especificar invocações individuais de execute() para exibir apenas valores armazenados em cache (CACHE_ONLY) ou para buscar incondicionalmente novos valores do servidor (SERVER_ONLY).

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

    Criar protótipos e testar o aplicativo iOS

    Instrumentar clientes para usar um emulador local

    É possível usar o SQL Connect emulator, seja na extensão do SQL Connect VS Code ou na CLI.

    A instrumentação do app para se conectar ao emulador é a mesma para os dois cenários.

    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
    

    Tipos de dados em SQL Connect SDKs

    O servidor SQL Connect representa tipos de dados comuns e personalizados do GraphQL. Eles são representados no SDK da seguinte maneira.

    Tipo de SQL Connect Swift
    String String
    Int Int
    Ponto flutuante Duplo
    Booleano Booleano
    UUID UUID
    Data FirebaseDataConnect.LocalDate
    Carimbo de data/hora FirebaseCore.Timestamp
    Int64 Int64
    Qualquer FirebaseDataConnect.AnyValue