Introduction: Why GraphQL and Swift?
Modern iOS and macOS development requires flexible and efficient ways to interact with the server. Traditional REST APIs often lead to the problem of over-fetching (retrieving unnecessary data) or under-fetching (insufficient data). GraphQL solves these problems by allowing the client to request only the data it needs in a single query.
In this tutorial, we will create a full-fledged Swift application that interacts with a GraphQL API. You will learn how to set up the project, execute queries, mutations, and handle errors. As a client, we will use Apollo iOS — the most popular library for working with GraphQL in the Apple ecosystem.
Project Setup and Installing Apollo iOS
Creating a New Project
Open Xcode and create a new iOS or macOS App project. Let's name it GraphQLDemo.
Installing Apollo iOS via Swift Package Manager
- In Xcode, go to File → Add Packages...
- Paste the Apollo repository URL:
https://github.com/apollographql/apollo-ios.git - Select the latest stable version and click Add Package.
- Make sure the package is added to your app's target.
Code Generation from GraphQL Schema
Apollo uses code generation to create type-safe classes. For this, we need a schema file (schema.graphqls) and query files (.graphql).
Create a GraphQL folder in the project and place the following there:
schema.graphqls— download your API's schema or use a public one (e.g., Countries GraphQL API).Queries.graphql— a file with your queries.
Example content of Queries.graphql:
query GetCountries { countries { code name capital currency }}Now add a Build Phase for code generation. In Xcode: Target → Build Phases → + → New Run Script Phase. Paste the script:
cd "${SRCROOT}/${TARGET_NAME}"./Pods/Apollo/scripts/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile=./schema.graphqls ./GraphQL/API.swiftNote: In modern versions of Apollo iOS, apollo-ios-cli is used. We recommend checking the official documentation for up-to-date instructions.
Executing GraphQL Queries
Initializing the Apollo Client
Let's create a manager for working with Apollo. Open the file NetworkManager.swift:
import Foundationimport Apollo
class NetworkManager { static let shared = NetworkManager() private(set) lazy var apollo: ApolloClient = { let url = URL(string: "https://countries.trevorblades.com/")! return ApolloClient(url: url) }()}Executing a Query
Now let's execute the GetCountries query in our ViewController:
import UIKit
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() fetchCountries() } private func fetchCountries() { NetworkManager.shared.apollo.fetch(query: GetCountriesQuery()) { result in switch result { case .success(let graphQLResult): if let countries = graphQLResult.data?.countries { for country in countries { print("\\(country.name) - \\(country.capital ?? "N/A")") }