compileGraphQLResult on Swift 6.3/macOS 26 (#929): Serialized async let calls in compileGraphQLResult to work around a Swift concurrency runtime crash triggered when code generation is used in an AsyncParsableCommand. See PR #942. Thank you to @m4p for the contribution.graphql-transport-ws protocol for subscriptions, queries, and mutations. See the WebSocket Transport documentation for setup and usage details.markTypesNonisolated codegen option that emits nonisolated on all generated type declarations. This prevents compilation errors when SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor is enabled. The option defaults to true when the codegen tool is compiled with Swift 6.2+.URLSessionTaskDelegate into ApolloURLSession, enabling delegate callback handling. Thank you to @hammy-e for the contribution.compileGraphQLResult (#929): Resolved a Swift compiler crash triggered by async let stack management during code generation in AsyncParsableCommand contexts. Thank you to @m4p for the contribution.graphql-transport-ws protocol for subscriptions, queries, and mutations. See the WebSocket Transport documentation for setup and usage details.URLSessionTaskDelegate into ApolloURLSession, enabling delegate callback handling. Thank you to @hammy-e for the contribution.JSONRequest.useGetForQueries mutable (#897): The useGetForQueries property on JSONRequest is now a var, allowing interceptors to mutate the request directly instead of copying it. Thank you to @nevil for the contribution.X-Apollo-Operation-Name header to requests to satisfy Apollo Router's CSRF prevention requirements.objectType(forTypename:) lookup (#918): Replaced the generated switch statement in SchemaMetadata.objectType(forTypename:) with a static dictionary lookup, improving deserialization performance by ~75% for schemas with many types (4000+). Thank you to @erneestoc for the contribution.objectType(forTypename:) lookup (#3631): The generated SchemaMetadata.objectType(forTypename:) method now uses a static dictionary for O(1) hash-based lookup instead of a switch statement that performed O(n) linear scanning. For schemas with many object types (~4300 types), this improves deserialization times by approximately 75%. See PR #926.graphql-transport-ws protocol for subscriptions, queries, and mutations. See the WebSocket Transport documentation for setup and usage details.URLSessionTaskDelegate into ApolloURLSession, enabling delegate callback handling. Thank you to @hammy-e for the contribution.JSONRequest.useGetForQueries mutable (#897): The useGetForQueries property on JSONRequest is now a var, allowing interceptors to mutate the request directly instead of copying it. Thank you to @nevil for the contribution.X-Apollo-Operation-Name header to requests to satisfy Apollo Router's CSRF prevention requirements.objectType(forTypename:) lookup (#918): Replaced the generated switch statement in SchemaMetadata.objectType(forTypename:) with a static dictionary lookup, improving deserialization performance by ~75% for schemas with many types (4000+). Thank you to @erneestoc for the contribution.Dictionary initialization with duplicate keys (#884): Dictionary initialization using literal elements now uses a safer internal initializer to prevent crashes when duplicate keys are used. In the event that duplicate keys are present, the value associated with the first key will override all other values. Thank you to @adysart for raising the issue.AsyncReadWriteLock (#862): This fixes issue #3616. Thank you to @AlexPan1992 for raising the issue.URLRequest.cachePolicy on GET requests (#859): Thank you to @samjdurante for the contribution.AsyncReadWriteLock (#851): When under heavy loads, the AsyncReadWriteLock used by the ApolloStore could cause a deadlock. This is now resolved. Thank you to @marksvend for raising the issue..noResults error was thrown instead of the expected CancellationError. This is now resolved. Thank you to @3redrubies for raising the issue.cannotParseChunkData parsing error. This is now resolved. Thank you to @ecant for raising the issue.__fulfilledFragments and collects selections from all of them, instead of just traversing downward from self.__selections. This ensures all expected data is collected from merged fragments. See PR #832. Thank you to @JOyo246 for raising the issue.useGETForQueries was enabled. Thank you to @nevil for the contribution.useGETForQueries was enabled. Thank you to @nevil for the contribution.__fulfilledFragments and collects selections from all of them, instead of just traversing downward from self.__selections. This ensures all expected data is collected from merged fragments. See PR #832. Thank you to @JOyo246 for raising the issue.This version has no new changes since v1.25.1 and is being created to fix an issue where the previous version was tagged incorrectly.
SelectionSet equality with @include/@skip fields (#840): When a single field was used in a selection set with an @include/@skip directive, an assertionFailure would crash the program. This is now fixed.SelectionSet equality with @include/@skip fields (#840): When a single field was used in a selection set with an @include/@skip directive, an assertionFailure would crash the program. This is now fixed.SelectionSet Equality (#3579): SelectionSet equality now uses a narrowly scoped algorithm that only compares fields in the underlying data that are relevant to the SelectionSet. This fixes a bug where a fragment read back from the graph doesn't match one created in memory by ensuring that equality checks for a fragment do not consider fields that are not included in the fragment, even if they are present in the data. Previous equality checks would simply compare the underlying DataDict dictionary which was incorrect. See PR #771. Thank you to @potrebic for raising the issue.Note: This change is fixing a long-standing bug in SelectionSet equality, however it may highlight previously hidden equality issues and appear to be a bug. If you're convinced this new equality behaviour exposes a bug please open a new issue and we can discuss it.
Apollo iOS 2.0 is now available! 🎉
Apollo iOS 2.0 represents a complete reimplementation of many components of the library, redesigned from the ground up to take full advantage of Swift's modern concurrency model. This major release introduces significant breaking changes but provides substantial improvements in type safety, performance, and developer experience.
async/await and structured concurrencySendable for improved thread safetyasync/await instead of callback-based APIscacheFirst, networkFirst, networkOnly, cacheOnly, cacheAndNetwork) with specific return signaturesGraphQLInterceptor, HTTPInterceptor, CacheInterceptor, and ResponseParsingInterceptor typesGraphQLResult with improved generic typing over operationsMinimum Deployment Targets
Removed Features
URLSessionClient replaced with ApolloURLSession protocol@TaskLocal values for dependency injectionCurrent Limitations
RequestChainNetworkTransport. Web socket support will be added in a future 2.0.x release.Apollo iOS 2.0 migration follows a two-phase approach:
Phase 1: Breaking Changes
Interceptors to new discrete typesNetworkTransport implementationsNormalizedCache implementationsPhase 2: Incremental Updates
async/await APIsRequestContext with @TaskLocal valuesFor detailed migration instructions, see the Apollo iOS 2.0 Migration Guide.
ApolloClient usage from callbacks to async/await@fieldPolicy directive. (#735): Added a new @fieldPolicy directive that can be used to configure cache keys for reading data from the cache prior to making a network request for an operation. Cache keys can also be configured programatically, for more information see documentation here.SQLiteError. (#755): Adding the raw sqlite result code as an associated value on enum cases of SQLiteError.RootSelectionSet convenience initializer from inline fragment. (#748): Added a convenience initializer to RootSelectionSet that allows it to be initialized directly from an InlineFragment, simplifying the conversion process between fragments and root entity types.dependentKeys in GraphQLResult public. (#758): Making dependentKeys public allows for implementing custom ApolloStoreSubscribers similar to GraphQLQueryWatcher. Without this it's extremely difficult to know when to react to cache changes for a query. _Thank you to @chrsmys for the contribution.clientVersion build delimiter. (#721): This changes the version/build delimiter from a - to a +. This now matches the semver specification of that additional metadata.Added @fieldPolicy directive (#766, #749): The @fieldPolicy directive provides new functionality for configuring cache keys for fields with arguments. See the documentation for more information.
RootSelectionSet Convenience Initializer (#748): Added convenience initializer for RootSelectionSet from inline fragments for easier model construction.
Swift 6 Language Mode (#740): Enabled Swift 6 language mode with strict concurrency checking for improved thread safety and modern Swift patterns.
Xcode 26 Support (#756): Updated project configuration and build settings for Xcode 26 compatibility.
Subscription Over HTTP Support for RequestChainNetworkTransport (#759): Added subscription support to RequestChainNetworkTransport with HTTP chunked multipart response handling for GraphQL subscriptions over HTTP.
Fix Fetch Default Cache Policies (#777): Fixed default cache policy behavior for fetch operations to ensure consistent caching behavior across different operation types.
Narrowly Scoped SelectionSet Equality Checking (#757, #770): Fixed equality checking implementation for generated models in Apollo iOS 2.0 to ensure proper comparison of selection set data.
CLI Installation (#746): Fixed issues with Apollo iOS CLI installation and distribution.
This is the first beta release of Apollo iOS 2.0 This release contains some APIs that are still in development and are subject to change prior to general release.
SelectionSet Equality (#736): Generated models now implement Equatable and Hashable using only the relevant fields for the model. This means that named fragments that do not have access to fields from the parent operation that fetched them will be equal if only the fields the fragment can access are equal.Remove Cocoapods Support (#723): Apollo iOS 2.0 will no longer support Cocoapods. While support was carried over in the alpha releases, this has been officially removed in beta 1.
Only Input Variables use Int32 in generated models (#729): Generated models in alpha-2 generated Int as Int32 to more safely represent GraphQL spec compliant data. This made using the models much more cumbersome. Beta 1 changes this behavior so only input variables that may be sent to a GraphQL server use Int32.
InputObject (#730): Fixed a bug when generating a nullable list of nullable items on an InputObject.This is the an alpha stage preview release of Apollo iOS 2.0. This preview release contains APIs that are still in development and are subject to change prior to stable release.
This version is likely to contain bugs and some features are still limited. This preview is intended to allow interested users to test out the new APIs and provide feedback to help shape the final product.
We are looking for bug reports as well as use cases that may not be supported by the current APIs. Any general feedback on the project is welcome as well. Bug reports can be filed as GitHub issues. For feature requests and general feedback, please comment on the https://github.com/apollographql/apollo-ios/issues/3411.
Int32The generated models will now represent Integers using Int32 instead of Int. The GraphQL spec specifically states that Int is a 32-bit integer, so this aligns us more correctly with the specification.
The impact of this change on the usability of the generated models is unclear at this time. We are seeking feedback on if this change is too much of an issue for users. While we would like to keep this new behavior, if user feedback is negative, this may be reverted or made into an optional behavior based on a codegen configuration option.
The codegen engine, apollo-ios-cli, pagination library, unit tests and other development projects have all been updated to Swift 6 with strict concurrency enabled.