Odyssey

Apollo iOS and Swift: Codegen and Queries
beta

Course intro and setupSandbox ExplorerAdd the GraphQL schemaRunning code generationExecute your first queryConnect your queries to your UIAdd more info to the list
4. Running code generation
2m

Overview

Now that we have both a schema and a query file, it's time to run code generation.

In this lesson, we will:

  • Run the codegen command
  • Add the generated code to our project
  • Examine how the code changes when we alter our query

Running code generation

To run code generation run the following command in a terminal opened to your project directory:

./apollo-ios-cli generate

In Finder, you should now see a new RocketReserverAPI folder in your project directory which contains the Swift package with your generated source code.

📦 starter
┣ 📂 RocketReserver
┣ 📂 RocketReserver.xcodeproj
┣ 📂 RocketReserverAPI
┣ 📄 apollo-codegen-config.json
┣ 📄 apollo-ios-cli
┗ 📂 graphql

Error: GraphQLError-Syntax-Error: Unexpected EOF

You'll see this error if the Codegen CLI is unable to locate a valid query in your LaunchList GraphQL file.

How to fix it: Double check that you copied the whole operation from Sandbox, and that the file has been saved! Then try running the command again.

Still having trouble? Visit the Odyssey forums to get help.

Add the generated SPM package to your project

With the code generated, next we need to add the generated SPM package to the project.

The default configuration for code generation creates a new Swift package for the schema module and operations. For more information on code generation such as different module types you can generate or different ways to run code generation see the documentation.

  1. In Xcode go to File > Add Package Dependencies..., in the dialog select Add Local...

    The Package Dependencies modal opened, highlighting Add Local Package

  2. Select the RocketReserverAPI folder in the file dialog, then click Add Package.

    The RocketReserverAPI folder in the file system

    Add it to the app target.

    Adding the RocketReserverAPI to project as target

  3. You should now see the RocketReserverAPI package included in your project.

    The RocketReserverAPI package in local dependencies

Great! Let's take a look at what we added.

Task!

Examine the generated code

In the Xcode project hierarchy, find RocketReserverAPI under Dependencies. Drill down to /Sources/Operations/Queries/LaunchListQuery.graphql.swift.

The LaunchListQuery generated file in the RocketReserverAPI dependency

That generated file defines a root class, LaunchListQuery, with many nested structs below it. If you compare the structs to the JSON data returned in Apollo Sandbox, you see that the structure matches. These structs include properties only for the fields that your query requests.

LaunchListQuery.graphql.swift
# ... other structs
public struct Launch: RocketReserverAPI.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { RocketReserverAPI.Objects.Launch }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("id", RocketReserverAPI.ID.self),
.field("site", String?.self),
] }
public var id: RocketReserverAPI.ID { __data["id"] }
public var site: String? { __data["site"] }
}

Let's see how this generated file changes when we alter our LaunchList query. Jump back into LaunchList.graphql, in our project's main graphql file. Let's comment out the id field, using a #.

query LaunchList {
launches {
cursor
hasMore
launches {
# id
site
}
}
}

Save the file, then open up your terminal. Let's rerun the codegen command.

./apollo-ios-cli generate

Now let's check out the results in LaunchListQuery.graphql, deep in the RocketReserverAPI dependency.

LaunchListQuery.graphql.swift
# ... other structs
public struct Launch: RocketReserverAPI.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { RocketReserverAPI.Objects.Launch }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("site", String?.self),
] }
public var site: String? { __data["site"] }
}

The innermost Launch now only includes the built-in __typename and the requested site property—the id field, because we commented it out, is nowhere to be found! This gives us a really good idea of how the codegen process outputs exactly the code we'll need to make our operations functional—nothing more, and nothing less.

We actually do want to keep the id field, so let's uncomment it in LaunchList.graphql and re-run code generation to restore the property.

Task!

Up next

Now that you've generated code and had a chance to see what's in there, it's time to get everything working end to end! Next, we'll execute the query.

Previous
Next

Share your questions and comments about this lesson

This course is currently in

beta
. Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              operation

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              operations

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              Apollo Sandbox

              A part of GraphOS Studio focused on local development, available at https://studio.apollographql.com/sandbox. Apollo Sandbox does not require an Apollo account.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              operations

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              NEW COURSE ALERT

              Introducing Apollo Connectors

              Connectors are the new and easy way to get started with GraphQL, using existing REST APIs.

              Say goodbye to GraphQL servers and resolvers—now, everything happens in the schema!

              Take the course