Live Chat

This guide is a high level overview of the Airship Live Chat feature for iOS devices.

Installation

In order to use Airship Live Chat, please contact your account manager or Airship Support. They will provision your account and provide the chat URLs for the config.

Add the chat module

AirshipChat is a modular framework called AirshipChat. If you are using CocoaPods add the subspec Airship/Chat.

Importing the module

For CocoaPods, import using:

import Airship
@import Airship;

For everything else, use:

import AirshipChat
@import AirshipChat;

Configure the URLs

The app needs to configure the chatURL and chatWebSocketURL in the UAConfig options.

  <?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>chatURL</key>
    <string>CHAT_URL</string>
    <key>chatWebSocketURL</key>
    <string>CHAT_WEB_SOCKET_URL</string>
    ...
  </dict>

Displaying chat

The AirshipChat module provides an activity that can be displayed by calling openChat on the Chat instance:

  Chat.shared().openChat()
  [[UAirshipChat shared] openChatWithMessage:nil];

Optionally, you can specify the draft message and or title when opening chat:

  Chat.shared().openChat(message: "message draft")
  [[UAirshipChat shared] openChatWithMessage:@"message draft"];

Styling the UI

To style the default UI, you can create an instance of a ChatStyle with any style overrides:

  var chatStyle  = ChatStyle()
  chatStyle.title = "Live Chat"
  chatStyle.backgroundColor = UIColor.blackColor
  UAChatStyle *chatStyle = [[UAChatStyle alloc] init];
  chatStyle.title = @"Live Chat";
  chatStyle.backgroundColor = [UIColor blackColor];
  ...

Then apply the style:

  Chat.shared().chatStyle = chatStyle
  [UAirshipChat shared].chatStyle = chatStyle;

Alternatively, you can define the style in a plist file named AirshipChatStyle.plist and define the properties of the style class. The style will automatically be applied to the out of the box UI.

<?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>backgroundColor</key>
	<string>#cccccc</string>
	<key>titleColor</key>
	<string>#FF0000</string>
	<key>title</key>
	<string>My Chat</string>
	<key>tintColor</key>
	<string>#004BFF</string>
	<key>titleFont</key>
	<dict>
		<key>fontName</key>
		<string>AmericanTypewriter</string>
		<key>fontSize</key>
		<string>19</string>
	</dict>

  ...

</dict>
</plist>

Custom UI

If the provided activity does not work for your application, you can either embed the ChatViewController directly into your application, or you can provide your own UI.

Embedding the ChatViewController

When embedding the ChatViewController you can pass message draft and style arguments before the view is loaded:

  let viewController = ChatViewController.init(nibName: "UAChatViewController", bundle: ChatResources.bundle())
  viewController.messageDraft = "message draft"
  viewController.chatStyle = chatStyle
  UAChatViewController *viewController = [[UAChatViewController alloc] initWithNibName:@"UAChatViewController" bundle:[UAChatResources bundle]];
  viewController.messageDraft = @"message draft";
  viewController.chatStyle = chatStyle;

Build your own

If the ChatViewController is insufficient for your app, you can build your own by accessing the Conversation directly:

  let conversation = Chat.shared().conversation
  id<UAConversationProtocol> conversation = [Chat shared].conversation;

You can access the last 50 messages with fetchMessages.

  conversation.fetchMessages(completionHandler: { (messages) in
    // messages fetched
  })
  [conversation fetchMessagesWithCompletionHandler:^(NSArray<UAChatMessage *> *messages) {
    // messages fetched
  }];

To listen when messages are updated, set a ConversationDelegate on the Conversation:

  conversation.delegate = conversationDelegate
    public func onConnectionStatusChanged() {
      // connection status changed
    }

    public func onMessagesUpdated() {
      // messaged updated
    }
  conversation.delegate = conversationDelegate;
  - (void)onConnectionStatusChanged {
    // connection status changed
  }

  - (void)onMessagesUpdated {
    // messaged updated
  }

To send a new message, call sendMessage on the Conversation:

  conversation.sendMessage("some text")
  [conversation sendMessage:@"some text"];

Override openChat behavior

If you provide your own UI or embed the fragment directly, you need to set a delegate on the openChat behavior to navigate to your custom UI. Set the listener during takeOff.

  Chat.shared().openChatDelegate = openChatDelegate
    public func openChat(message: String?) {
      // navigate to custom UI
    }
  [UAirshipChat shared].openChatDelegate = openChatDelegate;
  - (void)openChatWithMessage:(NSString * _Nullable)message {
    // navigate to custom ui
  }

Deep linking

Optionally, setup a deep link that navigates directly to chat. The deep link just needs to call through to Chat.shared().openChat().

  func openDeepLink(_ deepLink: String) {
      if (deepLink == "my-app://deeplink/chat") {
        Chat.shared().openChat()
      }
      ...
  }
  - (void)openDeepLink:(NSString *)deepLink {
      if ([deepLink isEqualToString:@"my-app://deeplink/chat"]) {
        [[UAirshipChat shared] openChat];
      }
      ...
  }