Integrating OAuth for Gmail Using iOS with Swift and GDATA Framework

iPhone SDK - GDATA OAuth

=====================================================

In this tutorial, we will walk through the process of integrating Gmail authentication using OAuth into an iPhone application built with Xcode and Swift. We will also explore how to use the GDATA framework for interacting with the Gmail API.

Introduction


OAuth is a widely used authorization protocol that allows applications to access resources on behalf of a user without sharing their credentials. In this tutorial, we will focus on implementing OAuth for Gmail using the Google API Client Library for iOS (GTL). We will also cover how to use the GDATA framework for making requests to the Gmail API.

Prerequisites

  • Xcode 12 or later
  • Swift 5 or later
  • iPhone SDK for iOS
  • A Gmail account with a valid email address and password

Installing the Google API Client Library for iOS (GTL)


Before we begin, you need to install the GTL library in your project. You can do this by following these steps:

Step 1: Create a new Xcode project

Create a new single-view app project in Xcode.

Step 2: Add the Google API Client Library for iOS (GTL) to your project

  1. Open your project’s Podfile and add the GTL library by running the following command:

pod ‘GoogleAPIClientForREST/ios’


2.  Run the following command to install the GTL library:

    ```
pod install
  1. Open the generated .xcassets folder in your project’s navigator and drag the GTL.gymmo file into your main storyboard.

Implementing OAuth for Gmail


To implement OAuth for Gmail, you need to follow these steps:

Step 1: Set up your Gmail account

  • Go to the Google Cloud Console and create a new project.
  • Click on “Enable APIs and Services” and search for “Gmail API”. Select it and click on “Enable”.
  • Create credentials for your app by clicking on “Create Credentials” and selecting “OAuth client ID”.
  • Choose “Other” as the application type and enter a authorized JavaScript origins (if you want to use this app with web pages).
  • Save the Client ID and Client secret.

Step 2: Install the Google API Client Library for iOS (GTL)

We have already installed the GTL library in your project. Now, let’s import it into our code:

import GoogleAPIClientForREST

Step 3: Set up OAuth

Create a new class to handle OAuth:

class OAuthManager {
    static let sharedInstance = OAuthManager()
    private var clientID: String?
    private var clientSecret: String?

    private init() {
        self.clientID = "YOUR_CLIENT_ID"
        self.clientSecret = "YOUR_CLIENT_SECRET"
    }

    func authenticate(with callbackUrl url: URL) {
        // Create a service instance
        let service = GoogleServiceClient(
            scopes: ["https://www.googleapis.com/auth/gmail.send"],
            clientId: clientID,
            clientSecret: clientSecret)

        // Get an authorization code from the user
        if #available(iOS 13.0, *) {
            guard let url = URLComponents(string: "https://accounts.google.com/o/oauth2/auth?client_id=\(clientID)&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send")?.url else { return }

            // Open the authorization URL in the user's browser
            guard let authUrl = UIApplication.shared.openURL(url) else {
                print("Failed to open URL")
                return
            }
        } else {
            // Handle iOS 12 or earlier
            // Create an authorization code from the url parameter
            guard let queryItems = url.queryComponents else { return }

            if let code = queryItems["code"], !code.isEmpty {
                handleCode(code: code)
            } else {
                print("No auth code found")
            }
        }
    }

    private func handleCode(code: String) {
        // Create a token request
        let request = Request(
            method: .POST,
            path: "/oauth2/v2/token",
            headers: [
                "Content-Type": "application/x-www-form-urlencoded"
            ],
            body: ["grant_type": "authorization_code", "code": code, "redirect_uri": "YOUR_REDIRECT_URI"]
        )

        // Send the request
        guard let service = GoogleServiceClient(
            scopes: ["https://www.googleapis.com/auth/gmail.send"],
            clientId: clientID,
            clientSecret: clientSecret) else { return }

        do {
            let response = try await service.perform(request)
            print(response.statusCode)
            print(response.body!)
        } catch {
            print(error)
        }
    }
}

Step 4: Use OAuth in your code

Use the OAuthManager class to authenticate:

func loginWithOAuth() async {
    // Create an instance of OAuthManager
    let oAuth = OAuthManager.sharedInstance
    
    // Authenticate with the Gmail API
    try? await oAuth.authenticate(with: URL(string: "YOUR_REDIRECT_URI")!)

    // Use the access token to send requests
    // For example, you can use it to read emails from your inbox:
    let service = GoogleServiceClient(
        scopes: ["https://www.googleapis.com/auth/gmail.readonly"],
        clientId: oAuth.clientID,
        clientSecret: oAuth.clientSecret)

    do {
        let response = try await service.perform(Request(method: .GET, path: "/messages list", headers: [ "Authorization" : "Bearer YOUR_ACCESS_TOKEN"]))
        print(response.statusCode)
        print(response.body!)
    } catch {
        print(error)
    }
}

Using GDATA Framework


The GDATA framework provides a simple way to interact with the Gmail API. You can use it to send emails, create labels and folders, and more.

Step 1: Install the GDATA framework

Install the GTM framework by adding this line of code to your Podfile:

pod 'GTM'

Then install it using pod install.

Step 2: Set up a service instance

Create an instance of GTMService and set its scope:

let service = GTMService(
    scopes: ["https://www.googleapis.com/auth/gmail.send"],
    clientId: oAuth.clientID,
    clientSecret: oAuth.clientSecret)

Step 3: Send emails

Use the send method to send an email:

do {
    let request = Request(method: .POST, path: "/messages", headers: [
        "Content-Type": "application/json; charset=UTF-8"
    ], body: [
        "raw": JSON(data: """
            {
                "labelIds": ["UNREAD"],
                "threadId": "msg-threadid",
                "message": {
                    "body": {
                        "text": {
                            "value": "Hello world!",
                            "Format": "raw"
                        },
                        "html": {
                            "value": "<b>Hello</b> <b>world!</b>",
                            "Format": "raw"
                        }
                    },
                    "payload": {
                        "body": {
                            "text": {
                                "value": "Hello world!",
                                "Format": "raw"
                            },
                            "html": {
                                "value": "<b>Hello</b> <b>world!</b>",
                                "Format": "raw"
                            }
                        },
                        "headers": [
                            {
                                "from": ["sender@example.com"],
                                "to": ["recipient@example.com"]
                            }
                        ]
                    }
                }
            }
        """.data(using: .utf8) ?? Data(),
    ]

    let response = try await service.perform(request)
    print(response.statusCode)
    print(response.body!)
} catch {
    print(error)
}

Step 4: Create labels and folders

Use the labels or folders method to create new labels or folders:

do {
    let request = Request(method: .POST, path: "/labels", headers: [
        "Content-Type": "application/json; charset=UTF-8"
    ], body: [
        "name": "My label",
        "colorId": 0,
        "labelType": "user-defined"
    ])

    let response = try await service.perform(request)
    print(response.statusCode)
    print(response.body!)
} catch {
    print(error)
}

do {
    let request = Request(method: .POST, path: "/folders", headers: [
        "Content-Type": "application/json; charset=UTF-8"
    ], body: [
        "name": "My folder",
        "labelIds": ["INBOX"],
        "folderType": "child"
    ])

    let response = try await service.perform(request)
    print(response.statusCode)
    print(response.body!)
} catch {
    print(error)
}

Conclusion


In this tutorial, we covered how to implement OAuth for Gmail using the Google API Client Library for iOS (GTL) and the GDATA framework. We also explained how to use these libraries to send emails, create labels and folders, and more.

Note that the above implementation is a basic example of how you can integrate OAuth with Gmail into your iPhone application. Depending on your specific requirements, you might need to add additional functionality or handle errors differently.


Last modified on 2023-08-02