Installing Apollo iOS
Follow the steps below to add Apollo iOS to your app:
1. Update Xcode
Before installing Apollo iOS, make sure you're using the latest version of Xcode. You can update Xcode via the Mac App Store.
2. Install the Apollo framework
You can install Apollo.framework into your project using any of the three major Cocoa ecosystem package managers: Swift Package Manager, CocoaPods, or Carthage.
Swift Package Manager Installation
Note: These instructions use the Xcode 13 UI. Xcode 11 is the first version of Xcode that integrates Swift Package manager, whereas older versions require using the command line. If you're using an older version of Xcode, we recommend using CocoaPods instead.
https://github.com/apollographql/apollo-ios.git) into the search bar, then select the apollo-ios package that appears:Xcode automatically suggests the dependency ruleUp to Next Major. We strongly suggest that until the release of Apollo iOS1.x, you selectUp To Next Minorinstead, because we might release breaking changes in a minor version.
Apollo library for now. You can always add other packages later if you need them.Note: Do not select the Apollo-Dynamic target. This target is only for projects that link to Apollo iOS. Most projects do not need to do this.Then, click Add Package.CocoaPods Installation
Install or update CocoaPods
Because Apollo iOS uses Swift 5, you need to use CocoaPods version1.7.0 or later. You can install CocoaPods with the following command:1gem install cocoapodsAdd dependencies
Addpod "Apollo" to your Podfile.- To include the
ApolloSQLiteframework, also addpod "Apollo/SQLite" - To include the
ApolloWebSocketframework, also addpod "Apollo/WebSocket"
pod install..xcworkspace file generated by CocoaPods to work on your project.Carthage Installation
Set up your Cartfile
Add github "apollographql/apollo-ios" to your Cartfile.Check out and build dependencies
Runcarthage update --use-xcframeworks --platform ios (or --platform ios,macos to build both Mac and iOS).Note: There's an issue with the way Carthage uses Lipo in the Xcode 12 GM. Pleasecdinto[YourProject]/Carthage/Checkouts/apollo-ios/scriptsand then run./carthage-build-workaround.shto resolve this build issue.
Add built frameworks to your project
Drag and dropApollo.framework from the appropriate Carthage/Build/iOS or Carthage/Build/Mac folder to the Embedded Binaries section of your application target's General settings tab. This should also cause them to appear in the Linked Frameworks And Libraries section automatically.- To include the
ApolloSQLitelibrary, also dragApolloSQLite.frameworkandSQLite.frameworkto this area. - To include the
ApolloWebSocketlibrary, also dragApolloWebSocket.frameworkandStarscream.frameworkto this area.
Work around Carthage submission bug
On your application target's Build Phases settings tab, click the + icon and choose New Run Script Phase. Create a Run Script in which you specify your shell (e.g.,bin/sh) and add the following contents to the script area below the shell:1/usr/local/bin/carthage copy-frameworks1$(SRCROOT)/Carthage/Build/iOS/Apollo.frameworkApolloSQLite or ApolloWebSocket, please make sure to add the other frameworks you added as Input Files.This script works around an App Store submission bug triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving.3. Add a schema file to your target directory
For Apollo iOS to generate models for your GraphQL operations, you need a local copy of your GraphQL server's schema. To acquire this schema, see Downloading a schema.
Make sure to add your schema.json/schema.graphqls file to the folder where most of your code is, not to the folder where your .xcodeproj and/or .xcworkspace files are located.
Here's an example file structure:
1| - your_project_folder
2 | your_project.xcodeproj
3 | - your_target_folder
4 | schema.json or schema.graphqls
5 | AppDelegate.swift
6 | ViewController.swift
7 | etc...
8 | - another_target_folder
9 | etc...Note: You can put the schema file in a different location, but if you do, you need to modify all relative paths to the file shown in future steps.
3. Install the Xcode add-ons for syntax highlighting (optional)
Check out the xcode-apollo repository and follow its installation guide.
4. Create .graphql files for your GraphQL operations
Apollo iOS generates code from GraphQL queries and mutations defined in .graphql files in your target. As a useful convention, you can define each [operation].graphql file alongside whichever [operation].swift file uses the corresponding operation.
If you have the Xcode add-ons installed, you can use the Xcode companion view to show a .swift file and its corresponding .graphql file side by side.
Note: If you don't have any
.graphqlfiles in your build tree yet, create one that contains a basic valid operation. If you don't, the code generation build step generates the errorNo operations or fragments found to generate code for.
5. Add a code generation build step
Apollo iOS code generation uses your .graphql files to generate API code that helps you execute all forms of GraphQL operations, as well as parse and cache operation responses. To run code generation as part of the Xcode build process, you need to create a build step that runs before "Compile Sources" to invoke a wrapper script.
The wrapper script calls through to the included binaries and files that constitute the apollo command-line interface. This helps ensure that you can use our tooling without having to worry about mismatched versioning between libraries.
📣 Check it out: Instead of writing the rest of this in Bash, try using our new Swift Scripting Library, now in Beta! It supports downloading a schema and generating code.
The location of this wrapper script depends on how you've integrated Apollo into your project, but these first steps are always the same:
On your application target's Build Phases settings tab, click the + icon and choose New Run Script Phase.
In the created Run Script, change its name to Generate Apollo GraphQL API.
Drag this new run script just above Compile Sources in your list of Build Phases so that it executes before your code is compiled.
Add the contents of the appropriate run script for the package manager you're using:
Swift Package Manager Run Script
Note: If your Derived Data is in a custom location, go back and use the Swift Scripting method instead. This script relies on Derived Data being in the default location. Swift Scripting doesn't rely on Derived Data at all.If you're using Xcode 11 or higher, SPM checks out the appropriate build script along with the rest of the files when it checks out the repo. Add the following to your Run Script build phase:
1# Don't run this during index builds
2if [ $ACTION = "indexbuild" ]; then exit 0; fi
3
4# Go to the build root and search up the chain to find the Derived Data Path where the source packages are checked out.
5DERIVED_DATA_CANDIDATE="${BUILD_ROOT}"
6
7while ! [ -d "${DERIVED_DATA_CANDIDATE}/SourcePackages" ]; do
8 if [ "${DERIVED_DATA_CANDIDATE}" = / ]; then
9 echo >&2 "error: Unable to locate SourcePackages directory from BUILD_ROOT: '${BUILD_ROOT}'"
10 exit 1
11 fi
12
13 DERIVED_DATA_CANDIDATE="$(dirname "${DERIVED_DATA_CANDIDATE}")"
14done
15
16# Grab a reference to the directory where scripts are checked out
17SCRIPT_PATH="${DERIVED_DATA_CANDIDATE}/SourcePackages/checkouts/apollo-ios/scripts"
18
19if [ -z "${SCRIPT_PATH}" ]; then
20 echo >&2 "error: Couldn't find the CLI script in your checked out SPM packages; make sure to add the framework to your project."
21 exit 1
22fi
23
24cd "${SRCROOT}/${TARGET_NAME}"
25"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swiftNote: If you try to use this with command line SPM, when you regenerate your xcodeproj this build script will get wiped out. We strongly recommend using Xcode 11's built-in SPM handling instead of the command line because of this.CocoaPods Run Script
apollo CLI client as files which will not be added to the framework, but which you can still call from a Run Script Build Phase. Add the following to the Run Script:1# Don't run this during index builds
2if [ $ACTION = "indexbuild" ]; then exit 0; fi
3
4SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts"
5cd "${SRCROOT}/${TARGET_NAME}"
6"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swiftCarthage Run Script
Carthage/Checkouts folder. If this folder is not checked into version control, all developers on a team (and your CI machine) need to run carthage checkout when changes are made to the version to ensure they have the correct underlying binaries and scripts.Team members can then use this build script:1# Don't run this during index builds
2if [ $ACTION = "indexbuild" ]; then exit 0; fi
3
4SCRIPT_PATH="${SRCROOT}/Carthage/Checkouts/apollo-ios/scripts"
5cd "${SRCROOT}/${TARGET_NAME}"
6"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swift6. Build your target
At this point, you can try building your target in Xcode. This verifies that the code generation build step can correctly locate your schema file.
Troubleshooting
If you get this error:
Cannot find GraphQL schema file [...]
The script can't locate your schema file. Double check the path you've used.
If you get this error:
No operations or fragments found to generate code for.
You haven't defined at least one .graphql file with a valid operation in your build tree.
If you need to validate the structure of a GraphQL operation, you can test it against your GraphQL server using Apollo Sandbox.
7. Add the generated API file to your target
Drag the generated API.swift file to your target.
Note: Because Apollo iOS generates operation-specific result types,
API.swiftis mostly empty at this point unless you've already added multiple.graphqlfiles to your target directory.
Make sure to uncheck the "Copy Files If Needed" checkbox, because it should already be in your project's folder system. Then, make sure you've checked all the Targets the API file needs to be included in.
Installation complete! You can now start executing GraphQL operations in your app. To learn how, next check out Creating a client and Fetching queries.
You can also continue reading below for some advanced codegen tips.
Advanced codegen tips and tricks
After you get up and running, here are a few improvements you can make to your codegen process.
Prevent unnecessary recompilation
Set up input and output files in your build phase
If you're using a tool like Interface Builder or SwiftUI to talk to a module with its own code generation build step, this is helpful to prevent the API.swift file from causing an auto-regeneration loop.
For example, if you're using something like this to run your code generation for a target called YourTarget:
1"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swiftAssuming you've set the script to run from $(SRCROOT)/YourTarget, you can add $(SRCROOT)/YourTarget/**/*.graphql (the path you're running it from + the glob you're passing to the includes CLI parameter) to the list of Input Files for your Apollo Run Script Build phase. Then, you can add $(SRCROOT)/YourTarget/API.swift (the path you're running it from + the output file) to the list of Output Files:
This should prevent automatic rebuild cycles if none of the InputFiles are changed. The script will still run if you explicitly build and run.
There's an open issue to auto-generate input and output file lists which will be addressed as part of Apollo iOS 1.0, but this will help until that's done.
Write to a temporary file
If for some reason the input/output file setup above doesn't work for you, you can also decide to first write the file to a temporary location, and then compare this temporary file to the current one. Then, only when the files differ you move the temporary file into place.
For a target called YourTarget, the script could look something like this:
1"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" "${SRCROOT}/YourTarget/API.swift.new"
2if ! diff -q "${SRCROOT}/YourTarget/API.swift.new" "${SRCROOT}/YourTarget/API.swift"; then
3 mv "${SRCROOT}/YourTarget/API.swift.new" "${SRCROOT}/YourTarget/API.swift"
4else
5 rm "${SRCROOT}/YourTarget/API.swift.new"
6fiGenerate multiple files in a folder instead of one large file
Instead of passing a single API.swift file, you can pass a (pre-existing) relative folder path such as API as the final parameter. This causes the codegen to create individual files and place them in that folder.
With small sets of graphql files this is usually unnecessary, but with large sets that can cause API.swift to be huge. Dividing it up like this can help significantly reduce compilation time.