NS

GraphQL Using Apollo and SwiftUI

Before we build a full-stack application from scratch, let’s get some terms out of the way:

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.” —GraphQL website

Apollo Client is a complete state management library for JavaScript apps. Simply write a GraphQL query, and Apollo Client will take care of requesting and caching your data, as well as updating your UI. Fetching data with Apollo Client guides you to structure your code in a predictable, declarative way consistent with modern React best practices. With Apollo, you can build high-quality features faster without the hassle of writing data plumbing boilerplate.” — Apollo website

SwiftUI is an innovative, exceptionally simple way to build user interfaces across all Apple platforms with the power of Swift. Build user interfaces for any Apple device using just one set of tools and APIs. With a declarative Swift syntax that’s easy to read and natural to write, SwiftUI works seamlessly with new Xcode design tools to keep your code and design perfectly in sync. Automatic support for Dynamic Type, Dark Mode, localization, and accessibility means your first line of SwiftUI code is already the most powerful UI code you’ve ever written” — Apple Developer website

Firstly, we will build a GraphQL schema, something as simple as this:

type Person { title: String  name: String }

Once you push the schema using amplify push, it will auto-generate queries, mutations, and subscriptions for you. Copy over the queries, mutations, and subscriptions inside your SwiftUI project directory.

The next file you need to import is your schema.json. If you run amplify status, it will give you the GraphQL endpoint where your schema is hosted.

Copy the generated schema.json to your project directory. The easiest way I could find to generate schema.json is by using the following query:

apollo schema:download --endpoint=<your\_endpoint>/graphql schema.json --header="x-api-key: <your-api-key"

We almost have our GraphQL side ready. One last step is to create a new run script phase. Go to build phases and add a new run script phase, and then add the following script to the Shell area.

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

That is everything you need to do to import GraphQL into your SwiftUI application. You should be able to build your project now. This will generate a new file called API.Swift in your project structure. Make sure the file resides in the same folder structure as GraphQL schema and queries.

Now that we have our API ready, we need Apollo to sit between our UI and GraphQL. It will help manage data and state in an application. Apollo will take care of requesting and caching your data, as well as updating your UI. While ApolloGraphQL is still not there, it’s awesome.

In the terminal, create the following:

cd proj\_directory  
pod init

This should create a Podfile Hereafter you should use <ProjectName>.xcworkspace to open your project. Open the Podfile and add Apollo to your Podfile.

pod "Apollo"

Create a new class in your project and name it Network. Paste the following code with your GraphQL endpoint and api-key, as below:

import Foundation
import Apollo

class Network {
    static let shared = Network()
    let apollo: ApolloClient = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = [
            "x-api-key": "<YOUR-API-KEY>"
        ]

        let url = URL(string: "<YOUR-GRAPHQL-ENDPOINT>")!

        return ApolloClient(
            networkTransport: HTTPNetworkTransport( url: url, session: URLSession(configuration: configuration))
        )
    }()
}

Ok, phew! Our app is now ready to communicate to GraphQL.

To perform basic operations, use the following:

Fetch

Network.shared.apollo.fetch(query: ListPersonQuery) { result in
            switch result {
                case .success(let graphQLResult):
                    if let items = graphQLResult.data?.listPerson?.items {
                        for conf in items {
                            if let curPerson = conf {
                            //Do whatever here with your Graphql Result
                                print(curPerson)
                            }
                        }
                    }
                    self.loading = false
            case .failure(let error):
                    print("Failure! Error: \(error)")
            }
        }

Post

Network.shared.apollo.perform(mutation: CreatePersonMutation(input: personInput)) { result in
            switch result {
            case .success(let graphQLResult):
                print(graphQLResult)
            case .failure(let error):
                print("Failure! Error: \(error)")
            }
        }

There you go. Now you have a full-stack SwiftUI application with a GraphQL back end. Happy hacking!

That’s all, folks!