从10月8日至10日加入我们,在新德里市学习关于 GraphQL Federation 和 API 平台工程的最新技巧、趋势和新闻。加入我们,参加2024年纽约市的 GraphQL Summit
文档
免费开始

Apollo iOS 1.2 迁移指南

从 1.0 - 1.1 到 1.2


本指南描述了将您的代码从版本 1.0 或 1.1 迁移到 Apollo iOS 1.2 版本的过程。

尽管 1.2 是一个 minor 版本升级,但在这个版本中解决了一个关键问题,升级过程中需要进行小的重大变更是必需的。虽然我们努力使次要版本的升级路径平滑,但如果没有这次迁移,无法合理地解决这个问题。

缓存键配置 API

本版本中配置自定义缓存键的 API 实现了细微的变化。在您生成的SchemaConfiguration.swift文件中定义的cacheKeyInfo(for:objecthots:)函数已进行了修改。

在先前版本中,objecthots:参数是JSONObject类型,这是一个typealias,表示Dictionary<String, AnyHashable>类型。在 1.2 版本中,objecthots:参数是新建类型ObjectData

为保留您的实现,SchemaConfiguration.swift文件只会在第一次生成代码时生成。这意味着在升级到 Apollo iOS 1.2 时,您需要修改cacheKeyInfo(for:objecthots:)函数的函数签名。

对于新项目,该函数将在第一次生成代码时正确生成。

理由

因为缓存键解析在原始JSON(来自网络响应)和SelectionSet模型数据(直接写入缓存时)上同时进行,因此底层object数据将具有不同的格式。这种不一致性导致了一些用户难以跟踪的bug。ObjectData包装器struct用于在cacheKeyInfo(for:object:)函数的上下文中规范这种数据以保持一致格式。

迁移步骤

对于大多数用户,更改只是将函数签名从

v1.0 SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: JSONObject) -> CacheKeyInfo? {
/// ...
}
}

修改为

v1.2 SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
/// ...
}
}

对于大多数基本用例,这些用例仅使用objectsubscript来访问其值,这将是足够的。ObjectData结构体并没有提供与Dictionary相同的API,并且存在一些语义上的差异,您可能需要解决。我们建议运行充分的测试以确认您的缓存键解析函数仍然返回预期的值。

如果您的缓存键解析函数在新函数签名下无法编译或无法正确解析缓存键,请继续阅读以获取更多信息。

底层值类型更改

The ObjectData struct 允许您以保持值类型一致性的方式访问提供的object中的值。如果您的对cacheKeyInfo(for:object:)函数的实现将值转换为特定预期类型,则可能需要修改您的代码以确保正确执行类型转换。

  • 类型
    • 原始的值(String, Int, Float, DoubleBool
  • 自定义标量类型
    • 自定义标量将被反序列化为从类型jsonValue属性返回的原始值。
    • 有关更多信息,请参阅自定义标量
  • s
    • 对于其他嵌套在传入的对象,将返回另一个ObjectData结构体。
    • 在之前的版本中,返回值是另一个JSONObject(即。Dictionary)。
  • 列表类型
    • 对于列表,返回值是新定义的ListData结构体。
    • ListData结构体与ObjectData结构体功能相同,但是包裹了一个元素数组而不是字典。

ObjectData API 限制

The ObjectData结构体公开了一个显著受限的 API。它仅允许对底层数据的键值对进行索引访问。通常,这个 API 应该足以访问解决缓存键所需的值。如果您cacheKeyInfo(for:object:)函数正在使用任何其他功能来使用Dictionary,您需要重构您的代码。

为了避免对缓存键解析机制的复杂性要求,仅在需要时根据用户反馈对ObjectDataAPI进行扩展。如果您的cacheKeyInfo(for:object:)函数需要在ObjectData上公开其他功能,请提交一个功能请求.

示例

让我们考虑一个示例cacheKeyInfo(for:object:)函数,它是从之前版本中需要修改以迁移到1.2版本的。

v1.0 SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: JSONObject) -> CacheKeyInfo? {
switch type {
case Objects.User:
let userInfo = object[info] as? [String: AnyHashable]
let emailList = userInfo["emailAddresses"] as? [String]
return try? CacheKeyInfo(jsonValue: emailList[0])
case Objects.Post:
let timestampCustomScalar = object["timestamp"] as? TimeStamp
let timestampRawValue = object["timestamp"] as? String
let timestampString = (timestampCustomScalar?.jsonValue as? String)
?? timestampRawValue
return try? CacheKeyInfo(jsonValue: timestampString)
case Objects.Product:
return try? CacheKeyInfo(id: object["UPC"])
default:
return nil
}
}
}

要将此函数迁移到1.2版本,我们需要进行一些更改。

  1. 必须将object参数更改为类型ObjectData
  2. 需要对User对象的info字段进行类型转换,使其成为ObjectData而不是[String: AnyHashable]
  3. 对于User对象的info.emailAddresses应期望是ListData类型而不是[String]
  4. 之前,Post对象的自定义标量timestamp的值可能是TimeStamp自定义标量或其原始jsonValue类型,这取决于数据来源。现在,我们应该一直期待反序列化为jsonValue – 在这种情况下,一个String
  5. Product对象的自定义字段UPC一直是标量值。这里不需要进行任何更改。
v1.2 SchemaConfiguration.swift
public enum SchemaConfiguration: ApolloAPI.SchemaConfiguration {
static func cacheKeyInfo(for type: Object, object: ObjectData) -> CacheKeyInfo? {
switch type {
case Objects.User:
let userInfo = object["info"] as? ObjectData
let emailList = userInfo["emailAddresses"] as? ListData
return try? CacheKeyInfo(jsonValue: emailList[0] as? String)
case Objects.Post:
let timestamp = object["timestamp"] as? String
return try? CacheKeyInfo(jsonValue: timestamp)
case Objects.Product:
return try? CacheKeyInfo(jsonValue: object["UPC"])
default:
return nil
}
}
}

ObjectDataListData索引访问器可以链式使用。这意味着User对象的缓存密钥解决方法可以更简单地实现为:

case Objects.User:
return try? CacheKeyInfo(
jsonValue: object["info"]?["emailAddresses"]?[0]
)

Swift访问修饰符

1.2.0引入了新的代码生成配置参数,允许您指定生成的Swift类型的访问控制。1.2.0引入了新的代码生成配置参数,允许您指定生成的Swift类型的访问控制。当使用模块类型为embeddedInTarget输出类型为relativeabsolute时,您可以选择让生成的Swift类型可以通过publicinternal访问。

您不需要将这些选项添加到您的代码生成配置中,但未指定选项时使用的默认值与先前的Apollo iOS版本不同。

1.2.0之前,所有的Swift类型都使用public访问权限生成,新的配置选项的默认值是internal

这意味着您之前可能使用公有的Swift类型的地方,现在可能会出现编译器错误,因为这些类型不再可访问。要解决这个问题,您需要在代码生成配置中添加配置选项,指定public访问修饰符。

您可能需要手动修改模式配置和自定义标量文件,因为如果这些文件已经存在,它们将不会被重新生成。手动更新它们的替代方案是删除这些文件,运行代码生成,然后重新添加任何可能在现有的自定义标量文件中使用的自定义逻辑。

示例

模块类型

CLI 配置 JSON
"output": {
"schemaTypes": {
"moduleType": {
"embeddedInTarget": {
"name": "MyApplicationTarget",
"accessModifier": "public"
}
},
"path": "./generated/schema/"
}
}
Swift 代码生成设置
let configuration = ApolloCodegenConfiguration(
// Other properties not shown
output: ApolloCodegenConfiguration.FileOutput(
schemaTypes: ApolloCodegenConfiguration.SchemaTypesFileOutput(
path: "./generated/schema/",
moduleType: .embeddedInTarget(name: "MyApplicationTarget", accessModifier: .public)
)
...
)
)

操作 - 相对

CLI 配置 JSON
"output": {
"operations" : {
"relative" : {
"subpath": "Generated",
"accessModifier": "public"
}
}
}
Swift 代码生成设置
let configuration = ApolloCodegenConfiguration(
// Other properties not shown
output: ApolloCodegenConfiguration.FileOutput(
operations: .relative(
subpath: "generated",
accessModifier: .public
)
...
)
)

操作 - 绝对

CLI 配置 JSON
"output": {
"operations" : {
"absolute" : {
"path": "Generated",
"accessModifier": "public"
}
}
}
Swift 代码生成设置
let configuration = ApolloCodegenConfiguration(
// Other properties not shown
output: ApolloCodegenConfiguration.FileOutput(
operations: .absolute(
path: "generated",
accessModifier: .public
)
...
)
)
上一页
v1.0
下一页
v1.3
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,业务名为Apollo GraphQL。

隐私政策

公司