Implementation of graphql in iOS
Did you ever feel frustrated when working with a REST API, because the endpoints didn’t give you the data you needed for the views in your app? Getting the right information from the server either required multiple requests or you had to bug the backend developers to adjust the API? Worry no more — it’s GraphQL and Apollo to the rescue!
GraphQL is a new API design paradigm open-sourced by Facebook in 2015, but has been powering their mobile apps since 2012. It eliminates many of the inefficiencies with today’s REST API. In contrast to REST, GraphQL APIs only expose a single endpoint and the consumer of the API can specify precisely what data they need.
iOS Apollo Installation
Let’s get started by installing apollo client framework & peer graphql dependencies:
1) Cd your xcworkspace file path
2) pod ‘Apollo’
3) pod install
Adding a code generation build step
In order to invoke apollo
as part of the Xcode build process, create a build step that runs before "Compile Sources".
- On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script, change its name to “Generate Apollo GraphQL API” and drag it just above “Compile Sources”. Then add the following contents to the script area below the shell:
SCRIPT_PATH=”${PODS_ROOT}/Apollo/scripts”
cd “${SRCROOT}/${TARGET_NAME}”
“${SCRIPT_PATH}”/run-bundled-codegen.sh codegen:generate — target=swift — includes=./**/*.graphql — localSchemaFile=”schema.json” API.swift
schema.json : Name of schema file
API.swift : It will be auto generated class after running above script.
Adding a schema file to your target directory
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
apollo schema:download — endpoint=http://hasura.io/learn/graphql — header=”Authorization: Bearer <token>”
Create .graphql files with your queries or mutations
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.
Create apollo client
Write your query or mutation inside .graphql file , like this:
mutation registerUser ($userDetail:UserInput!){
createUser(user:$userDetail){
id
token
fname
lname
bio
}}
//MARK:- Call When Need To Register User With An App
func registerUser(completion:@escaping (Bool,String?)->()) {
let apollo = ApolloClient(url: URL(string: “Your graphql url")!)
let sendDict = UserInput(email:”abc@test.com”,fname:”test”, lname: “app”,password:”1234567")
apollo.perform(mutation:RegisterUserMutation.init(userDetail:sendDict)) { result in
switch result {
case .success(let graphQLResult):
if(graphQLResult.errors?.count == nil){
completion(true,””)
}else{
completion(false,graphQLResult.errors?.first?.message)
}
break
case .failure(let error):
NSLog(“Error while create user: \(error.localizedDescription)”)
completion(false,error.localizedDescription)
}}}
Mutation is used to save a data in graphql database.
Let’s take an example of query, it is used to get a data from graphql db.
query AllHuntingTypes {
selectHuntingTypes {
types{
title
id
}
categories{
title
id
}}
}
//MARK:- Call When Need To Fetch All Categories
apollo.fetch(query:AllHuntingTypesQuery.init()){ result in
switch result {
case .success(let graphQLResult):
if(graphQLResult.errors?.count == nil){
self.arrHuntingTypes = graphQLResult.data?.selectHuntingTypes?.types as?[AllHuntingTypesQuery.Data.SelectHuntingType.Type]
self.arrHuntingCat = graphQLResult.data?.selectHuntingTypes?.categories as? [AllHuntingTypesQuery.Data.SelectHuntingType.Category]
completion(true,””)
}else{
completion(false,graphQLResult.errors?.first?.message)
}
break
case .failure(let error):
NSLog(“Error while create user: \(error.localizedDescription)”)
completion(false,error.localizedDescription)
}
}
}
Summing Up
GraphQL is a modern way to communicate with your server. It can replace the commonly used REST API approach. With GraphQL, you communicate with the back end via just one endpoint using declarative syntax.
Using GraphQL in your Swift applications for iOS, iPadOS, watchOS, macOS, and tvOS is easy with the Apollo framework. It’s officially supported by the GraphQL community, and lately, it has been well maintained and supported.
Links
- Official iOS GraphQL documentation and repository
- Blog post