Integrate AI agents into your iOS app to provide intelligent conversational experiences with chat history, contextual responses, and seamless handoffs.
Prerequisites
Before implementing AI agents, ensure you have:
Overview
The AI Agent integration provides:
Intelligent Responses - Context-aware AI conversations
Chat History - Browse and resume previous AI sessions
Streaming Responses - Real-time message streaming
Custom Styling - Match your app’s design
Suggested Messages - Quick-start prompts for users
Basic Implementation
Create a simple AI chat screen:
import UIKit
import CometChatUIKitSwift
import CometChatSDK
class AIAgentChatViewController : UIViewController {
private var user: User ?
private var messageHeader: CometChatMessageHeader !
private var messageList: CometChatMessageList !
private var messageComposer: CometChatMessageComposer !
convenience init ( user : User) {
self . init ()
self . user = user
}
override func viewDidLoad () {
super . viewDidLoad ()
view. backgroundColor = . systemBackground
setupUI ()
}
private func setupUI () {
guard let user = user else { return }
// Message Header
messageHeader = CometChatMessageHeader ()
messageHeader. set ( user : user)
messageHeader. translatesAutoresizingMaskIntoConstraints = false
view. addSubview (messageHeader)
// Message List
messageList = CometChatMessageList ()
messageList. set ( user : user)
messageList. translatesAutoresizingMaskIntoConstraints = false
view. addSubview (messageList)
// Message Composer
messageComposer = CometChatMessageComposer ()
messageComposer. set ( user : user)
messageComposer. translatesAutoresizingMaskIntoConstraints = false
view. addSubview (messageComposer)
setupConstraints ()
}
private func setupConstraints () {
NSLayoutConstraint. activate ([
messageHeader. topAnchor . constraint ( equalTo : view. safeAreaLayoutGuide . topAnchor ),
messageHeader. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageHeader. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageHeader. heightAnchor . constraint ( equalToConstant : 60 ),
messageList. topAnchor . constraint ( equalTo : messageHeader. bottomAnchor ),
messageList. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageList. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageList. bottomAnchor . constraint ( equalTo : messageComposer. topAnchor ),
messageComposer. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageComposer. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageComposer. bottomAnchor . constraint ( equalTo : view. safeAreaLayoutGuide . bottomAnchor )
])
}
}
Production Implementation
Complete AI agent chat with history, navigation, and error handling:
import UIKit
import CometChatUIKitSwift
import CometChatSDK
class ProductionAIAgentViewController : UIViewController {
// MARK: - Properties
private var user: User ?
private var group: Group ?
private var parentMessage: BaseMessage ?
private var isHistoryMode: Bool = false
private var messageHeader: CometChatMessageHeader !
private var messageList: CometChatMessageList !
private var messageComposer: CometChatMessageComposer !
// MARK: - Initialization
convenience init ( user : User, parentMessage : BaseMessage ? = nil , isHistory : Bool = false ) {
self . init ()
self . user = user
self . parentMessage = parentMessage
self . isHistoryMode = isHistory
}
convenience init ( group : Group, parentMessage : BaseMessage ? = nil , isHistory : Bool = false ) {
self . init ()
self . group = group
self . parentMessage = parentMessage
self . isHistoryMode = isHistory
}
// MARK: - Lifecycle
override func viewDidLoad () {
super . viewDidLoad ()
view. backgroundColor = . systemBackground
setupMessageHeader ()
setupMessageList ()
setupMessageComposer ()
setupConstraints ()
}
// MARK: - Setup
private func setupMessageHeader () {
messageHeader = CometChatMessageHeader ()
messageHeader. translatesAutoresizingMaskIntoConstraints = false
if let user = user {
messageHeader. set ( user : user)
} else if let group = group {
messageHeader. set ( group : group)
}
// Back button handler
messageHeader. set ( onBack : { [ weak self ] in
self ? . navigationController ? . popViewController ( animated : true )
})
// Chat history button handler
messageHeader. onAiChatHistoryClicked = { [ weak self ] user in
self ? . openChatHistory ()
}
view. addSubview (messageHeader)
}
private func setupMessageList () {
messageList = CometChatMessageList ()
messageList. translatesAutoresizingMaskIntoConstraints = false
messageList. hideThreadView = true
if let user = user {
messageList. set ( user : user)
} else if let group = group {
messageList. set ( group : group)
}
// If resuming from history, set parent message
if let parentMessage = parentMessage {
messageList. set ( parentMessage : parentMessage)
}
view. addSubview (messageList)
}
private func setupMessageComposer () {
messageComposer = CometChatMessageComposer ()
messageComposer. translatesAutoresizingMaskIntoConstraints = false
if let user = user {
messageComposer. set ( user : user)
} else if let group = group {
messageComposer. set ( group : group)
}
// If resuming from history, set parent message
if let parentMessage = parentMessage {
messageComposer. set ( parentMessage : parentMessage)
}
view. addSubview (messageComposer)
}
private func setupConstraints () {
NSLayoutConstraint. activate ([
messageHeader. topAnchor . constraint ( equalTo : view. safeAreaLayoutGuide . topAnchor ),
messageHeader. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageHeader. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageHeader. heightAnchor . constraint ( equalToConstant : 60 ),
messageList. topAnchor . constraint ( equalTo : messageHeader. bottomAnchor ),
messageList. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageList. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageList. bottomAnchor . constraint ( equalTo : messageComposer. topAnchor ),
messageComposer. leadingAnchor . constraint ( equalTo : view. leadingAnchor ),
messageComposer. trailingAnchor . constraint ( equalTo : view. trailingAnchor ),
messageComposer. bottomAnchor . constraint ( equalTo : view. safeAreaLayoutGuide . bottomAnchor )
])
}
// MARK: - Chat History
private func openChatHistory () {
let chatHistoryVC = CometChatAIAssistanceChatHistory ()
if let user = user {
chatHistoryVC. set ( user : user)
} else if let group = group {
chatHistoryVC. set ( group : group)
}
// Handle new chat button
chatHistoryVC. onNewChatButtonClicked = { [ weak self ] user in
self ? . startNewChat ()
}
// Handle message selection to resume conversation
chatHistoryVC. onMessageClicked = { [ weak self ] message in
self ? . resumeConversation ( from : message)
}
// Handle close
chatHistoryVC. onClose = { [ weak self ] in
self ? . navigationController ? . popViewController ( animated : true )
}
navigationController ? . pushViewController (chatHistoryVC, animated : true )
}
private func startNewChat () {
let newChatVC: ProductionAIAgentViewController
if let user = user {
newChatVC = ProductionAIAgentViewController ( user : user)
} else if let group = group {
newChatVC = ProductionAIAgentViewController ( group : group)
} else {
return
}
navigationController ? . pushViewController (newChatVC, animated : true )
}
private func resumeConversation ( from message : BaseMessage) {
let resumeVC: ProductionAIAgentViewController
if let user = user {
resumeVC = ProductionAIAgentViewController ( user : user, parentMessage : message, isHistory : true )
} else if let group = group {
resumeVC = ProductionAIAgentViewController ( group : group, parentMessage : message, isHistory : true )
} else {
return
}
navigationController ? . pushViewController (resumeVC, animated : true )
}
}
Launching AI Agent Chat
Start an AI agent conversation from your app:
import UIKit
import CometChatUIKitSwift
import CometChatSDK
class ChatListViewController : UIViewController {
func openAIAgentChat ( agentUID : String ) {
// Fetch the AI agent user
CometChat. getUser ( UID : agentUID) { [ weak self ] user in
DispatchQueue. main . async {
// Check if user is an AI agent (role contains "agentic")
if user.role ? . lowercased (). contains ( "agentic" ) == true {
let aiChatVC = ProductionAIAgentViewController ( user : user)
self ? . navigationController ? . pushViewController (aiChatVC, animated : true )
} else {
// Regular user chat
let messages = CometChatMessages ()
messages. set ( user : user)
self ? . navigationController ? . pushViewController (messages, animated : true )
}
}
} onError : { error in
print ( "Error fetching user: \( error ? . errorDescription ?? "" ) " )
}
}
func detectAndOpenChat ( for user : User) {
// Detect if user is an AI agent
let isAIAgent = user. role ? . lowercased (). contains ( "agentic" ) == true
if isAIAgent {
let aiChatVC = ProductionAIAgentViewController ( user : user)
navigationController ? . pushViewController (aiChatVC, animated : true )
} else {
let messages = CometChatMessages ()
messages. set ( user : user)
navigationController ? . pushViewController (messages, animated : true )
}
}
}
Styling
By default, all mobile UI Kits inherit font size from the operating system’s accessibility settings. However, on iOS, developers have the option to override this behavior and set custom font sizes programmatically using the textFont property on style objects or by configuring CometChatTypography globally.
Customize the AI chat bubble appearance:
import UIKit
import CometChatUIKitSwift
class AIAgentStylingExample {
func applyGlobalStyles () {
// Configure AI bubble style
var aiBubbleStyle = AIAssistantBubbleStyle ()
aiBubbleStyle. backgroundColor = . clear
aiBubbleStyle. borderWidth = 1
aiBubbleStyle. borderColor = . systemBlue
aiBubbleStyle. textColor = . label
aiBubbleStyle. textFont = UIFont. systemFont ( ofSize : 14 )
aiBubbleStyle. cornerRadius = CometChatCornerStyle ( cornerRadius : 12 )
// Apply globally
CometChatAIAssistantBubble. style = aiBubbleStyle
}
func applyInstanceStyles () -> ProductionAIAgentViewController {
let aiChatVC = ProductionAIAgentViewController ( user : User ())
// Custom message list style
let messageListStyle = MessageListStyle ()
messageListStyle. backgroundColor = UIColor. systemBackground
// Custom composer style
let composerStyle = MessageComposerStyle ()
composerStyle. backgroundColor = UIColor. secondarySystemBackground
composerStyle. borderColor = UIColor. separator
composerStyle. borderWidth = 1
return aiChatVC
}
}
Style Properties
Property Description backgroundColorBubble background color borderWidthBubble border width borderColorBubble border color textColorMessage text color textFontMessage text font cornerRadiusBubble corner radius
Customization Options
Empty State View
Customize the view shown when there are no messages:
let emptyView = UIView ()
let label = UILabel ()
label. text = "Start a conversation with AI"
label. textAlignment = . center
label. textColor = . secondaryLabel
emptyView. addSubview (label)
messageList. set ( emptyStateView : emptyView)
Streaming Speed
Adjust how fast AI responses stream:
// Configure streaming speed (characters per second)
messageList. set ( streamingSpeed : 50 )
Suggested Messages
Provide quick-start prompts for users:
let suggestions = [
"What can you help me with?" ,
"Tell me about your capabilities" ,
"How do I get started?"
]
messageComposer. set ( suggestedMessages : suggestions)
Configure custom tools for the AI agent:
messageComposer. set ( aiAssistantTools : { message in
// Return custom tools based on context
return [
AITool ( name : "search" , description : "Search knowledge base" ),
AITool ( name : "calculate" , description : "Perform calculations" )
]
})
Chat History Component
The CometChatAIAssistanceChatHistory component displays previous AI conversations:
import UIKit
import CometChatUIKitSwift
import CometChatSDK
class ChatHistoryViewController : UIViewController {
private var user: User ?
convenience init ( user : User) {
self . init ()
self . user = user
}
override func viewDidLoad () {
super . viewDidLoad ()
setupChatHistory ()
}
private func setupChatHistory () {
guard let user = user else { return }
let chatHistory = CometChatAIAssistanceChatHistory ()
chatHistory. set ( user : user)
// New chat button
chatHistory. onNewChatButtonClicked = { [ weak self ] user in
let newChat = ProductionAIAgentViewController ( user : user)
self ? . navigationController ? . pushViewController (newChat, animated : true )
}
// Resume conversation
chatHistory. onMessageClicked = { [ weak self ] message in
let resumeChat = ProductionAIAgentViewController (
user : user,
parentMessage : message,
isHistory : true
)
self ? . navigationController ? . pushViewController (resumeChat, animated : true )
}
// Close handler
chatHistory. onClose = { [ weak self ] in
self ? . dismiss ( animated : true )
}
addChild (chatHistory)
view. addSubview (chatHistory. view )
chatHistory. view . frame = view. bounds
chatHistory. didMove ( toParent : self )
}
}
Implementation Flow
Step Action 1 User selects AI agent from chat list 2 Detect agent by checking user role for “agentic” 3 Launch ProductionAIAgentViewController 4 Configure header, message list, and composer 5 User sends message, AI responds with streaming 6 Access chat history via header button
Components Reference
Component Purpose CometChatMessageHeaderNavigation and chat history access CometChatMessageListDisplay messages with AI responses CometChatMessageComposerSend messages to AI agent CometChatAIAssistanceChatHistoryBrowse previous AI conversations CometChatAIAssistantBubbleAI message bubble styling
AI Features Overview of all AI-powered features
AI Chat History Browse and resume AI conversations
Message List Display and customize chat messages