SDK quickstart

Updated

A highly reliable global communication platform where users can chat one-to-one, in groups or in chat rooms.

Instant messaging enhances user engagement by enabling users to connect and form a community within the app. Increased engagement can lead to increased user satisfaction and loyalty to your app. An instant messaging feature can also provide real-time support to users, allowing them to get help and answers to their questions quickly. The Chat SDK enables you to embed real-time messaging in any app, on any device, anywhere.

This page guides you through implementing peer-to-peer messaging into your app using the Chat SDK.

Understand the tech

The following figure shows the workflow of sending and receiving peer-to-peer messages using Chat SDK.

Chat SDK workflow

  1. Clients retrieve an authentication token from your app server.
  2. Users log in to Chat using the App ID, their user ID, and token.
  3. Clients send and receive messages through Chat as follows:
    1. Client A sends a message to Client B. The message is sent to the Agora Chat server.
    2. The server delivers the message to Client B. When Client B receives a message, the SDK triggers an event.
    3. Client B listens for the event to read and display the message.

Prerequisites

In order to follow the procedure on this page, you must have:

  • Xcode. This page uses Xcode 13.0 as an example.
  • A device running iOS 10 or later.

Project setup

To integrate Chat into your app, do the following:

  1. Create a new project for this device app using the App template. Select the Storyboard Interface and Swift Language.

    If you have not already added team information, click Add account…, input your Apple ID, then click Next.

  2. Enable automatic signing for your project. Set the target devices to deploy your iOS app to an iPhone or iPad.

  3. Add project permissions for microphone and camera usage:

    1. Open Info in the project navigation panel, then add the following properties to the Information Property List:

      KeyTypeValue
      NSMicrophoneUsageDescriptionStringAccess the microphone.
      NSCameraUsageDescriptionStringAccess the camera.
  4. Integrate Agora Chat SDK into your project:

    1. In Xcode, click File > Add Packages..., then paste the following link in the search:

      https://github.com/AgoraIO/AgoraChat_iOS.git

      You see the available Agora packages. In AgoraChat_iOS, specify the latest Chat SDK version, for example 1.0.9. You can obtain the latest version information in the release notes.

    2. Click Add Package. In the new window, click Add Package.

      You see AgoraChat in Package Dependencies for your project.

The privacy updates for App Store submissions released by Apple, require developers to declare approved reasons for using a set of APIs in their app’s privacy manifest. Agora provides a PrivacyInfo.xcprivacy file that you can include in your project. If you are using Chat SDK 1.2 or earlier, refer to Add a privacy manifest file for details.

Implement peer-to-peer messaging

This section shows how to use the Chat SDK to implement peer-to-peer messaging in your app, step by step.

Create the UI

In the quickstart app, you create a simple UI that consists of the following elements:

  • A UIButton to log in or out of the Chat.
  • A UITextField box to specify the recipient user ID.
  • A UITextField box to enter a text message.
  • A UIButton to send the text message.
  • A UITextView to display sent and received messages.

To create this user interface, in the ViewController class:

  1. Add the UI elements you need

    Add the following declarations at the top of the class.

    var btnJoinLeave: UIButton!
    var etRecipient: UITextField!
    var scrollView: UITextView!
    var etMessageText: UITextField!
    var btnSendMessage: UIButton!
  2. Configure the UI elements in your interface

    Add the following below super.viewDidLoad() inside the viewDidLoad method:

    btnJoinLeave = UIButton(type: .system)
    btnJoinLeave.frame = CGRect(x: 60, y: 100, width: 250, height: 30)
    btnJoinLeave.setTitle("Join", for: .normal)
    btnJoinLeave.addTarget(self, action: #selector(joinLeave), for: .touchUpInside)
    self.view.addSubview(btnJoinLeave)
    
    etRecipient = UITextField(frame: CGRect(x: 100, y: 150, width: 300, height: 30))
    etRecipient.placeholder = "Enter recipient user ID"
    self.view.addSubview(etRecipient)
    
    scrollView = UITextView(frame: CGRect(x: 130, y: 200, width: 300, height: 100))
    scrollView.isEditable = false
    self.view.addSubview(scrollView)
    
    etMessageText = UITextField(frame: CGRect(x: 80, y: 320, width: 200, height: 30))
    etMessageText.placeholder = "Message"
    self.view.addSubview(etMessageText)
    
    btnSendMessage = UIButton(type: .system)
    btnSendMessage.frame = CGRect(x: 270, y: 320, width: 80, height: 30)
    btnSendMessage.setTitle(">>", for: .normal)
    btnSendMessage.addTarget(self, action: #selector(sendMessage), for: .touchUpInside)
    self.view.addSubview(btnSendMessage)

Handle the system logic

Import the necessary classes, and add a method to show status updates to the user.

  1. Import the Chat SDK class

    In ViewController, add the provided code sample after import UIKit:

    import AgoraChat

If Xcode does not recognize this import, click File > Packages > Reset Package Caches.

  1. Log events and show status updates to your users

    In ViewController, add the following method after the viewDidLoad function:

    func showLog(_ text: String) -> Void {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: "", message: text, preferredStyle: .alert)
            self.present(alert, animated: true)
            alert.dismiss(animated: true, completion: nil)
        }
    }

Send and receive messages

When a user opens the app, you instantiate and initialize a ChatClient. When the user taps the Join button, the app logs in to the Chat. When a user types a message in the text box and then presses Send, the typed message is sent to the Chat. When the app receives a message from the server, the message is displayed in the message list. This simple workflow enables you to rapidly build a Chat client with basic functionality.

To implement this workflow in your app, take the following steps:

  1. Declare variables

    In the ViewController class, add the following declarations at the top:

    var userId = "<User ID of the local user>"
    var token = "<Your authentication token>"
    var appId = "<App ID from Agora console>"
    
    var agoraChatClient: AgoraChatClient!
    var isJoined: Bool = false
  2. Set up Chat when the app starts

    When the app starts, you create an instance of the AgoraChatClient. To do this, add the following to viewDidLoad:

    setupChatClient()  // Initialize the ChatClient
  3. Instantiate the AgoraChatClient

    To implement peer-to-peer messaging, you use Chat SDK to initialize an AgoraChatClient instance. In the ViewController class, add the following method after the viewDidLoad function:

    func setupChatClient() {
        if (appId.isEmpty) {
            showLog("You need to set your App ID")
            return
        }
        let options = AgoraChatOptions(appId: appId)  // Create AgoraChatOptions with your App ID
        agoraChatClient = AgoraChatClient.shared()
        options.enableConsoleLog = true  // Enable printing logs on console
        agoraChatClient.initializeSDK(with: options)  // Initialize the AgoraChatClient
        agoraChatClient.chatManager?.add(self, delegateQueue: nil)  // Adds the chat delegate to receive messages
    }
  4. Handle and respond to Chat events

    The AgoraChatClientDelegate implements callbacks to receive notification of Chat events such as a connection state change, and a token expiration. The AgoraChatManagerDelegate implements a callback to handle the receival of messages. When you receive the messagesDidReceive notification, you display the message to the user.

    To handle these events, add the following extensions to the ViewController:

    // Add message event callbacks
    extension ViewController: AgoraChatManagerDelegate {
        func messagesDidReceive(_ aMessages: [AgoraChatMessage]) {
            for message in aMessages {
                let msgBody = message.body as! AgoraChatTextMessageBody
    
                DispatchQueue.main.async {
                    self.displayMessage(messageText: msgBody.text, isSentMessage: false)
                }
    
                showLog("Received a message from \(message.from)")
            }
        }
    }
    
    // Add connection event callbacks
    extension ViewController: AgoraChatClientDelegate {
        func connectionStateDidChange(_ aConnectionState: AgoraChatConnectionState) {
            if aConnectionState == .connected {
                showLog("Connected to the chat server.")
            } else {
                if isJoined {
                    showLog("Disconnected from the chat server.")
                    isJoined = false
                }
            }
        }
    
        func tokenWillExpire(_ aErrorCode: AgoraChatErrorCode) {
            showLog("Token will expire (log in using new token)")
        }
    
        func tokenDidExpire(_ aErrorCode: AgoraChatErrorCode) {
            showLog("Token expired (log in using new token)")
        }
    }
  5. Log in to the Chat

    When a user presses Join, your app logs in to the Chat. When a user presses Leave, the app logs out of the Chat.

    To implement this logic, put the following method to the ViewController:

    @objc func joinLeave() {
        if (isJoined) {
            let result: AgoraChatError? = agoraChatClient.logout(true)
            guard result == nil else {
                showLog(result!.errorDescription)
                return
            }
    
            showLog("Signed out")
            DispatchQueue.main.async {
                self.btnJoinLeave.setTitle("Join", for: .normal)
                self.isJoined = false
            }
        } else {
            let result: AgoraChatError? = agoraChatClient.login(withUsername: userId, token: token)
            guard result == nil else {
                if (result!.code.rawValue == 200) {  // Already joined
                    isJoined = true
                    showLog("Already signed in")
                    DispatchQueue.main.async {
                        self.btnJoinLeave.setTitle("Leave", for: .normal)
                    }
                } else {
                    showLog(result!.errorDescription)
                }
                return
            }
    
            showLog("Signed in")
            isJoined = true
    
            DispatchQueue.main.async {
                self.btnJoinLeave.setTitle("Leave", for: .normal)
            }
        }
    }
  6. Send a message

    To send a message to the Chat when a user presses the Send button, perform the following steps:

    1. Add the following method to the ViewController class before the viewDidLoad function:

        @objc func sendMessage() {
            // Read the recipient name from the EditText box
            let toSendName = etRecipient.text!.trimmingCharacters(in: .whitespaces)
            let content = etMessageText.text!.trimmingCharacters(in: .whitespaces)
      
            if (toSendName.isEmpty || content.isEmpty) {
                showLog("Enter a recipient name and a message.")
                return
            }
      
            // Create a ChatMessage
            let message = AgoraChatMessage(
                conversationID: toSendName,
                from: agoraChatClient.currentUsername!,
                to: toSendName,
                body: AgoraChatTextMessageBody(text: content),
                ext: nil
            )
      
            // Send the message
            agoraChatClient.chatManager?.send(message, progress: nil) { _, err in
                if let err = err {
                    self.showLog("Error occurred when sending the message. \(err.errorDescription)")
                } else {
                    self.showLog("Message sent successfully.")
                    DispatchQueue.main.async {
                        self.displayMessage(messageText: content, isSentMessage: true)
                        self.etMessageText.text = ""
                    }
                }
            }
        }
  7. Display chat messages

    To display the messages the current user has sent and received in your app, add the following method to the ViewController class:

    func displayMessage(messageText: String, isSentMessage: Bool) {
        DispatchQueue.main.async {
            self.scrollView.text.append(
                DateFormatter.localizedString(from: Date.now, dateStyle: .none, timeStyle: .medium)
                + ":  " + String(reflecting: messageText) + "\r\n"
            )
            self.scrollView.scrollRangeToVisible(NSRange(location: self.scrollView.text.count, length: 1))
        }
    }

Test your implementation

To ensure that you have implemented Peer-to-Peer Messaging in your app:

  1. Create an app instance for the first user:

    1. Register a user in Agora Console and Generate a user token.

    2. In the ViewController class, update userId, token, and appId with values from Agora Console. To get your App ID, see Get Chat project information.

    3. Connect a physical device to your development device.

    4. In Xcode, click Run app. A moment later you see the project installed on your device.

  2. Create an app instance for the second user:

    1. Register a second user in Agora Console and generate a user token.

    2. In the ViewController class, update userId and token with values for the second user. Make sure you use the same appId as for the first user.

    3. Run the modified app on a device emulator or a second physical device.

  3. On each device, click Join to log in to the Chat.

  4. Edit the recipient name on each device to show the user ID of the user logged in to the other device.

  5. Type a message in the Message box of either device and press >>.

    The message is sent and appears on the other device.

  6. Press Leave to log out of the Chat.

Reference

This section contains content that completes the information in this page, or points you to documentation that explains other aspects to this product.

Integrate the SDK through CocoaPods

  1. Install CocoaPods. For details, see Getting Started with CocoaPods.

  2. In the Terminal, navigate to the project root directory and run the pod init command to create a text file Podfile in the project folder.

  3. Open the Podfile file and add the Agora Chat SDK. Remember to replace Your project target with the target name of your project.

    platform :ios, '11.0'
    
    target 'Your project target' do
        pod 'Agora_Chat_iOS'
    end
  4. In the project root directory, run the following command to integrate the SDK:

    pod install

    When the SDK is installed successfully, you can see Pod installation complete! in the Terminal and an xcworkspace file in the project folder.

  5. Open the xcworkspace file in Xcode.

Add a privacy manifest file

The Agora Chat SDK for device provides the PrivacyInfo.xcprivacy file that contains the required reasons for the APIs used by the SDK. To add the privacy manifest to your app in Xcode, follow these steps:

  1. Create a privacy manifest in your app project:

    1. Choose File > New File.

    2. Scroll down to the Resource section and select App Privacy File type.

    3. Click Next.

    4. Check your app in the Targets list.

    5. Click Create.

    The default file name is PrivacyInfo.xcprivacy which is also the required file name for bundled privacy manifests.

  2. Add the items in PrivacyInfo.xcprivacy file of the Agora Chat SDK to PrivacyInfo.xcprivacy of the app in either of the following ways:

    • Add the following source code:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
          <key>NSPrivacyAccessedAPITypes</key>
          <array>
              <dict>
                  <key>NSPrivacyAccessedAPITypeReasons</key>
                  <array>
                      <string>CA92.1</string>
                  </array>
                  <key>NSPrivacyAccessedAPIType</key>
                  <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
              </dict>
              <dict>
                  <key>NSPrivacyAccessedAPITypeReasons</key>
                  <array>
                      <string>C617.1</string>
                  </array>
                  <key>NSPrivacyAccessedAPIType</key>
                  <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
              </dict>
          </array>
          <key>NSPrivacyCollectedDataTypes</key>
          <array/>
          <key>NSPrivacyTrackingDomains</key>
          <array/>
          <key>NSPrivacyTracking</key>
          <false/>
      </dict>
      </plist>
    • Add the list of items as shown in the following figure:

Frequently asked questions

API reference

Next steps

In a production environment, best practice is to deploy your own token server. Users retrieve a token from the token server to log in to Chat. To see how to implement a server that generates and serves tokens on request, see Secure authentication with tokens.