-
Notifications
You must be signed in to change notification settings - Fork 21
In‐app chat
Find more info about Live chat product on Infobip docs.
- Prerequisites
- Example application
- Display In-app chat view
- Customer's Chat History
- Authenticated chat
- Customize In-app chat view
- Sending attachments
- Unread chat push messages counter
- Changing localization
- Sending Contextual Data
- Multiple chat threads
- Handle notification taps
- Library events
InAppChat is the mobile component for connecting and interacting with Infobip's LiveChat product. Built on top of Mobile Messaging SDK, InAppChat requires from you a careful setup, both in your mobile app and in Infobip's portal. The following steps must be prepared in order to ensure the chat communication:
Step 1:
You must include and setup the Mobile Messaging SDK in your application. If you haven't already, please follow its quick start guide carefully. Only by being able to receive a pushRegistrationId
in your device (it is a good idea to enable and check the console debug logs for its response), you'll be able to successfully connect to InAppChat in the next steps.
Step 2:
You need to create a LiveChat Widget, and assign to it the exact same mobile push profile you defined in Step1. Because Mobile Messaging uses different Push Certificates for sandbox (debug) and production (testflight/app store), InAppChat also has this distinction. Make sure to follow the correct setup: a sandbox certificates will work while debugging the SDK/InAppchat, while a production one needs to be use for the Apple Store.
Step 3:
Now you can add InAppChat as a dependency into your iOS app, just by adding the following line in your Podfile
:
pod 'MobileMessaging/InAppChat'
and indicating you want to use it by adding withInAppChat()
to the MobileMessaging initialization chain:
MobileMessaging
.withApplicationCode(<# your application code #>, notificationType: <# your notifications types preferences #>)?
.withInAppChat() // this line prepares In-app chat service to start
.start()
Mobile Messaging In-app chat SDK provides a built-in chat view which you can quickly embed into your own application. Key component to use is MMChatViewController
.
We support two ways of using it:
- via Interface Builder: set "MMChatViewController" as
Custom class
name for your view controller object. - programmatically: by presenting the appropriate chat view controller instance from an arbitrary parent view controller, for example:
If you want it to be with top bar, it will have dismiss(x) button:
if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
let chatVC = MMChatViewController.makeRootNavigationViewController()
rootVC.present(chatVC, animated: true)
}
or, if you have navigation controller, you can push chat view controller to it, navigation bar will have back button.
let vc = MMChatViewController.makeChildNavigationViewController()
navigationController?.pushViewController(vc, animated: true)
or, if you want view controller to be presented modally, it will be without top bar.
if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
let chatVC = MMChatViewController.makeModalViewController()
rootVC.present(chatVC, animated: true)
}
When your app is installed, it is assigned a set of ids for receiving push notifications and connecting to LiveChat. And also a "person" entity is created on Infobip side, automatically, and mostly empty, for that installation.
While having an anonymous customer/person fits some use cases, most likely you have an authenticated customer you can/want to identify (for example by his/her email, phone number, or some other unique id). Fortunately, you can use the Personalize feature of Mobile messaging to not only to link your customer to your app installation, but also for recovering the chat history of that customer.
Once your app has received the push registration, personalize your customer and, next time the chat is shown, previously sent messages will be presented, recovering the open conversation.
There is also option to depersonalize, that reverts the customer to its original, anonymous state, emptying the chat history. This is a common/suggested practice in log-out flows.
InAppChat offer three levels of customisation, all of them optional, each level allowing more freedom (thus being more complex as result).
The first level is defined as "General Chat Settings", and consist of values that are shared with the chat web widget, but also can be modified in runtime through code. The way to access this general chat settings, and customising the basics of the chat appearance, is through the instance: MMChatSettings.settings
, and consists of the following variables:
-
title
(String) - title for navigation bar when using NavigationViewController -
sendButtonTintColor
(UIColor) - tint color for Send button -
navBarItemsTintColor
(UIColor) - tint color of navigation bar items when using NavigationViewController -
navBarColor
(UIColor) - color of navigation bar when using NavigationViewController -
navBarTitleColor
(UIColor) - color of title of navigation bar when using NavigationViewController
The second level is defined as "Advanced Chat Settings". It allows you to modify anything from our UI classes, with the implication of extra effort in terms of testing and design in your end. You can access the long list of exposed variables through the instance MMChatSettings.settings.advancedSettings
, which includes all fonts, icons, frames and colours our chat compose bar uses. In the ChatExample project, included within the SDK, you can see its capabilities (search for setCustomSettings)
The third level is defined as "Custom Chat Replacement". It allows you to completely exclude the compose bar we offer for interacting with the chat, and use your own input instead. The only requirements are, for your custom input view:
- to use our MMChatComposer protocol.
- to use the MMComposeBarDelegate methods to interact with the chat.
- and to inject your view in our chat view controller before it is loaded (for example, with the provided initialiser
MMChatViewController.makeCustomViewController(with: yourCustomInputView)
).
In the ChatExample project, included within the SDK, you can see its capabilities (search for showReplacedChatInNavigation)
In a similar manner as you can customize in-app chat view (see section above), you can define your own settings/branding for dark mode. To achieve it, you must define your colors and other values within MMChatSettings.darkSettings
; it uses the same class as the regular settings explained previously.
Then, you can decide a theme, by assigning a value to MMChatSettings.colorTheme
, between three available option modes:
-
light
. This will use the values (default or assigned by you) inMMChatSetting.settings
. It is the default mode. -
dark
. This will use the values inMMChatSetting.darkSettings
. If darkSettings are undefined, it will use all colours oflight
mode, but inverted. -
auto
. This will decide based on the settings of the operating system - meaning, your end-user will decide which mode will be applied and when.
In the ChatExample project, included within the SDK, you can see how different settings are defined, and are dynamically applied, by searching for onChangeColorTheme and darkSettings.
Note: Dark mode feature is currently offered only on mobile.
You can retrieve the message details in such special scenario as user tapping on the notification alert/banner:
- Implement
MMMessageHandlingDelegate
protocol and it's methoddidPerform(action:forMessage:completion:)
:
class MyMessageHandlingDelegate : MMMessageHandlingDelegate {
func didPerform(action: MMNotificationAction, forMessage message: MM_MTMessage?, notificationUserInfo: [String: Any]?, completion: @escaping () -> Void) {
// this way you may distinguish chat message from regular flow/broadcast push message:
if message.isChatMessage {
print("Chat message with text: \(message.text) was tapped")
<# your custom handling here #>
}
// don't forget to call `completion`, it's very important to tell the system that action handling is finished
completion()
}
}
- Pass the delegate object to MobileMessaging SDK:
MobileMessaging.messageHandlindDelegate = MyMessageHandlingDelegate()
Mobile Messaging SDK supports MMNotificationInAppChatAvailabilityUpdated
event - Library-events, which is posted after the in-app chat availability status received from backend server. The userInfo dictionary contains the following key: MMNotificationKeyInAppChatEnabled - contains boolean value.
Starting from 8.1.0 SDK version, we added sending attachments feature. In order to be able to choose attachment, you application need to be able to open photo library to choose the file or use camera and microphone to capture photo and video. By the Apple policies you will need to add following keys with text descriptions to your App's Info.plist file:
- NSPhotoLibraryUsageDescription
- NSCameraUsageDescription
- NSMicrophoneUsageDescription
To enable document picker, you will need to turn on the iCloud Documents capabilities in Xcode.
Starting from 8.3.0 SDK version, we added attachments preview feature. Supported file types are Images, Videos and PDFs.
In order to be able to save attachment to photo library, by the Apple policies you will need to add following key with text description to your App's Info.plist file:
- NSPhotoLibraryAddUsageDescription
Media type | File size | File format |
---|---|---|
image | 10MB | JPG, JPEG, PNG |
audio | 10MB | M4A |
video | 10MB | MP4 |
document | 10MB |
Starting from version 9.2, new API is available to get and reset current unread chat push messages counter. The counter increments each time the application receives chat push message (this usually happens when chat screen is inactive or the application is in background/terminated state). In order to get current counter value use following API:
if let count = MobileMessaging.inAppChat?.getMessageCounter {
//use the count the way that suits you
}
MobileMessaging SDK automatically resets the counter to 0 whenever user opens the chat screen. However, use the following API in case you need to manually reset the counter:
MobileMessaging.inAppChat?.resetMessageCounter()
You can setup an MMInAppChatDelegate
in order to get updates of the counter in runtime, for example:
import MobileMessaging
class MyViewController: UIViewController, MMInAppChatDelegate {
override func viewDidLoad() {
super.viewDidLoad()
MobileMessaging.inAppChat?.delegate = self
}
//...
func didUpdateUnreadMessagesCounter(_ count: Int) {
//use the count the way that suits you
}
}
The predefined messages prompted within the In-app chat (such as status updates, button titles, input field prompt) by default are localized using the system locale settings, but you can easily changed the language any time you need.
For example, before showing the chat view controller, you can provide your locale string, and it wil be used the next time chat is presented:
MobileMessaging.inAppChat?.setLanguage("es_ES")
MobileMessaging.inAppChat?.setLanguage("es-ES")
MobileMessaging.inAppChat?.setLanguage("es")
But if you have the chat presented and loaded, you can change the language directly into it in real time (using the predefined MMLanguage's values):
let vc = MMChatViewController.makeModalViewController()
// chat is presented, loaded, and you need to change its language
vc.setLanguage(.es) { error in
// if error is nil, all went as expected or chat is not presented yet
}
It is possible to send contextual data / metadata to Infobip’s Conversations via In-App Chat SDK. The data can be send any time, several times, with only one restriction: the chat must be already loaded and presented, and the communication should have started (meaning, there are messages visible and not the initial “Start the chat” button). The data sent will be automatically linked to the conversationId and accountId internally.
There are two parameters:
- The mandatory data, sent as string, in the format of Javascript objects and values (for guidance, it must be accepted by JSON.stringify())
- And optionally, a multithread strategy that can be left empty, and will use ACTIVE as default. Possible values are: metadata sent to "ACTIVE" conversation for the widget, or "ALL" non closed conversations for the widget.
Usage:
// Having created your MMChatViewController instance
let vc = MMChatViewController(type: .back)
// Present and wait till the chat is loaded and ready, then simply call
vc.sendContextualData("{name: 'Robert'}") { error in ... }
Default LiveChat widget (name of the channel InAppChat uses) works with single chat threads: one customer can only have one single open conversation. But the LiveChat widget could be created, in Customer Portal, with support for multiple chat threads.
When the setting above is enabled, the InAppChat UI will automatically offer in mobile:
- A list (initially empty) of all the unsolved conversation threads the user has opened.
- A button to "Start new chat" thread.
- The capability to navigate to each specific chat thread upon tapping in them.
The functionality for multiple chat threads works out of the box: there is no need for extra implementation in the mobile integrator's side. But there is something you may need to consider regarding navigation bar and the back button of the chat view controller:
The MMChatViewController, when multiple threads are in use, needs to take control over the back button to allow a return to the threads list. In other words: the chat view controller will replace the default back button and its logic. For this reason, it is recommended not to use InAppChat's multiple threads feature without a navigation bar (for example, when presented as modal view). Nevertheless, we allow to customise and intercept the actions of this new back button, if you need so, as seen in the code below:
// Optional definition of a custom back button (but we recommend leaving the default one to handle the navigation for you)
let vc = MMChatViewController.makeRootNavigationViewController()
vc.initialLeftNavigationItem = UIBarButtonItem(image:style:target:action)
It is possible to authenticate an user before accesing the chat, given you have enabled this feature in the LiveChat widget. The authentication is accomplished by combining the SDK's Personalisation method with a JWT (JSON Web Token); a token that needs to be generated by your end (see instructions here). We recommend, due to the token expiration, that a new token is always generated and injected in the SDK before presenting the chat, each and every time.
The authentication will use a unique identifier for your user, that can be an email address, a phone number, or an external identifier. It is crucial for this identifier to be valid, and to match the identity defined in the Personalisation - there will be an authentication error otherwise.
The ChatExample provided within the Mobile Messaging SDK offers a functional interface for testing the authentication use case (you just need to set your own Ids, keys and secret keys for it to work). A simplified use would be as follows:
/*
1 - The customer authenticate in your system, and you recognise his/her unique identifier
2 - You call Personalise with this unique identifier (and optionally, with other attributes such as first name, second name, etc)
3 - Now you can display the chat as an authenticated user by doing the following:
*/
MobileMessaging.inAppChat?.jwt = jwt // freshly new generated token. See documentation linked above and/or ChatExample demo for more details
let vc = MMChatViewController.makeModalViewController() // Or your preferred presentation method/style. The chat will read the JWT automatically.
self.navigationController?.present(vc, animated: true, completion: nil)
If you have any questions or suggestions, feel free to send an email to support@infobip.com or create an issue.
- Library events
- Server errors
- Users and installations
- Messages and notifications management
- Inbox
- Geofencing service
- Privacy settings
- In-app chat
- WebRTC Calls and UI