
Prerequisites
Before implementing AI agents, ensure you have:- Completed Getting Started setup
- CometChat UIKit v5+ installed
- AI features enabled in your CometChat Dashboard
- User logged in with
CometChatUIKit.login()
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:Report incorrect code
Copy
Ask AI
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:Report incorrect code
Copy
Ask AI
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:Report incorrect code
Copy
Ask AI
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
Customize the AI chat bubble appearance:Report incorrect code
Copy
Ask AI
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 |
|---|---|
backgroundColor | Bubble background color |
borderWidth | Bubble border width |
borderColor | Bubble border color |
textColor | Message text color |
textFont | Message text font |
cornerRadius | Bubble corner radius |
Customization Options
Empty State View
Customize the view shown when there are no messages:Report incorrect code
Copy
Ask AI
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:Report incorrect code
Copy
Ask AI
// Configure streaming speed (characters per second)
messageList.set(streamingSpeed: 50)
Suggested Messages
Provide quick-start prompts for users:Report incorrect code
Copy
Ask AI
let suggestions = [
"What can you help me with?",
"Tell me about your capabilities",
"How do I get started?"
]
messageComposer.set(suggestedMessages: suggestions)
AI Assistant Tools
Configure custom tools for the AI agent:Report incorrect code
Copy
Ask AI
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
TheCometChatAIAssistanceChatHistory component displays previous AI conversations:
Report incorrect code
Copy
Ask AI
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 |
|---|---|
CometChatMessageHeader | Navigation and chat history access |
CometChatMessageList | Display messages with AI responses |
CometChatMessageComposer | Send messages to AI agent |
CometChatAIAssistanceChatHistory | Browse previous AI conversations |
CometChatAIAssistantBubble | AI message bubble styling |
Related Guides
AI Features
Overview of all AI-powered features
AI Chat History
Browse and resume AI conversations
Message List
Display and customize chat messages