iOS Integration Guidelines for Agentforce Mobile SDK
This guide provides the steps to integrate the Agentforce Mobile SDK with your native iOS application.
iOS: Version 17.0 or later
Xcode: Version 16.0 or later
Swift: Version 5.0 or later
An existing iOS project configured with CocoaPods.
Install Dependencies
To integrate the SDK into your project, you'll need to manage a set of dependencies through Cocoapods.
Using CocoaPods
Add the following lines to your project's Podfile. The Agentforce SDK podspec will pull in additional dependencies as needed.
At the top of your Podfile, add the Salesforce Mobile iOS Spec Repo above the CocoaPods trunk repo. Make sure to add the CocoaPods CDN if you use any other CocoaPods dependencies.
At the bottom of your podfile where you set up your post installer, configure it as shown:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
After adding the pods, run pod install from your project's root directory. If CocoaPods is unable to locate the specs, try pod install --repo-update.
Dependencies
The AgentforceSDK includes the following key dependencies:
SalesforceNetwork: An interface for consuming applications to provide a networking layer to Agentforce Mobile SDK.
SalesforceNavigation: An interface for consuming applications to handle navigation events occurring within Agentforce Mobile SDK views.
SalesforceUser: A designated way to provide user information to Agentforce Mobile SDK.
SalesforceLogging: An interface for consuming applications to handle logging from within Agentforce Mobile SDK.
Swift-Markdown-UI: A rendering library for GitHub Flavored Markdown.
Implement Core Service Protocols
The Agentforce Mobile SDK is designed for flexibility and delegates several core responsibilities to the host application. This is achieved through a set of protocols that your application must implement. This approach allows the SDK to remain lean and lets you use your existing application architecture for handling common tasks.
You will need to create concrete implementations for the following:
AgentforceSDK Interfaces:
AgentforceAuthCredentialProviding: Supplies the SDK with the authentication token (e.g., OAuth 2.0 access token) required to communicate securely with Salesforce APIs.
AgentforceInstrumentation: A handler for the SDK to emit instrumentation and telemetry data into your app's analytics system.
SalesforceNetwork.Network: Provides the SDK with the ability to make authenticated network calls to Salesforce. Your implementation will handle the underlying networking logic, leveraging your app's existing network stack, and will be responsible for attaching the necessary authentication tokens to each request.
SalesforceNavigation.Navigation: Handles navigation requests from the agent. For example, if the agent provides a link to a specific record, this interface allows your app to intercept that request and navigate the user to the appropriate screen within your native application.
SalesforceLogging.Logger: Allows the SDK to pipe its internal logs into your application's logging system for easier debugging and monitoring.
By implementing these interfaces, you provide the "scaffolding" that the Agentforce SDK builds upon, ensuring seamless integration with your app's existing ecosystem.
Example AgentforceAuthCredentialProviding Swift Implementation:
importFoundationimportAgentforceSDK// An example implementation that retrieves auth details from a hypothetical SessionManager.classMyAppCredentialProvider:AgentforceAuthCredentialProviding{publicfuncgetAuthCredentials()->AgentforceAuthCredential{// If using OAuthreturn.OAuth(authToken:getCurentAuthToken(), orgId: orgId, userId: userId)// If using OrgJWTsreturn.OrgJWT(orgJWT:getOrgJWT())}}
Create an AgentforceConfiguration Instance
The AgentforceConfiguration struct is used to configure the Agentforce SDK. It takes the following parameters:
agentId: The unique identifier for your agent
orgId: Your Salesforce organization ID
forceConfigEndpoint: The URL of your Salesforce instance
For more advanced configurations, you can also provide implementations for the following protocols:
dataProvider: Provide custom data to the agent
imageProvider: Provide custom images to the UI
agentforceCopier: Handle copy to clipboard functionality
ttsVoiceProvider: Provide a custom text-to-speech engine
speechRecognizer: Provide a custom speech-to-text engine
Here's an example of an AgentforceConfiguration instance:
importAgentforceSDKlet agentforceConfiguration =AgentforceConfiguration(
agentId:"YOUR_AGENT_ID",// Replace with your Agent ID
orgId:"YOUR_ORG_ID",// Replace with your Salesforce Org ID
forceConfigEndpoint:"YOUR_INSTANCE_URL"// e.g. "https://your-domain.my.salesforce.com")
Initialize the SDK and Build the View
You can initialize the SDK in one of two ways, depending on whether you want to use the pre-built UI or a headless implementation.
Option A: Full UI Experience
This approach is best if you want a complete, out-of-the-box chat interface. The AgentforceClient manages the session and provides a SwiftUI View that you can present in your app.
Instantiate AgentforceClient
Create and retain an instance of AgentforceClient. You will pass in your config object and your implementations of the core service protocols.
importAgentforceSDKclassAgentforceManager:ObservableObject{let agentforceClient:AgentforceClientinit(){// Initialize with your config and protocol implementationslet config =AgentforceConfiguration(...)let credentialProvider =MyAppCredentialProvider(...)let networkProvider =MyAppNetworkProvider(...)let contextProvider =MyAppContextProvider(...)self.agentforceClient =AgentforceClient(
credentialProvider: credentialProvider,
agentforceConfiguration: config,
contextProvider: contextProvider,
network: networkProvider
)}}
The AgentforceClient must be retained for the duration of the conversation. If it is deallocated, the session will be lost. Instantiate it in an object with an appropriate lifecycle for your needs.
Note
Starting a Conversation
Once you have initialized the AgentforceClient, you can start a conversation with an agent using the startAgentforceConversation method.
let conversation = agentforceClient.startAgentforceConversation(forAgentId:"YOUR_AGENT_ID")
This method returns an AgentConversation object, which represents a single conversation with an agent.
Displaying the Chat UI
To display the chat UI, you can use the createAgentforceChatView method. This method returns a SwiftUI view that you can present to the user.
do{let chatView =try agentforceClient.createAgentforceChatView(
conversation: conversation,
delegate:self,
onContainerClose:{// Handle chat view close})// Present the chatView in your SwiftUI hierarchy}catch{// Handle error}
The createAgentforceChatView method takes the following parameters:
conversation: The AgentConversation object that you created earlier
delegate: An object that conforms to the AgentforceUIDelegate protocol. This delegate will receive notifications about UI events
onContainerClose: A closure that will be called when the user closes the chat view
Basic Use Cases
This section covers the basic use cases for integrating the Agentforce Mobile SDK with your iOS app.
Send Messages
To send a message to the agent, you can use the sendUtterance method on the AgentConversation object.
To receive messages from the agent, you can subscribe to the messages publisher on the AgentConversation object.
conversation.messages
.sink { messages in// Handle new messages}.store(in:&cancellables)
Handle UI Events
To handle UI events, you can implement the AgentforceUIDelegate protocol. This protocol has the following methods:
modifyUtteranceBeforeSending(_:): This method is called before an utterance is sent to the agent. It allows you to modify the utterance before it is sent.
didSendUtterance(_:): This method is called after an utterance has been sent to the agent.
userDidSwitchAgents(newConversation:): This method is called when the user switches to a different agent.
extensionYourViewController:AgentforceUIDelegate{funcmodifyUtteranceBeforeSending(_ utterance:AgentforceUtterance)async->AgentforceUtterance{// Modify the utterance if neededreturn utterance
}funcdidSendUtterance(_ utterance:AgentforceUtterance){// Handle sent utterance}funcuserDidSwitchAgents(newConversation:AgentConversation){// Handle agent switch}}
Option B: Headless Integration
This approach is for developers who want to build a completely custom UI or run agent interactions in the background. The AgentforceService handles the communication and state, emitting events that your app uses to update its own UI. For more details, see the AgentforceMobileService-iOS repo.
Advanced Topics
This section covers advanced configuration and customization options for the Agentforce Mobile SDK.
Custom View Providers
The AgentforceViewProviding protocol allows you to provide your own custom views for the different components that are displayed in the chat interface. This is useful if you want to replace the default implementation of a component with your own.
To provide your own views, you must create a class that conforms to the AgentforceViewProviding protocol and implement the following methods:
canHandle(type:): This method should return true if you want to provide a custom view for the given component type, and false otherwise.
view(for:data:): This method should return your custom view for the given component type. The data parameter contains the properties for the component.
Here is an example of how you can provide a custom view for the AF_RICH_TEXT component:
importAgentforceSDKimportSwiftUIclassCustomViewProvider:AgentforceViewProviding{funccanHandle(type:String)->Bool{return type =="AF_RICH_TEXT"}@MainActorfuncview(for type:String, data:[String:Any])->AnyView{if type =="AF_RICH_TEXT"{let value = data["value"]as?String??""returnAnyView(Text(value).font(.custom("YourFont", size:16)))}returnAnyView(EmptyView())}}
Once you have created your custom view provider, you can pass it to the AgentforceClient when you initialize it:
let agentforceClient =AgentforceClient(
credentialProvider: yourCredentialProvider,
agentforceConfiguration: agentforceConfiguration,
viewProvider:CustomViewProvider())
Instrumentation
The Agentforce SDK provides a detailed instrumentation framework for monitoring performance and usage. To receive instrumentation events, you can provide an implementation of the AgentforceInstrumentationHandling protocol in your AgentforceConfiguration.
classMyInstrumentationHandler:AgentforceInstrumentationHandling{funcrecordEvent(_ event:AgentforceInstrumentationEvent){// Handle instrumentation eventsprint("Instrumentation event: \(event)")}}// Include in your configlet agentforceConfiguration =AgentforceConfiguration(
agentId:"YOUR_AGENT_ID",
orgId:"YOUR_ORG_ID",
forceConfigEndpoint:"YOUR_INSTANCE_URL",
instrumentationHandler:MyInstrumentationHandler())