Build your own UI

Learn how to build your own mobile Chat UI with the Kustomer Core SDK.

To build your own UI for Kustomer chat and the knowledge base, you can use the Kustomer Core SDK. The Core SDK gives you access to all the data, events, and methods available for our built-in UI.

The Kustomer Core SDK exposes APIs as provider interfaces that allow you to create your own UI and send information into Kustomer APIs.

This guide shows you how to use the Kustomer Core SDK to build your own mobile chat and knowledge base UI for iOS.

📘

Guide: Access the knowledge base 📙

Visit Access the Knowledge Base to learn how to work with the knowledge base with the Kustomer Core SDK.

📘

Guide: Work with conversational assistants 📙

Visit Work with conversational assistants (chatbots) to learn how to work with the conversational assistants with the Kustomer Core SDK.

Prerequisites

Before you get started, you'll need the following:

  • A valid API key with just the org.tracking role. See Requirements

  • Chat SDK installation. To learn more, see Installation.

Overview

To build your own UI with the Kustomer Core SDK, you will need to do the following:

  1. Configure Kustomer in your AppDelegate with options

  2. Access the `Kustomer.chatProvider' instance

  3. Implement listeners with KUSChatListener

Step 1: Configure Kustomer chat in your AppDelegate with options

First, configure Kustomer chat in your AppDelegate and pass in enableUI = false.

let options = KustomerOptions()
options.enableUI = false

Kustomer.configure(apiKey: apiKey, options: options)

Step 2: Access the `Kustomer.chatProvider' instance

After you configure Kustomer, create a reference to the Kustomer.chatProvider instance anywhere in your application.

You can call different methods of the Kustomer.chatProvider to receive events, create messages, and more. Also see the Provider callbacks section.

📘

Kustomer.chatProvider methods

Visit the Core API reference for a full list of provider methods.

let provider = Kustomer.chatProvider

//See the API Reference link on the left for a full list of methods
provider.addChatListener(foo)
provider.sendChatMessage(text: "Hello World", conversationId: "123") { result in
  switch result {
  case .success(let data):
    print("Message with id \(data.message.id) was sent to conversation \(data.conversation.id)")
  case .failure(let error):
    print("Error: \(error.errorDescription)")    
  }
}

Step 3: Implement listeners with KUSChatListener

After you create a Kustomer.chatProvider reference in your application, implement the KUSChatListener protocol in one of your classes. You can pass an instance of this class to the provider to take actions for events such as when users receive messages, conversations close, and more.

class MyListener: KUSChatListener {
   func onChatMessageReceived(conversationId: String,
                              chatMessage: KUSChatMessage) {
    print("New message in conversation \(conversationId): \(chatMessage.body)")
  }
  func onConversationCreated(conversationId: String,
                             conversation: KUSConversation) {
    print("A new conversation with id = \(conversationId) was created")
  }
}

let listener = MyListener()

let provider = Kustomer.chatProvider
provider.addChatListener(listener)

Get recent data

A list of conversations or messages for a given conversation ID can be fetched asynchronously.

We've included an example of how to fetch conversations and then fetch the messages for the first conversation.

provider.getConversations { result in
    guard case .success(let conversations) = result, 
        let firstConversationId = conversations.first?.id else {
        return
    }
    provider.getChatMessages(conversationId: firstConversationId) { result in
        if case .success(let messages) = result {
            // Use messages
        }
    }
}

To receive events in your chat listeners, you need to tell the Kustomer client to start up and go online.

Receive events in listeners

To receive events in chat listeners, use Kustomer.start() either before or after you attach listeners.

Kustomer.start()
Kustomer.shared.start({ result in
  switch result {
    case .success:
      print("started. you'll now get events.")
    case .failure(let error):
      print("could not start. try again later")
      print(error.localizedDescription)
  }
})

Stop events

You can stop Kustomer to block network events from listeners or prevent internet connection use.

Kustomer.stop()

Restart events

After you stop Kustomer, you can restart Kustomer at any time. Restart Kustomer to replay all chat listener events you missed while offline.

// At 11am:
Kustomer.stop()

// 10 minutes later, at 11:10am:
Kustomer.start()

// If you had any chat listeners at 11am, they will receive events that you missed from 11am to 11:10am

Automatic retry for events

Kustomer automatically stops when there are internet connection problems. The Core SDK uses an automatic retry scheme (similar to Alamofire), and Kustomer will not stop right away if the internet connection goes down.

You can attach a listener to receive notifications when Kustomer stops due to internet connection problems.

Provider callbacks

All ChatProvider provider methods have callbacks that let you know if the request was successful.

You can use ChatProvider to call methods that send data to the Kustomer platform (for example, send a new chat message).

Data only appears in the listeners and data cache after you successfully send data (for example, a new message or a request to close a conversation).

provider.sendChatMessage(text: "Hello World", conversationId: "123") { result in
  switch result {
  case .success(let data):
    print("Message with id \(data.message.id) was sent to conversation \(data.conversation.id)")
  case .failure(let error):
    print("Error: \(error.errorDescription)")    
  }
}

Suggested pattern

We've provided a suggested pattern that shows how to ensure the variable data always has every chat message for a specific conversation based on the conversation id.

In the code examples below, we use a conversation with a conversation id of 100.

import KustomerChat

class ChatDataSource: KUSChatListener {
  var provider: ChatProvider
  var data: [KUSChatMessage] = []
  let conversationID: String

  init(with conversationID: String) {
    self.conversationID = conversationID
    provider = Kustomer.chatProvider
    provider.getChatMessages(conversationId: conversationID, completion: { result in
      switch result {
      case .success(let messages):
        self.data = messages
      case .failure(let error):
        print("Error getting messages: \(error.localizedDescription) for Conversation \(conversationID)")
      }
    })
    provider.addChatListener(self)
    Kustomer.start()
  }

  func onChatMessageReceived(conversationId: String,
                                chatMessage: KUSChatMessage) {
    data.append(chatMessage)
  }
}

let options = KustomerOptions()
options.enableUI = false
Kustomer.configure(apiKey: "API Key", options: options)
let foo = ChatDataSource()

// now foo.data will always have the best available list of chat messages

📘

Authentication

If you are using Kustomer's Authentication it's recommended that you complete the authentication process BEFORE calling the Kustomer.start() method. This will ensure that the authenticated customer's historical messages are loaded when Kustomer.start() is called.