apollo-ios

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Apollo iOS Guide

Apollo iOS 指南

Apollo iOS is a strongly-typed GraphQL client for Apple platforms. It generates Swift types from your GraphQL operations and schema, and ships an async/await client, a normalized cache (in-memory or SQLite-backed), a pluggable interceptor-based HTTP transport that handles queries, mutations, and multipart subscriptions, and an optional WebSocket transport (
graphql-transport-ws
) that can carry any operation type.
Apollo iOS 是一款适用于苹果平台的强类型GraphQL客户端。它会根据你的GraphQL操作和架构生成Swift类型,同时提供异步/等待客户端、规范化缓存(基于内存或SQLite)、可插拔的基于拦截器的HTTP传输(处理查询、变更和多部分订阅),以及可选的WebSocket传输(
graphql-transport-ws
),可承载任何类型的操作。

Process

流程

Follow this process when adding or working with Apollo iOS:
  • Confirm target platforms, GraphQL endpoint(s), and how the schema is sourced.
  • Add Apollo iOS via Swift Package Manager and install the
    apollo-ios-cli
    .
  • Link each target to the correct product (
    Apollo
    for targets using
    ApolloClient
    ,
    ApolloAPI
    for targets that only read generated models).
  • Write
    apollo-codegen-config.json
    using the canonical default (
    moduleType: swiftPackage
    ,
    operations: relative
    ); deviate only when the project has a specific constraint.
  • Run codegen and wire it into the build.
  • Create a single shared
    ApolloClient
    and inject it via SwiftUI
    Environment
    .
  • Implement operations (queries, mutations, subscriptions) from
    @Observable
    view models.
  • Add interceptors for auth and logging.
  • When the first test that needs
    Mock<Type>
    is written, flip
    output.testMocks
    in
    apollo-codegen-config.json
    from
    none
    to
    swiftPackage
    (or
    absolute
    ), regenerate, and link the mocks target to the test target.
添加或使用Apollo iOS时,请遵循以下流程:
  • 确认目标平台、GraphQL端点以及架构的获取方式。
  • 通过Swift Package Manager添加Apollo iOS并安装
    apollo-ios-cli
  • 将每个目标链接到正确的产品(使用
    ApolloClient
    的目标链接
    Apollo
    ,仅读取生成模型的目标链接
    ApolloAPI
    )。
  • 使用标准默认配置(
    moduleType: swiftPackage
    operations: relative
    )编写
    apollo-codegen-config.json
    ;仅当项目有特定限制时才偏离该配置。
  • 运行代码生成并将其接入构建流程。
  • 创建单个共享的
    ApolloClient
    并通过SwiftUI
    Environment
    注入。
  • @Observable
    视图模型实现操作(查询、变更、订阅)。
  • 添加用于认证和日志的拦截器。
  • 当编写第一个需要
    Mock<Type>
    的测试时,将
    apollo-codegen-config.json
    中的
    output.testMocks
    none
    改为
    swiftPackage
    (或
    absolute
    ),重新生成代码,并将模拟目标链接到测试目标。

Reference Files

参考文件

  • Setup — Install the SDK and CLI, link the right product (
    Apollo
    /
    ApolloAPI
    /
    ApolloSQLite
    /
    ApolloWebSocket
    /
    ApolloTestSupport
    ) to each target, generate the canonical
    apollo-codegen-config.json
    , download the schema, run initial codegen, initialize
    ApolloClient
    , wire it into SwiftUI.
  • Codegen — Full
    apollo-codegen-config.json
    reference:
    schemaTypes.moduleType
    (
    swiftPackage
    /
    embeddedInTarget
    /
    other
    ) and
    operations
    (
    relative
    /
    inSchemaModule
    /
    absolute
    ) with tradeoffs and fragment-sharing patterns, renaming generated types, test mocks, Swift 6 / MainActor flags, and why you should not auto-run codegen from an Xcode build phase.
  • Custom Scalars — Default behavior (generated as
    typealias <Scalar> = String
    ), when to replace the default, conforming to
    CustomScalarType
    , and canonical patterns for
    Date
    ,
    URL
    , and
    Decimal
    .
  • Operations — Queries, mutations, watchers, cache policies, error handling, and SwiftUI
    @Observable
    view-model patterns with async/await.
  • Caching — Choosing between in-memory and SQLite cache, declaring cache keys with the
    @typePolicy
    directive, programmatic cache keys as advanced fallback, watching the cache, manual reads/writes.
  • Interceptors — The four interceptor protocols, building a custom
    InterceptorProvider
    , auth token interceptor, logging, retry, APQ.
  • Subscriptions — Choosing between HTTP multipart and WebSocket transports,
    SplitNetworkTransport
    wiring,
    connection_init
    auth, pause/resume on scene phase, consuming subscriptions from SwiftUI.
  • Testing
    ApolloTestSupport
    , generated
    Mock<Type>
    fixtures, the protocol-wrapper pattern for testable view models, integration testing with a fake
    NetworkTransport
    , testing watchers.
  • 设置 — 安装SDK和CLI,为每个目标链接正确的产品(
    Apollo
    /
    ApolloAPI
    /
    ApolloSQLite
    /
    ApolloWebSocket
    /
    ApolloTestSupport
    ),生成标准的
    apollo-codegen-config.json
    ,下载架构,运行初始代码生成,初始化
    ApolloClient
    ,并将其接入SwiftUI。
  • 代码生成
    apollo-codegen-config.json
    完整参考:
    schemaTypes.moduleType
    swiftPackage
    /
    embeddedInTarget
    /
    other
    )和
    operations
    relative
    /
    inSchemaModule
    /
    absolute
    )的权衡与片段共享模式、重命名生成的类型、测试模拟、Swift 6 / MainActor标志,以及为何不应从Xcode构建阶段自动运行代码生成。
  • 自定义标量 — 默认行为(生成为
    typealias <Scalar> = String
    )、何时替换默认值、遵循
    CustomScalarType
    ,以及
    Date
    URL
    Decimal
    的标准模式。
  • 操作 — 查询、变更、监视器、缓存策略、错误处理,以及结合async/await的SwiftUI
    @Observable
    视图模型模式。
  • 缓存 — 在内存缓存和SQLite缓存之间选择,使用
    @typePolicy
    指令声明缓存键,将程序化缓存键作为高级备选方案,监听缓存,手动读取/写入。
  • 拦截器 — 四种拦截器协议、构建自定义
    InterceptorProvider
    、认证令牌拦截器、日志、重试、APQ。
  • 订阅 — 在HTTP多部分传输和WebSocket传输之间选择、
    SplitNetworkTransport
    配置、
    connection_init
    认证、场景阶段的暂停/恢复、从SwiftUI消费订阅。
  • 测试
    ApolloTestSupport
    、生成的
    Mock<Type>
    测试数据、用于可测试视图模型的协议包装模式、使用模拟
    NetworkTransport
    进行集成测试、测试监视器。

Scripts

脚本

  • list-apollo-ios-versions.sh — List published Apollo iOS tags. Use this to find the latest version before writing version-pinned SPM dependencies.
  • list-apollo-ios-versions.sh — 列出已发布的Apollo iOS标签。在编写固定版本的SPM依赖项之前,使用此脚本查找最新版本。

Key Rules

核心规则

  • Use Apollo iOS v2+. v1.x and v0.x are legacy — do not target them for new work.
  • Install via Swift Package Manager. CocoaPods and Carthage are not the recommended distribution mechanism for apollo-ios.
  • Default the codegen config to
    moduleType: swiftPackage
    and
    operations: relative
    (see Setup). This shape works for single-target and multi-module apps alike. Deviate only when the project cannot use SPM or has specific fragment-sharing needs (see Codegen).
  • Name the generated schema module after the project, using the
    <ProjectName>API
    convention (e.g.
    RocketReserverAPI
    for a project called
    RocketReserver
    ). Derive the project name from
    Package.swift
    / the
    .xcodeproj
    / the app product name — never ship the
    MyAPI
    placeholder. If the project name is not obvious, ask the user with
    AskUserQuestion
    .
  • Target linking is a per-target decision made as modules grow — there is no upfront decision to make. Link
    Apollo
    to targets using
    ApolloClient
    ; link
    ApolloAPI
    to targets that only consume generated response models.
  • Keep
    schema.graphqls
    ,
    .graphql
    operation files, and
    apollo-codegen-config.json
    in source control so builds are reproducible.
  • Regenerate code after every schema or
    .graphql
    operation change. Never hand-edit generated files.
  • Commit the generated Swift files to source control. Do not wire
    apollo-ios-cli generate
    into an Xcode Run Script build phase — it measurably slows compile times on every build. Regenerate manually or via a dedicated script alias.
  • Generate test mocks lazily. The canonical codegen config ships with
    output.testMocks: { "none": {} }
    . Flip it on (and regenerate) only when the first test that needs
    Mock<Type>
    is being written — see Testing.
  • Create a single shared
    ApolloClient
    per endpoint. Inject it via SwiftUI
    Environment
    ; never construct a new client per request.
  • Prefer
    @typePolicy
    schema directives over programmatic cache key resolution when declaring cache keys for types.
  • Put auth (attach token + refresh on 401 + retry) in a single
    GraphQLInterceptor
    . Attach via
    request.additionalHeaders["Authorization"]
    , detect 401 via
    .mapErrors
    , and trigger the retry by throwing
    RequestChain.Retry(request:)
    . Always pair with
    MaxRetryInterceptor
    as a safety-net cap. Reserve
    HTTPInterceptor
    for purely HTTP-scoped headers (
    User-Agent
    ,
    Accept-Encoding
    ). Never put auth or retry in view code.
  • In SwiftUI, scope fetch
    Task
    s to
    .task { }
    so they cancel automatically when the view disappears.
  • If Xcode MCP tools are available in the agent environment (typically exposed as
    mcp__xcode__BuildProject
    ,
    mcp__xcode__RunSomeTests
    ,
    mcp__xcode__XcodeListNavigatorIssues
    , etc.), prefer them over raw
    xcodebuild
    for building, running tests, and inspecting build issues after regenerating code.
  • 使用Apollo iOS v2+。v1.x和v0.x为旧版本——新开发工作请勿使用这些版本。
  • 通过Swift Package Manager安装。CocoaPods和Carthage不是apollo-ios推荐的分发机制。
  • 将代码生成配置默认设置为
    moduleType: swiftPackage
    operations: relative
    (参见设置)。此配置适用于单目标和多模块应用。仅当项目无法使用SPM或有特定的片段共享需求时才偏离该配置(参见代码生成)。
  • 按照
    <ProjectName>API
    的约定,以项目名称命名生成的架构模块(例如,名为
    RocketReserver
    的项目对应
    RocketReserverAPI
    )。从
    Package.swift
    /
    .xcodeproj
    / 应用产品名称中获取项目名称——切勿使用
    MyAPI
    占位符。如果项目名称不明确,请使用
    AskUserQuestion
    询问用户。
  • 目标链接是随着模块增长而做出的逐目标决策——无需提前决定。为使用
    ApolloClient
    的目标链接
    Apollo
    ;为仅使用生成的响应模型的目标链接
    ApolloAPI
  • schema.graphqls
    .graphql
    操作文件和
    apollo-codegen-config.json
    纳入版本控制,确保构建可重现。
  • 每次架构或
    .graphql
    操作变更后重新生成代码。切勿手动编辑生成的文件。
  • 将生成的Swift文件提交到版本控制。不要
    apollo-ios-cli generate
    接入Xcode Run Script构建阶段——这会显著减慢每次构建的编译时间。手动重新生成或通过专用脚本别名执行。
  • 延迟生成测试模拟。标准代码生成配置默认
    output.testMocks: { "none": {} }
    。仅当编写第一个需要
    Mock<Type>
    的测试时才启用它(并重新生成代码)——参见测试
  • 为每个端点创建单个共享的
    ApolloClient
    。通过SwiftUI
    Environment
    注入;切勿为每个请求构造新的客户端。
  • 声明类型的缓存键时,优先使用
    @typePolicy
    架构指令而非程序化缓存键解析。
  • 将认证(附加令牌 + 401时刷新 + 重试)放在单个
    GraphQLInterceptor
    中。通过
    request.additionalHeaders["Authorization"]
    附加令牌,通过
    .mapErrors
    检测401,通过抛出
    RequestChain.Retry(request:)
    触发重试。始终搭配
    MaxRetryInterceptor
    作为安全上限。将
    HTTPInterceptor
    仅用于纯HTTP范围的头信息(
    User-Agent
    Accept-Encoding
    )。切勿在视图代码中处理认证或重试逻辑。
  • 在SwiftUI中,将获取数据的
    Task
    限定在
    .task { }
    范围内,以便视图消失时自动取消任务。
  • 如果代理环境中提供了Xcode MCP工具(通常以
    mcp__xcode__BuildProject
    mcp__xcode__RunSomeTests
    mcp__xcode__XcodeListNavigatorIssues
    等形式暴露),则优先使用这些工具而非原始
    xcodebuild
    来构建、运行测试,以及重新生成代码后检查构建问题。