top of page

Integrating Hasura and Implementing GraphQL in Swift-Based iOS Apps using Apollo


Integrating Hasura and Implementing GraphQL in Swift-Based iOS Apps using Apollo

Building robust and efficient iOS applications often involves integrating powerful backend services. Hasura, a real-time GraphQL engine, provides a convenient way to connect and interact with databases, enabling seamless integration between your iOS app and your backend.


In this tutorial, we will explore how to integrate Hasura and use GraphQL in Swift-based iOS apps. We will cover all CRUD operations (Create, Read, Update, Delete), as well as subscribing and unsubscribing to real-time updates.


Prerequisites


To follow this tutorial, you should have the following:

  1. Xcode installed on your machine

  2. Basic knowledge of Swift programming

  3. Hasura GraphQL endpoint and access to a PostgreSQL database


1. Set Up Hasura and Database


Before we dive into coding, let's set up Hasura and Database:


1.1 Install Hasura CLI


Open a terminal and run the following command:

curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash

1.2 Initialize Hasura project


Navigate to your project directory and run:

hasura init hasura-app

1.3 Configure Hasura


Modify the config.yaml file generated in the previous step to specify your database connection details.


1.4 Apply migrations


Apply the initial migration to create the required tables and schema. Run the following command:

hasura migrate apply

1.5 Start the Hasura server


Run the following command:

hasura server start

2. Set Up the iOS Project


Now let's set up our iOS project and integrate the required dependencies:


  • Create a new Swift-based iOS project in Xcode.

  • Install Apollo GraphQL Client: Use CocoaPods or Swift Package Manager to install the Apollo iOS library. Add the following line to your Podfile and run pod install:

pod 'Apollo'
  • Create an ApolloClient instance: Open the project's AppDelegate.swift file and import the Apollo framework. Configure and create an instance of ApolloClient with your Hasura GraphQL endpoint.

import Apollo

// Add the following code in your AppDelegate.swift file
let apollo = ApolloClient(url: URL(string: "https://your-hasura-endpoint")!)

3. Perform CRUD Operations with GraphQL


Now we'll demonstrate how to perform CRUD operations using GraphQL in your Swift-based iOS app:


3.1 Define GraphQL queries and mutations


In your project, create a new file called GraphQL.swift and define the GraphQL queries and mutations you'll be using. For example:

import Foundation

struct GraphQL {
    static let getAllUsers = """
    query GetAllUsers {
        users {
            id
            name
            email
        }
    }
    """
    static let createUser = """
    mutation CreateUser($name: String!, $email: String!) {
        insert_users_one(object: {name: $name, email: $email}) {
            id
            name
            email
        }
    }
    """
    static let updateUser = """
    mutation UpdateUser($id: Int!, $name: String, $email: String) {
        update_users_by_pk(pk_columns: {id: $id}, _set: {name: $name, email: $email}) {
            id
            name
            email
        }
    }
    """
    static let deleteUser = """
    mutation DeleteUser($id: Int!) {
        delete_users_by_pk(id: $id) {
            id
            name
            email
        }
    }
    """
}

3.2 Fetch data using GraphQL queries


In your view controller, import the Apollo framework and make use of the ApolloClient to execute queries. For example:

import Apollo

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        apollo.fetch(query: GetAllUsersQuery()) { 
        result in
        switch result {
            case .success(let graphQLResult):
                // Handle the result
                if let users = graphQLResult.data?.users {
                    // Process the users data
                }

            case .failure(let error):
                // Handle the error
                print("Error fetching users: \(error)")
            }
        }
    }
}

3.3 Perform mutations for creating/updating/deleting data


Use ApolloClient to execute mutations. For example:

// Create a user
apollo.perform(mutation: CreateUserMutation(name: "John", email: "john@example.com")) { result in
switch result {
    case .success(let graphQLResult):
        // Handle the result
        if let user = graphQLResult.data?.insert_users_one {
            // Process the newly created user
        }

    case .failure(let error):
        // Handle the error
        print("Error creating user: \(error)")
    }
}

// Update a user
apollo.perform(mutation: UpdateUserMutation(id: 1, name: "Updated Name", email: "updated@example.com")) { result in
switch result {
    case .success(let graphQLResult):
        // Handle the result
        if let updatedUser = graphQLResult.data?.update_users_by_pk {
            // Process the updated user data
        }

    case .failure(let error):
        // Handle the error
        print("Error updating user: \(error)")
    }
}

// Delete a user
apollo.perform(mutation: DeleteUserMutation(id: 1)) { result in
switch result {
    case .success(let graphQLResult):
        // Handle the result
        if let deletedUser = graphQLResult.data?.delete_users_by_pk {
            // Process the deleted user data
        }

    case .failure(let error):
        // Handle the error
        print("Error deleting user: \(error)")
    }
}


4. Subscribe and Unsubscribe to Real-Time Updates


Hasura allows you to subscribe to real-time updates for specific data changes. Let's see how to do that in your iOS app:


4.1 Define a subscription


Add the subscription definition to your GraphQL.swift file. For example:

static let userAddedSubscription = """
subscription UserAdded {
    users {
        id
        name
        email
    }
}
"""

4.2 Subscribe to updates


In your view controller, use ApolloClient to subscribe to the updates. For example:

swiftCopy code
let subscription = apollo.subscribe(subscription: UserAddedSubscription()) { result in
switch result {
    case .success(let graphQLResult):
        // Handle the real-time update
        if let user = graphQLResult.data?.users {
            // Process the newly added user
        }

    case .failure(let error):
        // Handle the error
        print("Error subscribing to user additions: \(error)")
    }
}

4.3 Unsubscribe from updates


When you no longer need to receive updates, you can unsubscribe by calling the cancel method on the subscription object.

subscription.cancel()

Conclusion


In this tutorial, we learned how to integrate Hasura and use GraphQL in Swift-based iOS apps. We covered the implementation of CRUD operations (Create, Read, Update, Delete), as well as subscribing and unsubscribing to real-time updates.


By leveraging the power of Hasura and GraphQL, you can build responsive and efficient iOS apps that seamlessly connect with your backend services.


Happy coding!

Blog for Mobile App Developers, Testers and App Owners

 

This blog is from Finotes Team. Finotes is a lightweight mobile APM and bug detection tool for iOS and Android apps.

In this blog we talk about iOS and Android app development technologies, languages and frameworks like Java, Kotlin, Swift, Objective-C, Dart and Flutter that are used to build mobile apps. Read articles from Finotes team about good programming and software engineering practices, testing and QA practices, performance issues and bugs, concepts and techniques. 

bottom of page