Build a Core SDK App for iOS
The Core SDK allows you to call all the necessary In-App Messaging APIs directly from your app. With the Core SDK, you’re in full control over the entire user experience—you tell the API when to send a message and the API tells you when a message is received.
This article applies to the following implementations:
| UI SDK | Core SDK |
|---|---|
| ✅ |
If you want to use our ready-made user interface and user experience, use the UI SDK instead.
Import the Framework
Import the framework wherever you’re using the SDK.
1import SMIClientCoreCreate a Configuration
Create a Configuration instance. To create a configuration instance, you can point to the config file you previously downloaded from your org, or you can manually add the values from within this config file.
OPTION 1: Configure Using the Config File
Once you’ve added the config.json file to your project, you can reference it from the code.
1guard let configPath = Bundle.main.path(forResource: "configFile",
2 ofType: "json") else {
3 // TO DO: Handle error
4 return
5}
6
7let configURL = URL(fileURLWithPath: configPath)
8let config = Configuration(url: configURL)To learn how to download the config file from your org, see Configure an Enhanced In-App Chat Deployment in Salesforce Help. This file contains the Service API URL, the org ID, and the API name for the deployment. For example:
1{
2 "OrganizationId": "00ZZZ0000000Zzz",
3 "DeveloperName": "MyMessagingForInAppDeployment",
4 "Url": "https://zzzz.my.api.url.salesforce-scrt.com"
5}Note
OPTION 2: Configure Manually with Config Info
If you don’t want to use the config.json file in your project, you can configure the SDK manually using the Service API URL, the org ID, and the API name for the deployment.
1guard let serviceAPIURL = URL(string: "URL_TO_MY_SERVICE_API") else {
2 // TO DO: Handle error
3 return
4}
5
6let config = Configuration(serviceAPI: serviceAPIURL,
7 organizationId: "ORG_ID",
8 developerName: "API_NAME_OF_DEPLOYMENT")Get the Core Client Object
The CoreFactory class lets you create a CoreClient object.
1// Create core client
2let coreClient = CoreFactory.create(withConfig: config)Start the Core Instance
To receive messages and events, call CoreClient.start().
1// Start listening for events
2coreClient.start()Create a Conversation Client
The CoreClient object lets you create a ConversationClient object to start a conversation.
This example creates a random UUID for the conversation ID. However, if you want this conversation to persist even after the app is restarted, be sure to use the same conversation ID. Also, if you want to see this same conversation across multiple devices, in addition to using the same conversation ID, turn on user verification, which is described in the Enhance the Experience section.
Tip
Don’t use user IDs or other IDs as the ConversationID. Conversation IDs establish a permanent link with a user and are only available to the user who created it. Using a different existing ID instead of a unique ID can result in access issues or errors while developing or testing your Enhanced Chat integration. To pass existing IDs required for your flow, use the Pre-chat feature.
Note
1let conversationID = UUID()
2let conversationClient = coreClient.conversationClient(with: conversationID)Handle a Pre-Chat Form
In order to get the pre-chat fields before a conversation, call the retrieveRemoteConfiguration method from your CoreClient object. This method passes back an SMIRemoteConfigurationCompletion completion block that contains the array of pre-chat fields.
1var preChatFields: [PreChatField]?
2
3coreClient.retrieveRemoteConfiguration(completion: { remoteConfig, error in
4 preChatFields = remoteConfig?.preChatFields
5})Each pre-chat field has the properties necessary for you to build your pre-chat form. After you present a pre-chat form to the user, fill in the value field for each pre-chat object. Then submit the pre-chat fields using the submit(remoteConfig: ) method on the ConversationClient object.
IMPORTANT: The submit(preChatFields: ) method is deprecated in SDK version 1.4. If you want to use new features added in version 1.4 and later, submit pre-chat fields using the submit(remoteConfig: ) method.
Important
1coreClient.retrieveRemoteConfiguration(completion: { remoteConfig, error in
2 // Get the pre-chat fields from the remote config.
3 if let preChatFields = remoteConfig?.preChatConfiguration?.first?.preChatFields {
4 // Set the pre-chat values.
5 for field in preChatFields {
6 field.value = "Some value from user"
7 }
8
9 // You can choose to create the conversation when submitting
10 // pre-chat values, otherwise the conversation will be started
11 // after sending the first message.
12 self.conversationClient?.submit(remoteConfig: remoteConfig, createConversationOnSubmit: true)
13 }
14})To learn about hidden pre-chat fields, see Hidden Pre-Chat for iOS.
Send Messages
Send a message with the ConversationClient instance.
1conversationClient.send(message: "It worked!")If you see the Exception Failed (417) error on sending a message, it’s because you set the Pre-Chat Display Frequency to Every Session in the Pre-Chat Settings and a new session is being created. To fix this, call the submitRemoteConfiguration method on the ConversationClient object with your pre-chat values.
Note
Listen for Events
To listen for events (such as new incoming messages), implement a delegate.
Implement the CoreDelegate protocol to listen for general messaging events or implement the ConversationClientDelegate protocol to listen for messaging events related to a particular conversation. The conversation delegate (ConversationClientDelegate) gets all events for a specific conversation. The core delegate (CoreDelegate) gets events for every conversation. The core delegate also returns network connectivity events (didChangeNetworkStatus) and general error messages (didError).
When you receive conversation entries from various event methods, they’re delivered as ConversationEntry objects. In addition to the payload, you can inspect the format (for example, RichLink) and the type (for example, Message) when deciding how to process the message.
Tip
1/* Implement this delegate to listen to
2 ALL messaging events…
3*/
4class MyCoreDelegate : NSObject, CoreDelegate {
5
6 // Received incoming conversation entries
7 func core(_ core: CoreClient!,
8 conversation: Conversation!,
9 didReceiveEntries entries: [ConversationEntry]!,
10 paged: Bool) {
11 // TO DO: Handle event
12 }
13
14 // Message status has changed
15 func core(_ core: CoreClient!,
16 conversation: Conversation!,
17 didUpdateEntries entries: [ConversationEntry]!) {
18 // TO DO: Handle event
19 }
20
21 // Conversation was created
22 func core(_ core: CoreClient!,
23 didCreateConversation conversation: Conversation!) {
24 // TO DO: Handle event
25 }
26
27 // Received a started typing event
28 func core(_ core: CoreClient!,
29 didReceiveTypingStartedEvent event: ConversationEntry!) {
30 // TO DO: Handle event
31 }
32
33 // Received a stopped typing event
34 func core(_ core: CoreClient!,
35 didReceiveTypingStoppedEvent event: ConversationEntry!) {
36 // TO DO: Handle event
37 }
38
39 // Network status has changed
40 func core(_ core: CoreClient!,
41 didChangeNetworkState state: NetworkConnectivityState!) {
42 // TO DO: Handle event
43 }
44
45 // Received an error message
46 func core(_ core: CoreClient!, didError error: Error!) {
47 // TO DO: Handle an error condition!
48 }
49}1/* Implement this delegate to listen to events related
2 to a specific conversation…
3*/
4class MyConversationDelegate: NSObject, ConversationClientDelegate {
5
6 // Received conversation entries
7 func client(_ client: ConversationClient!,
8 didReceiveEntries entries: [ConversationEntry]!, paged: Bool) {
9 // TO DO: Handle event
10 }
11
12 // Entries changed status
13 func client(_ client: ConversationClient!,
14 didUpdateEntries entries: [ConversationEntry]!) {
15 // TO DO: Handle event
16 }
17
18 // Created a conversation
19 func client(_ client: ConversationClient!,
20 didCreateConversation conversation: Conversation!) {
21 // TO DO: Handle event
22 }
23
24 // Received a started typing event
25 func client(_ client: ConversationClient!,
26 didReceiveTypingStartedEvent event: ConversationEntry!) {
27 // TO DO: Handle event
28 }
29
30 // Received a stopped typing event
31 func client(_ client: ConversationClient!,
32 didReceiveTypingStoppedEvent event: ConversationEntry!) {
33 // TO DO: Handle event
34 }
35
36 // Conversation error
37 func client(_ client: ConversationClient!,
38 didError error: Error!) {
39 // TO DO: Handle event
40 }
41}Use the addDelegate method on the CoreClient instance to add a core delegate. Use the addDelegate method on the ConversationClient instance to add a conversation client delegate.
1// Add a core delegate
2let myCoreDelegate = MyCoreDelegate()
3coreClient.addDelegate(delegate: myCoreDelegate)
4
5// Add a conversation delegate
6let myConversationDelegate = MyConversationDelegate()
7conversationClient.addDelegate(delegate: myConversationDelegate)Handle Participant Roles
The Participant protocol has a role field of type ParticipantRole. Participant maps to the sender field of the ConversationEntry protocol.
| Participant Role Type | Description |
|---|---|
ParticipantRoleSystem | Set for ParticipantChangedOperation. The participant field on the ParticipantChangedOperation protocol represents the participant whose role is being updated. |
ParticipantRoleUser | Set for all conversation entries sent by a user. |
ParticipantRoleAgent | Set for all conversation entries sent by a rep. |
ParticipantRoleChatbot | Set for all conversation entries sent by a chatbot. |
ParticipantRoleRouter | Set for ParticipantChangedOperation. This role is ignored by the SDK UI experience. |
ParticipantRoleSupervisor | Set for ParticipantChangedOperation after a supervisor on a Salesforce org joins a conversation after the rep raises a flag seeking their input. This role is ignored by the SDK UI experience. |
Enhance the Experience
You can enhance your users’ experience by adding push notifications, passing information to Salesforce about a verified user, sending hidden pre-chat fields, adjusting chat button visibility based on business hours, and more.
For enhanced features, see Enhance the Experience for iOS.
For more details about the Core SDK, see the iOS Reference Documentation.
Sample App
For an example app, see the Core SDK example in GitHub.