Releases: apollographql/apollo-ios
Preview: Codegen Field Merging
This is a preview release of a new feature that improves the code generation engine's field merging algorithm and allows for disabling of field merging altogether. The feature work for this preview version is being tracked in issue #2560.
Reduced Generated Code Size of Merged Selection Sets
The code generation algorithm is now able to recognize most situations where a merged selection set is a direct copy of a selection set that is being merged. In those cases, it now uses a typealias
referencing the original selection set rather than generating a duplicate. This is most commonly seen for the child entities of a named fragment that is spread into another selection set. In some cases this can dramatically decrease the size and complexity of the generated models.
Bug Fix: Generated Selections Sets in Inclusion Condition Scope
This also fixes a bug when using @include/@skip
where generated models that should have been generated inside of a conditional inline fragment were generated outside of the conditional scope. This may cause breaking changes for a small number of users. Those breaking changes are considered a bug fix since accessing the conditional inline fragments outside of the conditional scope could cause runtime crashes (if the conditions for their inclusion were not met).
Disabling Field Merging
If you need to further reduce the size of generated models, you can use the new experimental field merging configuration option to disable field merging.
The field merging feature has three types of merging that you can enable or disable selectively:
- Ancestors: Merges fields and fragment accessors from the selection set's direct ancestors.
- Siblings: Merges fields and fragment accessors from sibling inline fragments that match the selection set's scope.
- Named Fragments: Merges fields and fragment accessors from named fragments that have been spread into the selection set.
Limitations
Disabling of field merging is incompatible with the inclusion of selectionSetInitializers
. Because the generated initializers require fully formed objects with all field merged into them in order to ensure the generated objects are valid for each of their type cases. It is likely that this limitation will not be able to be resolved in the future. However we hope the new merging algorithm additions will provide enough of an improvement to the generated models to make disabling of field merging unnecessary for most users.
Configuration - JSON
To enable this option when using a json config file, use the configuration option experimentalFeatures.fieldMerging
.
{
"experimentalFeatures" : {
"fieldMerging" : [
# Any combination of these values:
"siblings",
"ancestors",
"namedFragments"
],
"legacySafelistingCompatibleOperations" : true
},
"input": {
# ...
You may also input fieldMerging: [ "all" ]
, to enable all types of field merging (which is the default value if not provided).
Configuration - Scripting with ApolloCodegenLib
To enable this option when using the ApolloCodegenLib
directly, set the ApolloCodegenConfiguration.experimentalFeatures.fieldMerging
option.
config = ApolloCodegenConfiguration(
schemaNamespace: "MySchema,
input: // ...,
output: // ...,
options: // ... ,
experimentalFeatures: .init(
fieldMerging: [
# Any combination of these values:
.siblings,
.ancestors,
.namedFragments
]
)
)
You may also input fieldMerging: .all
, to enable all types of field merging (which is the default value if not provided).
Known Issues
There is a longstanding bug (since Apollo iOS 1.0) in the codegen engine for some users that have large sets of operations with many deeply nested fragment spreads. For these users, the codegen engine never finishes running, using unbounded memory and eventually crashing once it has used all available memory. This version does not resolve this issue, but we are hoping to address this in a release in the near future!
Testing
Because the changes to the generated models in this version can be large in some circumstances, we would like to get feedback on any issues you encounter while using this preview version before we release this into a stable version of Apollo iOS. Please file an issue for any problems you encounter.
Issues may appear when using the new disabling of field merging, but we are also aware of possible issues when not using this new feature (ie. fieldMerging: .all
)
We are particularly concerned about possible issues in the following situations:
- GraphQL Definitions with deeply nested named fragments spreads
- Complex uses cases with
@include/@skip
conditions
In addition to feedback on problems you encounter, we would also love to hear about your success stories! If this new version works well for you and reduces the size of your generated models in a meaningful way, please let us know in #2560!
Thank you for trying out this preview version of Apollo iOS. We appreciate your time and effort as well as any feedback you can provide.
1.14.0
New
- Experimental support for the
@defer
directive: You can now use the@defer
directive in your operations and code generation will generate models that support asynchronously receiving the deferred selection sets. There is a helpful property wrapper with a projected value to determine the state of the deferred selection set, and support for cache reads and writes. This feature is enabled by default but is considered experimental. Please refer to the documentation for further details. - Add
debugDescription
toSelectionSet
(#3374): This adds the ability to easily print code generated models to the Xcode debugger console. See PR #412. Thanks to @raymondk-nf for raising the issue. - Xcode 16 editor config files (#3404): Xcode 16 introduced support for
.editorconfig
files that represent settings like spaces vs. tabs, how many spaces per tab, etc. We've added a.editorconfig
file with the projects preferred settings, so that the editor will use them automatically. See PR #419. Thanks to @TizianoCoroneo for raising the issue.
Fixed
- Local cache mutation build error in Swift 6 (#3398): Mutating a property of a fragment annotated with the
@apollo_client_ios_localCacheMutation
directive caused a compile time error in Xcode 16 with Swift 6. See PR #417. Thanks to @martin-muller for raising the issue.
1.13.0
New
- Added
ExistentialAny
requirement (#379): This adds the-enable-upcoming-feature ExistentialAny
to all targets to ensure compatibility with the upcoming Swift feature. - Schema type renaming (#388): This adds the feature to allow customizing the names of schema types in Swift generated code.
- JSONConverter helper (#380): This adds a new helper class for handling JSON conversion of data including the ability to convert
SelectionSet
instances to JSON.
Fixed
- ApolloSQLite build error with Xcode 16 (#386): This fixes a naming conflict with Foundation in iOS 18 and the SQLite library. Thanks to @rastersize for the contributon.
1.12.2
Fixed
- Rebuilt the CLI binary with the correct version number: The CLI binary included in the
1.12.1
package was built with an incorrect version number causing a version mismatch when attempting to execute code generation.
1.12.1
Fixed
- Rebuilt the CLI binary: The CLI binary included in the
1.12.0
package was built with inconsistent SDK versions resulting in the linker signing not working correctly.
1.12.0
New
ID
as a custom scalar (#3379): This changes the generation of the built-in GraphQLID
scalar to be treated as a custom scalar that can be modified by the user. See PR #363.
Fixed
- Adds visionOS deployment to ApolloTestSupport podspec (#364): This adds the
visionOS
deployment target to the ApolloTestSupport podspec to match the other package managers. - Add
@_spi(Execution)
to executor for import in test mocks (#362): This replaces the use of@testable
in ApolloTestSupport with specific@_spi
scopes. This resolves a few issues that have been reported where the Apollo module could not be built for testing in non-debug configurations.
1.11.0
New
- Added
refetchOnFailedUpdates
option toGraphQLQueryWatcher
(#347): This allows you to configure the query watcher not to refetch it's query from the server when a cache read to update it's data fails.
Fixed
-
Generated input objects have default
nil
value for parameters with a schema-defined default value (#2997): When the schema defines a default value for an input parameter, you can now omit that parameter when initializing the input object and the default value will be used. This corrects feature parity with the Apollo Kotlin client. See PR #358. -
Fix namespacing error in
InterfaceTemplate
(#3375): This fixes an issue where having a schema type namedInterface
caused compilation errors in generated code. See PR #359.
1.10.0
New
- Added support for visionOS (#3320): All the dependecies that Apollo iOS requires have been updated to add support for visionOS, so we can now add official support for visionOS too. See PR #333.
Improvement
- Add Sendable conformance to some basic SchemaTypes: This adds
Sendable
conformance to the some of the generated schema types. This does not mean that all of the generated code is safe to use yet with complete concurrency checking of Swift 5.10 but it gets us closer to that goal. See PR #322. Thanks to @bdbergeron for the contributon.
preview-defer.2
This preview release has been superseded by release 1.14.0.
This is the second preview release of @defer
support in Apollo iOS which focuses on providing early access to using the @defer
directive in your operations. During preview releases bugs can occur, if you do experience anything unexpected please report it to us.
Note: Apollo supports a very specific version of the @defer
directive proposal as documented here. The @defer
directive is still in the proposal stage and is not an official addition to the GraphQL specification yet. This means that Apollo iOS may not work with all servers that currently support @defer
.
In this release
- Fixed: If your schema explicitly declared the
@defer
directive then an error about duplicate directives would be thrown during code generation. - Fixed: In some cases the operation metadata for deferred fragments may have been generated with incorrect Swift syntax resulting in a build error.
How to use it
We have a sample schema/server that supports @defer
and can be launched using the Docker configuration.
Once you have that service launched you can configure your Apollo iOS client to target the apollo-ios
and apollo-ios-codegen
dependency packages using the preview-defer.2
tag. Below is an example query using @defer
against the schema.
query ExampleQuery {
allProducts {
sku
id
... on Product @defer(label: "additional") {
dimensions {
size
}
variation {
id
name
}
}
}
}
Alternatively here is a sample client to demonstrate the code generation and operation execution of the @defer
directive.
Caveats in this preview release
- Caching is intentionally disabled for operations using
@defer
.
1.9.3
Fixed
- Fix injecting of context for UploadRequest: Any request context passed into an upload request was not being added to the HTTP request and would not be available to the interceptor chain. See PR (#302). Thanks to @RobertDresler for the contribution.
- Added support for SPM Package.resolved format version 3 (#3355): When using Xcode 15.3 the codegen CLI would fail the
generate
command with an error stating the Package.resolve file version is unsupported. Version 3 is now accepted as a valid file format for the codegen version checker. See PR (#304). - PrivacyInfo.xcprivacy file is invalid for Apollo and ApolloApi (#3359): We received reports that when submitting to the App Store the submission would fail with an error stating that the privacy manifests were invalid. We identified the error and updated the privacy files. See PR (#309). Thanks to @azilbershtein for raising the issue.
Improvement
- Provide a direct means to observe changes in ApolloStore:
ApolloStore
now exposes it's subscriber mechanism publicly. This means you can now observe and receive notifications about changes to the store. See PR (#300). Thanks to @jamesonwilliams for the contribution. - Remove redundant iteration in EntitySelectionTree merging algorithm: The conditions for merging selections were revisited and we identified, and removed, a redundant iteration. This is a significant performance improvement as it removes an entire additional iteration through all the conditional scopes in the tree. See PR (#308).