Apollo gives a neat abstraction layer and an interface to your GraphQL server.
You don't need to worry about constructing your queries with request body, headers and options, that you might have done with AFNetworking
or NWConnection
say.
You can directly write queries and mutations in GraphQL, and they will automatically be sent to your server via your apollo client instance.
Let's get started by installing apollo client framework & peer graphql dependencies:
"apollostack/apollo-ios"
to your Cartfile.carthage update
bin/sh
), add the following contents to the script area below the shell:/usr/local/bin/carthage copy-frameworks
and add the paths to the frameworks you want to use under "Input Files", e.g.:
$(SRCROOT)/Carthage/Build/iOS/Apollo.framework
In order to invoke apollo
as part of the Xcode build process, create a build step that runs before "Compile Sources".
for iOS Project
APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"
if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi
The script above will invoke apollo
through the check-and-run-apollo-cli.sh
wrapper script, which is actually contained in the Apollo.framework
bundle. The main reason for this is to check whether the version of apollo
installed on your system is compatible with the framework version installed in your project, and to warn you if it isn't. Without this check, you could end up generating code that is incompatible with the runtime code contained in the framework.
You'll have to copy or download a schema to your target directory before generating code.
Apollo iOS requires a GraphQL schema file as input to the code generation process. A schema file is a JSON file that contains the results of an an introspection query. Conventionally this file is called schema.json
To download schema.json
, you need to use the id_token from auth0 and run this in your terminal
Tip:
Always remember to replace
API_SECRET
in the Bearer Token andproject-id
in the URL with the correct values from the Apito console.
If you are unsure where to find your API secrets and endpoints for your project, visit this page.
apollo schema:download --endpoint=https://api.apito.io/secured/graphql --header="Authorization: Bearer API_SECRET"
At this point, you can try building your target in Xcode. This will verify that the schema.json
file can be found by the apollo
script created above, otherwise you'll get a build error such as:
Cannot find GraphQL schema file [...]
API.swift
file to your target.Note that because Apollo iOS generates query-specific result types,
API.swift
will be mostly empty at this point unless you've already added some.graphql
files with queries or mutations to your target directory.
xcode-apollo
repository to your computer.~/Library/Developer/Xcode
:mkdir ~/Library/Developer/Xcode/Plug-ins ~/Library/Developer/Xcode/Specifications
GraphQL.ideplugin
to ~/Library/Developer/Xcode/Plug-ins
.cp -R GraphQL.ideplugin ~/Library/Developer/Xcode/Plug-ins
GraphQL.xclangspec
to ~/Library/Developer/Xcode/Specifications
.cp -R GraphQL.xclangspec ~/Library/Developer/Xcode/Specifications
You may receive a warning when you first start up Xcode after installing these add-ons.
Apollo iOS generates code from queries and mutations contained in .graphql
files in your target.
A useful convention is to colocate queries, mutations or fragments with the Swift code that uses them by creating <name>.graphql
next to <name>.swift
.
If you have the Xcode add-ons installed, you can use the Xcode companion view to show a .swift
file and the corresponding .graphql
file side by side.
Open LoginVC.swift and add below
case .success(let credentials):
if(!SessionManager.shared.store(credentials: credentials)) {
print("Failed to store credentials")
} else {
SessionManager.shared.retrieveProfile { error in
DispatchQueue.main.async {
guard error == nil else {
print("Failed to retrieve profile: \(String(describing: error))")
return self.showLoginWithPatch()
}
+ NetworkManager.shared.setApolloClient(accessToken: credentials.idToken!)
self.dismiss(animated: true, completion: nil)
}
}
}
}
DispatchQueue.main.async {
SessionManager.shared.retrieveProfile { error in
DispatchQueue.main.async {
guard error == nil else {
print("Failed to retrieve profile: \(String(describing: error))")
return callback()
}
+ NetworkManager.shared.setApolloClient(accessToken: (SessionManager.shared.credentials?.idToken!)!)
self.dismiss(animated: true, completion: nil)
}
}
}
We are passing our tokenID to be set in apollo client so that we can make authorised calls to our graphql backend. Now let's create this file which will return apollo client with httplink and cache. Lets call this file 'NetworkManager.swift`
:::note
Always remember to replace API_SECRET
with the correct value that you copied from apito console.
Go to this page if you do not know where to find your api secrets for your project
:::
import Foundation
import Apollo
import ApolloWebSocket
class NetworkManager {
static let shared = NetworkManager()
let graphEndpoint = "https://api.apito.io/secured/graphql"
var apolloClient : ApolloClient?
private init (){
}
func setApolloClient(accessToken: String){
self.apolloClient = {
let authPayloads = ["Authorization": "Bearer API_SECRET"]
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = authPayloads
let endpointURL = URL(string: graphEndpoint)!
return ApolloClient(networkTransport: HTTPNetworkTransport(url: endpointURL, configuration: configuration))
}()
}
}
For an alternate and detailed guide, be sure to check out the official apollo guide here