diff --git a/ui-kit/ios/ai-assistant-chat-history.mdx b/ui-kit/ios/ai-assistant-chat-history.mdx
index a811738d7..66c7baac0 100644
--- a/ui-kit/ios/ai-assistant-chat-history.mdx
+++ b/ui-kit/ios/ai-assistant-chat-history.mdx
@@ -37,7 +37,7 @@ The `CometChatAIAssistanceChatHistory` component displays past conversations bet
"sdkListeners": [],
"compositionExample": {
"description": "AIAssistanceChatHistory shows previous AI conversations for a user or group",
- "components": ["CometChatAIAssistanceChatHistory", "CometChatMessages"],
+ "components": ["CometChatAIAssistanceChatHistory", "CometChatMessageList"],
"flow": "User opens AI history → selects conversation → views full AI chat"
}
}
@@ -258,7 +258,7 @@ class AIAssistantViewController: UIViewController {
// MARK: - Actions
private func startNewAIChat() {
// Option 1: Open messages view for new AI chat
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
navigationController?.pushViewController(messagesVC, animated: true)
@@ -284,7 +284,7 @@ class AIAssistantViewController: UIViewController {
}
private func continueChat(from message: BaseMessage) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -589,7 +589,7 @@ class MainTabBarController: UITabBarController {
private func setupTabs() {
// Chats Tab
- let chatsVC = CometChatConversationsWithMessages()
+ let chatsVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let chatsNav = UINavigationController(rootViewController: chatsVC)
chatsNav.tabBarItem = UITabBarItem(
title: "Chats",
@@ -611,7 +611,7 @@ class MainTabBarController: UITabBarController {
)
// Users Tab
- let usersVC = CometChatUsersWithMessages()
+ let usersVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let usersNav = UINavigationController(rootViewController: usersVC)
usersNav.tabBarItem = UITabBarItem(
title: "Users",
@@ -623,7 +623,7 @@ class MainTabBarController: UITabBarController {
}
private func startNewAIChat() {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = currentUser
if let nav = selectedViewController as? UINavigationController {
@@ -683,7 +683,7 @@ class ProfileViewController: UIViewController {
chatHistory.user = user
chatHistory.onNewChatButtonClicked = { [weak self] selectedUser in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = selectedUser
self?.navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -762,7 +762,7 @@ Show AI chat history when user taps a button in their profile:
chatHistory.user = currentUser
chatHistory.onNewChatButtonClicked = { [weak self] user in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
self?.navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -785,7 +785,7 @@ chatHistory.user = user
chatHistory.onMessageClicked = { [weak self] message in
// Open the messages view to continue the conversation
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = self?.user
self?.navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -846,7 +846,7 @@ class MainTabBarController: UITabBarController {
aiHistory.user = currentUser
aiHistory.onNewChatButtonClicked = { [weak self] user in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
if let nav = self?.selectedViewController as? UINavigationController {
nav.pushViewController(messagesVC, animated: true)
diff --git a/ui-kit/ios/ai-features.mdx b/ui-kit/ios/ai-features.mdx
index fbb20b85e..44e03fe80 100644
--- a/ui-kit/ios/ai-features.mdx
+++ b/ui-kit/ios/ai-features.mdx
@@ -9,7 +9,7 @@ description: "Complete guide to AI-powered chat features in iOS apps - conversat
{
"category": "ai",
"features": [
- {"name": "aiAgentChat", "description": "Chat with AI-powered assistants", "component": "CometChatMessages", "enabledByDefault": false},
+ {"name": "aiAgentChat", "description": "Chat with AI-powered assistants", "component": "CometChatMessageList", "enabledByDefault": false},
{"name": "chatHistory", "description": "Browse and resume previous AI sessions", "component": "CometChatAIAssistanceChatHistory", "enabledByDefault": false},
{"name": "streamingResponses", "description": "Real-time AI message streaming", "component": "CometChatMessageList", "enabledByDefault": false},
{"name": "suggestedMessages", "description": "AI-powered conversation starters and smart replies", "component": "CometChatMessageComposer", "enabledByDefault": false}
@@ -18,7 +18,7 @@ description: "Complete guide to AI-powered chat features in iOS apps - conversat
"location": "CometChat Dashboard → AI",
"features": ["Conversation Starter", "Smart Replies", "Conversation Summary"]
},
- "relatedComponents": ["CometChatMessages", "CometChatAIAssistanceChatHistory", "CometChatMessageList", "CometChatMessageComposer"]
+ "relatedComponents": ["CometChatMessageList", "CometChatAIAssistanceChatHistory", "CometChatMessageList", "CometChatMessageComposer"]
}
```
@@ -80,7 +80,7 @@ When a user opens a new chat with no message history, AI suggests conversation o
### Implementation
-Conversation starters appear automatically in `CometChatMessages`:
+Conversation starters appear automatically in `CometChatMessageList`:
@@ -94,7 +94,7 @@ class ChatViewController: UIViewController {
func openChatWithUser(uid: String) {
CometChat.getUser(UID: uid) { [weak self] user in
DispatchQueue.main.async {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
// Conversation starters appear automatically
@@ -142,7 +142,7 @@ import CometChatSDK
class ChatViewController: UIViewController {
func openChat(with user: CometChat.User) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
// Smart replies appear automatically in the composer
@@ -186,7 +186,7 @@ import CometChatSDK
class ChatViewController: UIViewController {
func openChat(with user: CometChat.User) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
// Conversation summary option appears in composer action sheet
@@ -400,7 +400,7 @@ class AIEnabledTabBarController: UITabBarController {
private func setupTabs() {
// Chats - AI features (starters, smart replies, summary) work automatically
- let chatsVC = CometChatConversationsWithMessages()
+ let chatsVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let chatsNav = UINavigationController(rootViewController: chatsVC)
chatsNav.tabBarItem = UITabBarItem(
title: "Chats",
@@ -418,7 +418,7 @@ class AIEnabledTabBarController: UITabBarController {
)
// Users
- let usersVC = CometChatUsersWithMessages()
+ let usersVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let usersNav = UINavigationController(rootViewController: usersVC)
usersNav.tabBarItem = UITabBarItem(
title: "Users",
@@ -491,7 +491,7 @@ extension AIAssistantListViewController: UITableViewDelegate, UITableViewDataSou
chatHistory.onNewChatButtonClicked = { [weak self] in
// Start new AI chat
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
self?.navigationController?.pushViewController(messagesVC, animated: true)
}
diff --git a/ui-kit/ios/call-buttons.mdx b/ui-kit/ios/call-buttons.mdx
index 39bd76112..83b796d1c 100644
--- a/ui-kit/ios/call-buttons.mdx
+++ b/ui-kit/ios/call-buttons.mdx
@@ -92,7 +92,7 @@ The `setOnVoiceCallClick` action is usually invoked when a voice call is initiat
```swift lines
let cometChatCallButton = CometChatCallButtons(width: 24, height: 24)
-.set(onVoiceCallClick: { user, group in
+.onVoiceCallClick = { user, group in
//Perform Your Action
})
```
@@ -109,7 +109,7 @@ The `setOnVideoCallClick` action is typically triggered when a video call is ini
```swift lines
let cometChatCallButton = CometChatCallButtons(width: 24, height: 24)
-.set(onVideoCallClick: { user, group in
+.onVideoCallClick = { user, group in
//Perform Your Action
})
@@ -308,7 +308,7 @@ Below is a list of customizations along with corresponding code snippets
| set(group:Group) | Sets the Group object for CometChatCallButtons. | `.set(group:Group)` |
| set(outgoingCallConfiguration:) | Sets the configuration for outgoing calls. | `setOutgoingCallConfiguration(config)` |
| set(customSoundForCalls:) | Sets a custom sound for incoming and outgoing calls. | `set(customSoundForCalls: URL)` |
-| set(callSettingBuilder:) | Function to build call settings based on call type and participants. | `.set(callSettingBuilder { callType, participants in ... })` |
+| set(callSettingsBuilder:) | Function to build call settings based on call type and participants. | `.set(callSettingBuilder { callType, participants in ... })` |
### Advanced
@@ -516,7 +516,7 @@ Show confirmation before starting a call:
```swift lines
let callButtons = CometChatCallButtons(width: 24, height: 24)
callButtons.set(user: user)
-callButtons.set(onVoiceCallClick: { [weak self] user, group in
+callButtons.onVoiceCallClick = { [weak self] user, group in
let alert = UIAlertController(
title: "Start Voice Call",
message: "Call \(user?.name ?? group?.name ?? "")?",
@@ -546,7 +546,7 @@ callButtons.hideVoiceCallButton = true // Groups often use video calls
callButtons.set(controller: self)
// Custom call settings for group calls
-callButtons.set(callSettingBuilder: { callType, participants in
+callButtons.set(callSettingsBuilder: { callType, participants in
return CallSettingsBuilder()
.setDefaultLayout(true)
.setShowRecordingButton(true)
diff --git a/ui-kit/ios/call-features.mdx b/ui-kit/ios/call-features.mdx
index 863aef8e3..890844cda 100644
--- a/ui-kit/ios/call-features.mdx
+++ b/ui-kit/ios/call-features.mdx
@@ -104,7 +104,7 @@ func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options conn
-**That's it!** Call buttons now appear in `CometChatMessages` header automatically.
+**That's it!** Call buttons appear in `CometChatMessageHeader` automatically.
---
@@ -190,7 +190,7 @@ class MainTabBarController: UITabBarController {
private func setupTabs() {
// Chats Tab - with calling enabled
- let chatsVC = CometChatConversationsWithMessages()
+ let chatsVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let chatsNav = UINavigationController(rootViewController: chatsVC)
chatsNav.tabBarItem = UITabBarItem(
title: "Chats",
@@ -211,7 +211,7 @@ class MainTabBarController: UITabBarController {
)
// Users Tab
- let usersVC = CometChatUsersWithMessages()
+ let usersVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let usersNav = UINavigationController(rootViewController: usersVC)
usersNav.tabBarItem = UITabBarItem(
title: "Users",
@@ -220,7 +220,7 @@ class MainTabBarController: UITabBarController {
)
// Groups Tab
- let groupsVC = CometChatGroupsWithMessages()
+ let groupsVC = ChatListVC() // your own list + chat screen — see /ui-kit/ios/ios-tab-based-chat
let groupsNav = UINavigationController(rootViewController: groupsVC)
groupsNav.tabBarItem = UITabBarItem(
title: "Groups",
@@ -253,7 +253,7 @@ class MainTabBarController: UITabBarController {
// Fetch user and open chat
CometChat.getUser(UID: uid) { [weak self] user in
DispatchQueue.main.async {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.user = user
if let nav = self?.selectedViewController as? UINavigationController {
@@ -484,11 +484,11 @@ class ChatHeaderViewController: UIViewController {
callButtons.user = user
// Customize actions
- callButtons.set(onVoiceCallClick: { user, group in
+ callButtons.onVoiceCallClick = { user, group in
print("Voice call to: \(user?.name ?? group?.name ?? "")")
})
- callButtons.set(onVideoCallClick: { user, group in
+ callButtons.onVideoCallClick = { user, group in
print("Video call to: \(user?.name ?? group?.name ?? "")")
})
@@ -581,8 +581,8 @@ let callButtons = CometChatCallButtons()
callButtons.user = user // or callButtons.group = group
// Callbacks
-callButtons.set(onVoiceCallClick: { user, group in })
-callButtons.set(onVideoCallClick: { user, group in })
+callButtons.onVoiceCallClick = { user, group in })
+callButtons.onVideoCallClick = { user, group in })
callButtons.set(onError: { error in })
```
@@ -595,7 +595,7 @@ let incomingCall = CometChatIncomingCall()
incomingCall.set(call: call)
incomingCall.set(onAcceptClick: { call in })
-incomingCall.set(onDeclineClick: { call in })
+incomingCall.set(onCancelClick: { call in })
```
### CometChatOutgoingCall
diff --git a/ui-kit/ios/component-styling.mdx b/ui-kit/ios/component-styling.mdx
index 2b372fb1a..847f8bf2b 100644
--- a/ui-kit/ios/component-styling.mdx
+++ b/ui-kit/ios/component-styling.mdx
@@ -369,7 +369,7 @@ CometChatSearch.style.listItemBackground = UIColor(hex: "#EDEAFA")
import CometChatUIKitSwift
// Date separator style
-let dateStyle = CometChatDateStyle()
+let dateStyle = DateStyle()
dateStyle.textColor = UIColor(hex: "#8E8E93")
dateStyle.textFont = UIFont.systemFont(ofSize: 12)
diff --git a/ui-kit/ios/components-overview.mdx b/ui-kit/ios/components-overview.mdx
index 06fa3c5b1..81689e84f 100644
--- a/ui-kit/ios/components-overview.mdx
+++ b/ui-kit/ios/components-overview.mdx
@@ -31,12 +31,12 @@ description: "Understand CometChat iOS UI Kit component types, base components,
{"name": "CometChatMessageHeader", "purpose": "Chat header"},
{"name": "CometChatCallLogs", "purpose": "Call history"}
],
- "compositeComponents": [
- {"name": "CometChatMessages", "contains": ["MessageHeader", "MessageList", "MessageComposer"]},
- {"name": "CometChatUsersWithMessages", "contains": ["Users", "Messages"]},
- {"name": "CometChatGroupsWithMessages", "contains": ["Groups", "Messages"]},
- {"name": "CometChatConversationsWithMessages", "contains": ["Conversations", "Messages"]}
- ]
+ "composition": {
+ "note": "v5 ships NO composite/all-in-one component. The host composes the chat screen itself.",
+ "chatScreen": ["CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
+ "listToChat": "CometChatConversations.set(onItemClick:) -> push your own messages view controller",
+ "recipe": "/ui-kit/ios/ios-conversation"
+ }
}
```
@@ -123,34 +123,44 @@ messageList.set(user: user)
---
-### Composite Components
+### Composing a chat screen
-Combine multiple components into complete features.
+The UI Kit ships **no composite/all-in-one component** — you compose the chat screen yourself from
+the three message components, and drive navigation from the list's `onItemClick`. This keeps your
+navigation, layout, and presentation under your control.
-| Component | Contains |
+| You want | Compose |
|-----------|----------|
-| `CometChatMessages` | MessageHeader + MessageList + MessageComposer |
-| `CometChatUsersWithMessages` | Users + Messages |
-| `CometChatGroupsWithMessages` | Groups + Messages |
-| `CometChatConversationsWithMessages` | Conversations + Messages |
+| A chat screen | `CometChatMessageHeader` + `CometChatMessageList` + `CometChatMessageComposer` |
+| Chat with user selection | `CometChatUsers` → push your chat screen |
+| Chat with group selection | `CometChatGroups` → push your chat screen |
+| Chat with recent conversations | `CometChatConversations` → push your chat screen |
```swift lines
import CometChatUIKitSwift
-// Complete chat experience in one component
-let conversationsWithMessages = CometChatConversationsWithMessages()
-navigationController?.pushViewController(conversationsWithMessages, animated: true)
-
-// Or just the messages view
-let messages = CometChatMessages()
-messages.user = user // or messages.group = group
-navigationController?.pushViewController(messages, animated: true)
+// Show recent conversations, then push YOUR chat screen on selection.
+let conversations = CometChatConversations()
+conversations.set(onItemClick: { [weak self] conversation, _ in
+ let messagesVC = MessagesVC() // your view controller — see the recipe below
+ messagesVC.user = conversation.conversationWith as? User
+ messagesVC.group = conversation.conversationWith as? Group
+ self?.navigationController?.pushViewController(messagesVC, animated: true)
+})
+navigationController?.pushViewController(conversations, animated: true)
```
+
+ For the full `MessagesVC` — the three components laid out with safe-area constraints — follow
+ [Conversation List + Message View](/ui-kit/ios/ios-conversation). The same pattern with a users or
+ groups list is in [One-to-One / Group Chat](/ui-kit/ios/ios-one-to-one-chat), and inside a tab bar in
+ [Tab-Based Chat](/ui-kit/ios/ios-tab-based-chat).
+
+
---
## Actions
@@ -291,61 +301,65 @@ class ChatManager {
---
-## Configurations
+## Configuring components
-Customize nested components within composite components:
+Because you compose the chat screen yourself, you configure **each component directly on its own
+instance** — there is no configuration object to pass down through a parent.
```swift lines
import CometChatUIKitSwift
-// CometChatMessages contains: MessageHeader, MessageList, MessageComposer
-// You can configure each one:
-
-let messages = CometChatMessages()
-messages.user = user
-
-// Configure MessageHeader
-let headerConfig = MessageHeaderConfiguration()
-headerConfig.hideBackButton = false
-headerConfig.set(subtitleView: { user, group in
+// Header — set the target, then customize it directly
+let messageHeader = CometChatMessageHeader()
+messageHeader.set(user: user)
+messageHeader.set(controller: self)
+messageHeader.hideBackButton = false
+messageHeader.set(subtitleView: { user, group in
let label = UILabel()
+ label.font = UIFont.systemFont(ofSize: 13)
+ label.textColor = .secondaryLabel
label.text = user?.status == .online ? "Online" : "Offline"
- label.textColor = user?.status == .online ? .systemGreen : .gray
return label
})
-messages.set(messageHeaderConfiguration: headerConfig)
-
-// Configure MessageList
-let listConfig = MessageListConfiguration()
-listConfig.set(emptyStateText: "No messages yet")
-listConfig.set(errorStateText: "Failed to load messages")
-messages.set(messageListConfiguration: listConfig)
-
-// Configure MessageComposer
-let composerConfig = MessageComposerConfiguration()
-composerConfig.set(placeholderText: "Type a message...")
-composerConfig.hideLiveReaction = true
-messages.set(messageComposerConfiguration: composerConfig)
+
+// Message list — same target, its own empty/error views
+let messageList = CometChatMessageList()
+messageList.set(user: user)
+messageList.set(controller: self)
+messageList.set(emptyView: myEmptyView)
+messageList.set(errorView: myErrorView)
+
+// Composer — same target
+let composer = CometChatMessageComposer()
+composer.set(user: user)
+composer.set(controller: self)
+composer.placeholderText = "Type a message..."
```
+
+ Pass the **same** `user` (or `group`) to all three components — that shared target is what keeps the
+ header, list, and composer on the same conversation. Component-specific configuration objects do exist
+ for nested sub-features (for example `ReactionsConfiguration`, `StickerKeyboardConfiguration`,
+ `IncomingCallConfiguration`); see each component's own page for its full API.
+
+
---
## Component Hierarchy
```
-CometChatConversationsWithMessages
-├── CometChatConversations
-│ ├── CometChatListItem
-│ │ ├── CometChatAvatar
-│ │ ├── CometChatBadge
-│ │ ├── CometChatStatusIndicator
-│ │ └── CometChatDate
-│ └── CometChatListBase
-└── CometChatMessages
+YourNavigationController // yours
+├── CometChatConversations // list screen
+│ └── CometChatListItem
+│ ├── CometChatAvatar
+│ ├── CometChatBadge
+│ ├── CometChatStatusIndicator
+│ └── CometChatDate
+└── MessagesVC // YOUR view controller, pushed on selection
├── CometChatMessageHeader
│ ├── CometChatAvatar
│ └── CometChatStatusIndicator
@@ -358,6 +372,9 @@ CometChatConversationsWithMessages
└── CometChatStickerKeyboard
```
+The two levels you own are the navigation controller and `MessagesVC`; everything below them is a
+UI Kit component.
+
---
## Quick Reference
@@ -368,25 +385,30 @@ CometChatConversationsWithMessages
|------|-----|
| Display user avatar | `CometChatAvatar` (Base) |
| Show list of users | `CometChatUsers` (Component) |
-| Complete chat with user selection | `CometChatUsersWithMessages` (Composite) |
+| Complete chat with user selection | `CometChatUsers` → push your chat screen ([recipe](/ui-kit/ios/ios-one-to-one-chat)) |
+| Complete chat with recent conversations | `CometChatConversations` → push your chat screen ([recipe](/ui-kit/ios/ios-conversation)) |
| Custom chat UI | Individual Components |
-| Quick integration | Composite Components |
### Common Patterns
```swift lines
-// Pattern 1: Quick integration with composite
-let chat = CometChatConversationsWithMessages()
-navigationController?.pushViewController(chat, animated: true)
+// Pattern 1: Recent conversations -> your chat screen
+let conversations = CometChatConversations()
+conversations.set(onItemClick: { [weak self] conversation, _ in
+ let messagesVC = MessagesVC()
+ messagesVC.user = conversation.conversationWith as? User
+ messagesVC.group = conversation.conversationWith as? Group
+ self?.navigationController?.pushViewController(messagesVC, animated: true)
+})
-// Pattern 2: Custom flow with components
+// Pattern 2: User list -> your chat screen
let users = CometChatUsers()
-users.set(onItemClick: { user, _ in
- let messages = CometChatMessages()
- messages.user = user
- self.navigationController?.pushViewController(messages, animated: true)
+users.set(onItemClick: { [weak self] user, _ in
+ let messagesVC = MessagesVC()
+ messagesVC.user = user
+ self?.navigationController?.pushViewController(messagesVC, animated: true)
})
// Pattern 3: Fully custom with base components
diff --git a/ui-kit/ios/conversations.mdx b/ui-kit/ios/conversations.mdx
index 7e15e8704..fc108b494 100644
--- a/ui-kit/ios/conversations.mdx
+++ b/ui-kit/ios/conversations.mdx
@@ -59,10 +59,10 @@ The `CometChatConversations` component displays a list of all conversations (one
"leadingView": "(Conversation) -> UIView",
"titleView": "(Conversation) -> UIView",
"subtitleView": "(Conversation) -> UIView",
- "tailView": "(Conversation) -> UIView",
- "emptyStateView": "() -> UIView",
- "errorStateView": "() -> UIView",
- "loadingStateView": "() -> UIView"
+ "trailView": "(Conversation) -> UIView",
+ "emptyStateView": "UIView (assign a view; not a closure — inherited from CometChatListBase)",
+ "errorStateView": "UIView (assign a view; not a closure — inherited from CometChatListBase)",
+ "loadingView": "UIView (assign a view; not a closure)"
},
"formatting": {
"datePattern": "(Conversation) -> String",
@@ -89,8 +89,8 @@ The `CometChatConversations` component displays a list of all conversations (one
],
"compositionExample": {
"description": "Conversations list navigating to Messages",
- "components": ["CometChatConversations", "CometChatMessages"],
- "flow": "User taps conversation → onItemClick fires → Navigate to CometChatMessages with user/group"
+ "components": ["CometChatConversations", "CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
+ "flow": "User taps conversation → onItemClick fires → push YOUR chat screen (header + list + composer) with the user/group. v5 ships no composite component."
},
"types": {
"Conversation": {
@@ -101,9 +101,10 @@ The `CometChatConversations` component displays a list of all conversations (one
"unreadMessageCount": "Int"
},
"ConversationType": {
- "user": "One-on-one conversation",
- "group": "Group conversation",
- "both": "All conversation types"
+ "user": "One-on-one conversations only",
+ "group": "Group conversations only",
+ "none": "No type filter",
+ "_note": "Set with setConversationType(conversationType:), not set(conversationType:). Omit it entirely to get both 1:1s and groups."
}
}
}
@@ -120,7 +121,7 @@ The `CometChatConversations` component displays a list of all conversations (one
## Where It Fits
-`CometChatConversations` serves as the main entry point for chat functionality. It displays all conversations and navigates to `CometChatMessages` when a conversation is selected.
+`CometChatConversations` serves as the main entry point for chat functionality. It displays all conversations; on selection you push **your own** chat screen, composed from `CometChatMessageHeader` + `CometChatMessageList` + `CometChatMessageComposer` (see [Conversation List + Message View](/ui-kit/ios/ios-conversation)). The UI Kit ships no composite/all-in-one messages component.
```swift lines
import UIKit
@@ -148,13 +149,10 @@ class ChatListViewController: UIViewController {
}
private func openMessages(for conversation: Conversation) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
- if let user = conversation.conversationWith as? User {
- messagesVC.set(user: user)
- } else if let group = conversation.conversationWith as? Group {
- messagesVC.set(group: group)
- }
+ messagesVC.user = conversation.conversationWith as? User
+ messagesVC.group = conversation.conversationWith as? Group
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -191,8 +189,8 @@ import CometChatUIKitSwift
import CometChatSDK
// Create a custom request builder
+// Omit setConversationType to get BOTH 1:1s and groups — that is the default.
let requestBuilder = ConversationRequest.ConversationRequestBuilder(limit: 30)
- .set(conversationType: .both)
let conversations = CometChatConversations(conversationRequestBuilder: requestBuilder)
```
@@ -201,8 +199,8 @@ let conversations = CometChatConversations(conversationRequestBuilder: requestBu
| Recipe | Code |
|--------|------|
-| Show only one-on-one chats | `.set(conversationType: .user)` |
-| Show only group chats | `.set(conversationType: .group)` |
+| Show only one-on-one chats | `.setConversationType(conversationType: .user)` |
+| Show only group chats | `.setConversationType(conversationType: .group)` |
| Filter by tags | `.withTags(true).set(tags: ["support", "sales"])` |
| Limit results | `ConversationRequestBuilder(limit: 20)` |
| Include user/group tags | `.withUserAndGroupTags(true)` |
@@ -226,13 +224,10 @@ let conversations = CometChatConversations()
conversations.set(onItemClick: { [weak self] conversation, indexPath in
guard let self = self else { return }
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
- if let user = conversation.conversationWith as? User {
- messagesVC.set(user: user)
- } else if let group = conversation.conversationWith as? Group {
- messagesVC.set(group: group)
- }
+ messagesVC.user = conversation.conversationWith as? User
+ messagesVC.group = conversation.conversationWith as? Group
self.navigationController?.pushViewController(messagesVC, animated: true)
})
@@ -959,11 +954,11 @@ import CometChatUIKitSwift
let conversations = CometChatConversations()
-// Create custom text formatters
-let mentionFormatter = CometChatMentionTextFormatter()
-let urlFormatter = CometChatURLTextFormatter()
+// Mentions are formatted by CometChatMentionsFormatter, a CometChatTextFormatter subclass.
+// Subclass CometChatTextFormatter yourself for any other formatting you need.
+let mentionFormatter = CometChatMentionsFormatter()
-conversations.set(textFormatters: [mentionFormatter, urlFormatter])
+conversations.set(textFormatters: [mentionFormatter])
```
---
@@ -992,7 +987,7 @@ avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
avatarStyle.borderWidth = 1
avatarStyle.borderColor = UIColor.systemGray4
-conversations.set(avatarStyle: avatarStyle)
+conversations.avatarStyle = avatarStyle
```
### badgeStyle
@@ -1015,7 +1010,7 @@ badgeStyle.textColor = UIColor.white
badgeStyle.textFont = UIFont.systemFont(ofSize: 12, weight: .bold)
badgeStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 10)
-conversations.set(badgeStyle: badgeStyle)
+conversations.badgeStyle = badgeStyle
```
### conversationRequestBuilder
@@ -1045,7 +1040,7 @@ let dateStyle = DateStyle()
dateStyle.textColor = UIColor.secondaryLabel
dateStyle.textFont = UIFont.systemFont(ofSize: 12)
-conversations.set(dateStyle: dateStyle)
+conversations.dateStyle = dateStyle
```
### dateTimeFormatter
@@ -1181,10 +1176,10 @@ import CometChatUIKitSwift
let conversations = CometChatConversations()
-conversations.set(onSearchClick: { [weak self] in
+conversations.onSearchClick = { [weak self] in
// Handle search button click
self?.presentSearchViewController()
-})
+}
```
### privateGroupIcon
@@ -1238,7 +1233,7 @@ receiptStyle.sentIconTint = UIColor.systemGray
receiptStyle.deliveredIconTint = UIColor.systemGray
receiptStyle.readIconTint = UIColor.systemBlue
-conversations.set(receiptStyle: receiptStyle)
+conversations.receiptStyle = receiptStyle
```
### selectionMode
@@ -1269,7 +1264,7 @@ statusIndicatorStyle.backgroundColor = UIColor.systemGreen
statusIndicatorStyle.borderWidth = 2
statusIndicatorStyle.borderColor = UIColor.white
-conversations.set(statusIndicatorStyle: statusIndicatorStyle)
+conversations.statusIndicatorStyle = statusIndicatorStyle
```
### textFormatters
@@ -1299,7 +1294,7 @@ let typingIndicatorStyle = TypingIndicatorStyle()
typingIndicatorStyle.textColor = UIColor.systemGray
typingIndicatorStyle.textFont = UIFont.italicSystemFont(ofSize: 14)
-conversations.set(typingIndicatorStyle: typingIndicatorStyle)
+conversations.typingIndicatorStyle = typingIndicatorStyle
```
---
@@ -1448,13 +1443,10 @@ class MentionConfiguredViewController: UIViewController {
}
private func openMessages(for conversation: Conversation) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
- if let user = conversation.conversationWith as? User {
- messagesVC.set(user: user)
- } else if let group = conversation.conversationWith as? Group {
- messagesVC.set(group: group)
- }
+ messagesVC.user = conversation.conversationWith as? User
+ messagesVC.group = conversation.conversationWith as? Group
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -1519,7 +1511,7 @@ class ConversationsContainerViewController: UINavigationController {
// Navigate to messages on tap
conversations.set(onItemClick: { [weak self] conversation, _ in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
if let user = conversation.conversationWith as? User {
messagesVC.set(user: user)
@@ -1537,24 +1529,30 @@ class ConversationsContainerViewController: UINavigationController {
### Custom empty state with CTA
+The empty state is a **`UIView` you assign**, not a closure — `emptyStateView` is inherited from
+`CometChatListBase`. Build the view first, then set it (`set(emptyView:)` is the equivalent builder form).
+
```swift lines
let conversations = CometChatConversations()
-conversations.set(emptyStateView: {
- let emptyView = UIView()
-
- let label = UILabel()
- label.text = "No conversations yet"
- label.textAlignment = .center
- label.textColor = .secondaryLabel
-
- let button = UIButton(type: .system)
- button.setTitle("Start a conversation", for: .normal)
- button.addTarget(self, action: #selector(startNewConversation), for: .touchUpInside)
-
- // Add subviews and constraints...
- return emptyView
-})
+let emptyView = UIView()
+
+let label = UILabel()
+label.text = "No conversations yet"
+label.textAlignment = .center
+label.textColor = .secondaryLabel
+
+let button = UIButton(type: .system)
+button.setTitle("Start a conversation", for: .normal)
+button.addTarget(self, action: #selector(startNewConversation), for: .touchUpInside)
+
+// Add subviews and constraints to emptyView...
+
+conversations.emptyStateView = emptyView // or: conversations.set(emptyView: emptyView)
+
+// Want to keep the built-in empty state and just retitle it?
+conversations.emptyStateTitleText = "No conversations yet"
+conversations.emptyStateSubTitleText = "Start a chat to see it here"
```
### Hide all chrome — minimal list
@@ -1572,13 +1570,13 @@ conversations.hideDeleteConversationOption = true
```swift lines
// Only user conversations
let userOnlyBuilder = ConversationRequest.ConversationRequestBuilder(limit: 30)
- .set(conversationType: .user)
+ .setConversationType(conversationType: .user)
let conversations = CometChatConversations(conversationRequestBuilder: userOnlyBuilder)
// Only group conversations
let groupOnlyBuilder = ConversationRequest.ConversationRequestBuilder(limit: 30)
- .set(conversationType: .group)
+ .setConversationType(conversationType: .group)
let groupConversations = CometChatConversations(conversationRequestBuilder: groupOnlyBuilder)
```
diff --git a/ui-kit/ios/core-features.mdx b/ui-kit/ios/core-features.mdx
index ae494ff0d..32f7b1fba 100644
--- a/ui-kit/ios/core-features.mdx
+++ b/ui-kit/ios/core-features.mdx
@@ -8,7 +8,7 @@ description: "Review CometChat iOS UI Kit core features for messaging, media sha
{
"category": "messaging",
"features": [
- {"name": "instantMessaging", "description": "Send and receive text messages in real-time", "component": "CometChatMessages", "enabledByDefault": true},
+ {"name": "instantMessaging", "description": "Send and receive text messages in real-time", "component": "CometChatMessageList", "enabledByDefault": true},
{"name": "mediaSharing", "description": "Share images, videos, audio files, and documents", "component": "CometChatMessageComposer", "enabledByDefault": true},
{"name": "readReceipts", "description": "Show when messages are delivered and read", "component": "CometChatMessageList", "enabledByDefault": true},
{"name": "typingIndicators", "description": "Show when users are typing in real-time", "component": "CometChatMessageHeader", "enabledByDefault": true},
@@ -19,7 +19,7 @@ description: "Review CometChat iOS UI Kit core features for messaging, media sha
{"name": "groupChat", "description": "Create and manage group conversations", "component": "CometChatGroups", "enabledByDefault": true},
{"name": "search", "description": "Search across conversations and messages", "component": "CometChatSearch", "enabledByDefault": true}
],
- "relatedComponents": ["CometChatMessages", "CometChatConversations", "CometChatMessageList", "CometChatMessageComposer"]
+ "relatedComponents": ["CometChatMessageList", "CometChatConversations", "CometChatMessageList", "CometChatMessageComposer"]
}
```
@@ -45,7 +45,7 @@ class ChatViewController: UIViewController {
super.viewDidLoad()
// For one-on-one chat
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
// Set the user to chat with
CometChat.getUser(UID: "cometchat-uid-1") { user in
@@ -83,7 +83,7 @@ class MediaChatViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
// The message composer includes multi-attachment media sharing:
// - Multi-select photos and videos from the library
@@ -136,7 +136,7 @@ class ReceiptsViewController: UIViewController {
super.viewDidLoad()
// Read receipts are enabled by default
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
// To hide receipts:
// messagesVC.hideReceipts = true
@@ -188,7 +188,7 @@ class UnreadMessagesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
// Enable starting from first unread message
messagesVC.scrollToUnreadMessages = true
@@ -238,7 +238,7 @@ class TypingIndicatorViewController: UIViewController {
// - CometChatConversations (shows "typing..." in conversation list)
// - CometChatMessageHeader (shows "typing..." below user name)
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -343,7 +343,7 @@ class ReactionsViewController: UIViewController {
// Reactions are enabled by default
// Users can long-press a message to add reactions
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -402,7 +402,7 @@ class MentionsViewController: UIViewController {
// Mentions are enabled by default
// Type @ in the composer to see mention suggestions
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getGroup(GUID: "group-123") { group in
DispatchQueue.main.async {
@@ -474,7 +474,7 @@ class ThreadedMessagesViewController: UIViewController {
// Threaded messages are enabled by default
// Users can tap "Reply in thread" on any message
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -504,14 +504,14 @@ class ThreadedMessagesViewController: UIViewController {
// Create message list for thread replies
let messageList = CometChatMessageList()
messageList.set(user: user)
- messageList.set(parentMessage: parentMessage)
+ messageList.set(parentMessageId: parentMessage.id)
messageList.set(controller: threadVC)
messageList.translatesAutoresizingMaskIntoConstraints = false
// Create composer for thread replies
let composer = CometChatMessageComposer()
composer.set(user: user)
- composer.set(parentMessage: parentMessage)
+ composer.set(parentMessageId: parentMessage.id)
composer.set(controller: threadVC)
composer.translatesAutoresizingMaskIntoConstraints = false
@@ -593,7 +593,7 @@ class GroupChatViewController: UIViewController {
// Open chat for a group
func openGroupChat(group: Group) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(group: group)
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -658,7 +658,7 @@ class QuotedReplyViewController: UIViewController {
// Quoted reply is enabled by default
// Users can swipe right on a message or tap "Reply" in message actions
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -740,7 +740,7 @@ class ModerationViewController: UIViewController {
// Blocked messages are displayed appropriately
// based on your moderation rules
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -779,7 +779,7 @@ class ReportMessageViewController: UIViewController {
// Report message is available in message actions
// Users can long-press a message and select "Report"
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
CometChat.getUser(UID: "cometchat-uid-1") { user in
DispatchQueue.main.async {
@@ -862,7 +862,7 @@ class MainTabBarController: UITabBarController {
let conversationsNav = UINavigationController()
let conversations = CometChatConversations()
conversations.set(onItemClick: { [weak conversationsNav] conversation, _ in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
if let user = conversation.conversationWith as? User {
messagesVC.set(user: user)
} else if let group = conversation.conversationWith as? Group {
@@ -881,7 +881,7 @@ class MainTabBarController: UITabBarController {
let usersNav = UINavigationController()
let users = CometChatUsers()
users.set(onItemClick: { [weak usersNav] user, _ in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: user)
usersNav?.pushViewController(messagesVC, animated: true)
})
@@ -896,7 +896,7 @@ class MainTabBarController: UITabBarController {
let groupsNav = UINavigationController()
let groups = CometChatGroups()
groups.set(onItemClick: { [weak groupsNav] group, _ in
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(group: group)
groupsNav?.pushViewController(messagesVC, animated: true)
})
diff --git a/ui-kit/ios/group-members.mdx b/ui-kit/ios/group-members.mdx
index cc5e702f5..8fdb94de6 100644
--- a/ui-kit/ios/group-members.mdx
+++ b/ui-kit/ios/group-members.mdx
@@ -38,8 +38,7 @@ The `CometChatGroupMembers` component displays all members of a group with their
"onItemClick": "(GroupMember, IndexPath) -> Void",
"onItemLongClick": "(GroupMember, IndexPath) -> Void",
"onBack": "() -> Void",
- "onSelection": "([GroupMember]) -> Void",
- "onSelectedItemProceed": "([GroupMember]) -> Void",
+ "onSelectedItemProceed": "([GroupMember]) -> Void (assignable property)",
"onError": "(CometChatException) -> Void",
"onEmpty": "() -> Void",
"onLoad": "([GroupMember]) -> Void"
@@ -68,7 +67,7 @@ The `CometChatGroupMembers` component displays all members of a group with their
"titleView": "(GroupMember?) -> UIView",
"subtitleView": "(GroupMember?) -> UIView",
"trailView": "(GroupMember?) -> UIView",
- "emptyStateView": "UIView",
+ "emptyStateView": "UIView (assign a view; inherited from CometChatListBase)",
"errorStateView": "UIView",
"loadingStateView": "UIView"
}
@@ -113,7 +112,7 @@ The `CometChatGroupMembers` component displays all members of a group with their
],
"compositionExample": {
"description": "GroupMembers is typically accessed from group details or settings",
- "components": ["CometChatGroups", "CometChatGroupMembers", "CometChatMessages"],
+ "components": ["CometChatGroups", "CometChatGroupMembers", "CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
"flow": "User opens group → views members → taps member → starts direct chat"
},
"types": {
@@ -174,7 +173,7 @@ class GroupDetailViewController: UIViewController {
}
private func startDirectChat(with member: GroupMember) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: member)
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -251,7 +250,7 @@ let groupMembers = CometChatGroupMembers(group: group)
groupMembers.set(onItemClick: { [weak self] member, indexPath in
guard let self = self else { return }
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: member)
self.navigationController?.pushViewController(messagesVC, animated: true)
})
@@ -310,7 +309,7 @@ import CometChatSDK
let groupMembers = CometChatGroupMembers(group: group)
groupMembers.selectionMode = .multiple
-groupMembers.set(onSelection: { [weak self] selectedMembers in
+groupMembers.onSelectedItemProceed = { [weak self] selectedMembers in
print("Selected \(selectedMembers.count) members")
})
```
@@ -365,7 +364,7 @@ groupMembers.set(onLoad: { members in
| `set(onItemClick:)` | Triggered when a member is tapped | Start direct chat |
| `set(onItemLongClick:)` | Triggered on long press | Show options menu |
| `set(onBack:)` | Triggered when back button is pressed | Custom navigation |
-| `set(onSelection:)` | Triggered in selection mode | Multi-select members |
+| `onSelectedItemProceed` | Fires when the user confirms a multi-selection | Multi-select members |
| `set(onError:)` | Triggered when an error occurs | Show error alert |
| `set(onEmpty:)` | Triggered when list is empty | Show empty state |
| `set(onLoad:)` | Triggered when members load | Analytics tracking |
@@ -917,7 +916,7 @@ groupMembers.set(options: { group, member in
icon: UIImage(systemName: "message"),
backgroundColor: .systemBlue,
onClick: { member, group, section, option, controller in
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: member)
controller.navigationController?.pushViewController(messages, animated: true)
}
@@ -1136,7 +1135,7 @@ import CometChatSDK
let groupMembers = CometChatGroupMembers(group: group)
groupMembers.selectionMode = .multiple
-groupMembers.set(onSelectedItemProceed: { [weak self] selectedMembers in
+groupMembers.onSelectedItemProceed = { [weak self] selectedMembers in
print("Proceeding with \(selectedMembers.count) selected members")
for member in selectedMembers {
@@ -1178,7 +1177,7 @@ let messageOption = CometChatGroupMemberOption(
icon: UIImage(systemName: "message"),
backgroundColor: .systemBlue,
onClick: { member, group, section, option, controller in
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: member)
controller.navigationController?.pushViewController(messages, animated: true)
}
@@ -1223,16 +1222,19 @@ class GroupMembersViewController: UIViewController {
action: #selector(addMemberTapped)
)
- groupMembers.set(menus: [addButton])
+ groupMembers.menus = [addButton]
let navController = UINavigationController(rootViewController: groupMembers)
present(navController, animated: true)
}
@objc func addMemberTapped() {
- // Show add member screen
- let addMembers = CometChatAddMembers(group: group)
- navigationController?.pushViewController(addMembers, animated: true)
+ // The UI Kit ships no add-members component — build your own picker
+ // (CometChatUsers with selectionMode) and add via the SDK:
+ // CometChat.addMembersToGroup(guid:groupMembers:bannedUIDs:onSuccess:onError:)
+ // See /sdk/ios/group-add-members
+ let picker = AddMembersVC(group: group) // your own screen
+ navigationController?.pushViewController(picker, animated: true)
}
}
```
@@ -1268,12 +1270,12 @@ groupMembers.hideScopeChangeOption = true
```swift lines
let groupMembers = CometChatGroupMembers(group: group)
-groupMembers.set(emptyStateView: {
- let label = UILabel()
- label.text = "No members in this group"
- label.textAlignment = .center
- return label
-})
+// emptyStateView is a UIView you assign (inherited from CometChatListBase).
+let label = UILabel()
+label.text = "No members in this group"
+label.textAlignment = .center
+
+groupMembers.emptyStateView = emptyView // or: groupMembers.set(emptyView: emptyView)
```
### Multi-select members
@@ -1282,7 +1284,7 @@ groupMembers.set(emptyStateView: {
let groupMembers = CometChatGroupMembers(group: group)
groupMembers.selectionMode = .multiple
-groupMembers.set(onSelection: { selectedMembers in
+groupMembers.onSelectedItemProceed = { selectedMembers in
print("Selected \(selectedMembers.count) members")
// Kick selected members, change scope, etc.
})
diff --git a/ui-kit/ios/groups.mdx b/ui-kit/ios/groups.mdx
index 8be5fe225..6d0f85a73 100644
--- a/ui-kit/ios/groups.mdx
+++ b/ui-kit/ios/groups.mdx
@@ -106,8 +106,8 @@ The `CometChatGroups` component displays a searchable list of all available grou
],
"compositionExample": {
"description": "Groups list for browsing and joining group conversations",
- "components": ["CometChatGroups", "CometChatMessages"],
- "flow": "User taps on a group → onItemClick fires → Navigate to CometChatMessages with selected group"
+ "components": ["CometChatGroups", "CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
+ "flow": "User taps on a group → onItemClick fires → push your own chat screen with the selected group"
},
"types": {
"Group": {
@@ -165,7 +165,7 @@ class GroupsViewController: UIViewController {
}
private func openGroupChat(_ group: Group) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(group: group)
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -238,7 +238,7 @@ let groups = CometChatGroups()
groups.set(onItemClick: { [weak self] group, indexPath in
guard let self = self else { return }
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(group: group)
self.navigationController?.pushViewController(messagesVC, animated: true)
})
@@ -297,9 +297,9 @@ import CometChatSDK
let groups = CometChatGroups()
groups.selectionMode = .multiple
-groups.set(onSelection: { [weak self] selectedGroups in
+groups.onSelectedItemProceed = { [weak self] selectedGroups in
print("Selected \(selectedGroups.count) groups")
-})
+}
```
#### onSelectedItemProceed
@@ -377,7 +377,7 @@ groups.set(onLoad: { groups in
| `set(onItemClick:)` | Triggered when a group is tapped | Open group chat |
| `set(onItemLongClick:)` | Triggered on long press | Show options menu |
| `set(onBack:)` | Triggered when back button is pressed | Custom navigation |
-| `set(onSelection:)` | Triggered in selection mode | Multi-select groups |
+| `onSelectedItemProceed` | Fires when the user confirms a multi-selection | Multi-select groups |
| `onSelectedItemProceed` | Triggered when selection is confirmed | Process selected groups |
| `set(onError:)` | Triggered when an error occurs | Show error alert |
| `set(onEmpty:)` | Triggered when list is empty | Show empty state |
@@ -751,7 +751,7 @@ import CometChatSDK
let groups = CometChatGroups()
-groups.set(subtitleView: { group in
+groups.set(subtitle: { group in
let view = CustomSubtitleView(membersCount: group.membersCount)
return view
})
@@ -793,7 +793,7 @@ import CometChatSDK
let groups = CometChatGroups()
-groups.set(trailView: { group in
+groups.set(trailingView: { group in
let view = CustomTrailView()
return view
})
@@ -1115,7 +1115,7 @@ avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
avatarStyle.borderWidth = 1
avatarStyle.borderColor = UIColor.systemGray4
-groups.set(avatarStyle: avatarStyle)
+groups.avatarStyle = avatarStyle
```
### groupsRequestBuilder
@@ -1276,7 +1276,7 @@ statusIndicatorStyle.backgroundColor = UIColor.systemGreen
statusIndicatorStyle.borderWidth = 2
statusIndicatorStyle.borderColor = UIColor.white
-groups.set(statusIndicatorStyle: statusIndicatorStyle)
+groups.statusIndicatorStyle = statusIndicatorStyle
```
---
@@ -1319,19 +1319,19 @@ groups.set(groupsRequestBuilder: joinedBuilder)
```swift lines
let groups = CometChatGroups()
-groups.set(emptyStateView: {
- let emptyView = UIView()
-
- let label = UILabel()
- label.text = "No groups found"
- label.textAlignment = .center
-
- let button = UIButton(type: .system)
- button.setTitle("Create a group", for: .normal)
-
- // Add subviews and constraints...
- return emptyView
-})
+// emptyStateView is a UIView you assign (inherited from CometChatListBase).
+let emptyView = UIView()
+
+let label = UILabel()
+label.text = "No groups found"
+label.textAlignment = .center
+
+let button = UIButton(type: .system)
+button.setTitle("Create a group", for: .normal)
+
+// Add subviews and constraints...
+
+groups.emptyStateView = emptyView // or: groups.set(emptyView: emptyView)
```
### Hide all chrome — minimal list
@@ -1349,7 +1349,7 @@ groups.hideSectionHeader = true
let groups = CometChatGroups()
groups.selectionMode = .multiple
-groups.set(onSelection: { selectedGroups in
+groups.onSelectedItemProceed = { selectedGroups in
print("Selected \(selectedGroups.count) groups")
})
```
diff --git a/ui-kit/ios/guide-ai-agent.mdx b/ui-kit/ios/guide-ai-agent.mdx
index abfb9c12d..e4945490f 100644
--- a/ui-kit/ios/guide-ai-agent.mdx
+++ b/ui-kit/ios/guide-ai-agent.mdx
@@ -187,7 +187,7 @@ class ProductionAIAgentViewController: UIViewController {
// If resuming from history, set parent message
if let parentMessage = parentMessage {
- messageList.set(parentMessage: parentMessage)
+ messageList.set(parentMessageId: parentMessage.id)
}
view.addSubview(messageList)
@@ -205,7 +205,7 @@ class ProductionAIAgentViewController: UIViewController {
// If resuming from history, set parent message
if let parentMessage = parentMessage {
- messageComposer.set(parentMessage: parentMessage)
+ messageComposer.set(parentMessageId: parentMessage.id)
}
view.addSubview(messageComposer)
@@ -308,7 +308,7 @@ class ChatListViewController: UIViewController {
self?.navigationController?.pushViewController(aiChatVC, animated: true)
} else {
// Regular user chat
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: user)
self?.navigationController?.pushViewController(messages, animated: true)
}
@@ -326,7 +326,7 @@ class ChatListViewController: UIViewController {
let aiChatVC = ProductionAIAgentViewController(user: user)
navigationController?.pushViewController(aiChatVC, animated: true)
} else {
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: user)
navigationController?.pushViewController(messages, animated: true)
}
@@ -405,7 +405,7 @@ label.textAlignment = .center
label.textColor = .secondaryLabel
emptyView.addSubview(label)
-messageList.set(emptyStateView: emptyView)
+messageList.emptyStateView = emptyView
```
### Streaming Speed
diff --git a/ui-kit/ios/guide-block-unblock-user.mdx b/ui-kit/ios/guide-block-unblock-user.mdx
index 191856c88..f59a01c68 100644
--- a/ui-kit/ios/guide-block-unblock-user.mdx
+++ b/ui-kit/ios/guide-block-unblock-user.mdx
@@ -54,7 +54,7 @@ class UserDetailsViewController: UIViewController {
// Avatar
let avatar = CometChatAvatar()
- avatar.set(user: user)
+ avatar.setAvatar(avatarUrl: user.avatar, with: user.name)
avatar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(avatar)
@@ -113,7 +113,7 @@ class UserDetailsViewController: UIViewController {
@objc private func openChat() {
guard let user = user else { return }
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: user)
navigationController?.pushViewController(messages, animated: true)
}
@@ -314,7 +314,7 @@ class ProductionUserDetailsViewController: UIViewController {
private func configureWithUser() {
guard let user = user else { return }
- avatar.set(user: user)
+ avatar.setAvatar(avatarUrl: user.avatar, with: user.name)
nameLabel.text = user.name
updateStatusLabel(user: user)
}
@@ -362,7 +362,7 @@ class ProductionUserDetailsViewController: UIViewController {
return
}
- let messages = CometChatMessages()
+ let messages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messages.set(user: user)
navigationController?.pushViewController(messages, animated: true)
}
@@ -657,7 +657,7 @@ avatar.set(style: avatarStyle)
| Component | Purpose |
|-----------|---------|
| `CometChatAvatar` | Display user profile picture |
-| `CometChatMessages` | Open chat interface |
+| your own chat screen | Open chat interface |
| `CometChat.blockUsers()` | Block users |
| `CometChat.unblockUsers()` | Unblock users |
| `CometChat.deleteConversation()` | Delete chat history |
diff --git a/ui-kit/ios/guide-group-chat.mdx b/ui-kit/ios/guide-group-chat.mdx
index 71f857fcd..68282b75c 100644
--- a/ui-kit/ios/guide-group-chat.mdx
+++ b/ui-kit/ios/guide-group-chat.mdx
@@ -31,7 +31,7 @@ Before implementing group details, ensure you have:
|-----------|-------------|
| `CometChatGroup` | Renders group avatar, name, and metadata |
| `GroupActionView` | Custom view for action buttons (view/add/banned members) |
-| `CometChatMessagesViewController` | Opens group chat interface when "Chat" is tapped |
+| your own chat screen | Opens group chat interface when "Chat" is tapped |
| `CometChat.joinGroup()` | Joins public or password-protected groups |
| `CometChat.leaveGroup()` | Leaves the current group |
| `CometChat.deleteGroup()` | Deletes and exits the group (owners only) |
diff --git a/ui-kit/ios/guide-message-privately.mdx b/ui-kit/ios/guide-message-privately.mdx
index c9aec2254..664e3c21f 100644
--- a/ui-kit/ios/guide-message-privately.mdx
+++ b/ui-kit/ios/guide-message-privately.mdx
@@ -26,10 +26,10 @@ Before implementing this feature, ensure you have:
| `CometChatMessageOption` | Defines the **Message Privately** option in the context menu |
| `MessageDataSource` | Supplies the `messagePrivatelyOption` in the options array |
| `CometChatMessageListViewModel` | Manages UI state, including `hideMessagePrivatelyOption` |
-| `CometChatMessages` | Entry point for rendering or pushing the private chat interface |
+| your own chat screen | Entry point for rendering or pushing the private chat interface |
| `CometChat.getUser(UID:onSuccess:onError:)` | Retrieves the `User` object for the selected message sender |
| `CometChatUIEvents.openChat(user:group:)` | Opens the chat interface for a user or group |
-| `UIViewController` (Navigation) | Pushes or presents the private chat screen (`CometChatMessages`) |
+| `UIViewController` (Navigation) | Pushes or presents your own private chat screen |
## Integration Steps
@@ -82,7 +82,7 @@ func startPrivateChatManual(with selectedMessage: BaseMessage) {
DispatchQueue.main.async {
// Navigate to the private chat screen
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: user)
self?.navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -105,7 +105,7 @@ This automates the transition from group context to private conversation.
| 3 | User taps **Message Privately** |
| 4 | App gets `User` from `message.sender` |
| 5 | Opens chat via `CometChatUIEvents.openChat(user:group:)` |
-| 6 | Pushes `CometChatMessages` onto the navigation stack |
+| 6 | Pushes your own chat screen onto the navigation stack |
## Customization Options
diff --git a/ui-kit/ios/message-header.mdx b/ui-kit/ios/message-header.mdx
index fa64f531b..04cd482f4 100644
--- a/ui-kit/ios/message-header.mdx
+++ b/ui-kit/ios/message-header.mdx
@@ -37,8 +37,8 @@ The `CometChatMessageHeader` component displays user or group details in the too
"callbacks": {
"onBack": "() -> Void",
"onError": "(CometChatException) -> Void",
- "onAiChatHistoryClicked": "() -> Void",
- "onAiNewChatClicked": "() -> Void"
+ "onAiChatHistoryClicked": "(User) -> Void (assignable property)",
+ "onAiNewChatClicked": "(User) -> Void (assignable property)"
},
"visibility": {
"hideBackButton": { "type": "Bool", "default": false },
@@ -71,7 +71,7 @@ The `CometChatMessageHeader` component displays user or group details in the too
"disconnect()": "Disconnects WebSocket connection"
},
"menuCustomization": {
- "set(options:)": "((User?, Group?) -> [CometChatMessageHeaderOption])? - Sets custom menu options"
+ "set(options:)": "[CometChatPopupMenu.MenuItem]? - Sets custom menu options"
}
},
"events": [],
@@ -82,7 +82,7 @@ The `CometChatMessageHeader` component displays user or group details in the too
"onTypingEnded"
],
"compositionExample": {
- "description": "MessageHeader is typically used within CometChatMessages at the top of the chat screen",
+ "description": "MessageHeader is typically used at the top of your own chat screen",
"components": ["CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
"flow": "User views header → sees recipient info → taps back to return to conversations"
},
@@ -101,7 +101,7 @@ The `CometChatMessageHeader` component displays user or group details in the too
## Where It Fits
-`CometChatMessageHeader` displays the recipient's information at the top of the chat screen. It's typically used within `CometChatMessages` alongside `CometChatMessageList` and `CometChatMessageComposer`.
+`CometChatMessageHeader` displays the recipient's information at the top of the chat screen. It's typically used in your own chat screen alongside `CometChatMessageList` and `CometChatMessageComposer`.
```swift lines
import UIKit
@@ -782,12 +782,12 @@ Sets custom menu options for the message header. These options appear in the hea
```swift lines
@discardableResult
-public func set(options: ((_ user: User?, _ group: Group?) -> [CometChatMessageHeaderOption])?) -> Self
+public func set(options: [CometChatPopupMenu.MenuItem]?) -> CometChatMessageHeader
```
| Parameter | Type | Description |
|-----------|------|-------------|
-| `options` | `((User?, Group?) -> [CometChatMessageHeaderOption])?` | Closure that returns an array of menu options based on the current user or group |
+| `options` | `[CometChatPopupMenu.MenuItem]?` | The menu items shown in the header overflow menu |
```swift lines
import CometChatUIKitSwift
@@ -796,30 +796,22 @@ import CometChatSDK
let messageHeader = CometChatMessageHeader()
messageHeader.set(options: { user, group in
- var options = [CometChatMessageHeaderOption]()
-
- // Add a custom "View Profile" option
- let viewProfileOption = CometChatMessageHeaderOption(
- id: "view_profile",
+ // set(options:) takes [CometChatPopupMenu.MenuItem] — init is (title:icon:action:)
+ var options = [CometChatPopupMenu.MenuItem]()
+
+ let viewProfileOption = CometChatPopupMenu.MenuItem(
title: "View Profile",
- icon: UIImage(systemName: "person.circle")
- ) { user, group in
- // Handle view profile action
- print("View profile tapped")
- }
- options.append(viewProfileOption)
-
- // Add a custom "Mute Notifications" option
- let muteOption = CometChatMessageHeaderOption(
- id: "mute_notifications",
+ icon: UIImage(systemName: "person.circle") ?? UIImage(),
+ action: { [weak self] in self?.showProfile() }
+ )
+
+ let muteOption = CometChatPopupMenu.MenuItem(
title: "Mute Notifications",
- icon: UIImage(systemName: "bell.slash")
- ) { user, group in
- // Handle mute action
- print("Mute notifications tapped")
- }
- options.append(muteOption)
-
+ icon: UIImage(systemName: "bell.slash") ?? UIImage(),
+ action: { [weak self] in self?.toggleMute() }
+ )
+
+ options.append(contentsOf: [viewProfileOption, muteOption])
return options
})
```
@@ -850,7 +842,7 @@ avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 20)
avatarStyle.borderWidth = 2
avatarStyle.borderColor = UIColor.white
-messageHeader.set(avatarStyle: avatarStyle)
+messageHeader.avatarStyle = avatarStyle
```
### dateTimeFormatter
@@ -973,7 +965,7 @@ import CometChatUIKitSwift
let messageHeader = CometChatMessageHeader()
-messageHeader.set(onAiChatHistoryClicked: { [weak self] in
+messageHeader.onAiChatHistoryClicked = { [weak self] user in
// Handle AI chat history button click
self?.presentAiChatHistory()
})
@@ -993,7 +985,7 @@ import CometChatUIKitSwift
let messageHeader = CometChatMessageHeader()
-messageHeader.set(onAiNewChatClicked: { [weak self] in
+messageHeader.onAiNewChatClicked = { [weak self] user in
// Handle AI new chat button click
self?.startNewAiChat()
})
@@ -1019,7 +1011,7 @@ statusIndicatorStyle.borderWidth = 2
statusIndicatorStyle.borderColor = UIColor.white
statusIndicatorStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 6)
-messageHeader.set(statusIndicatorStyle: statusIndicatorStyle)
+messageHeader.statusIndicatorStyle = statusIndicatorStyle
```
### typingIndicatorStyle
@@ -1040,7 +1032,7 @@ let typingIndicatorStyle = TypingIndicatorStyle()
typingIndicatorStyle.textColor = UIColor.systemGray
typingIndicatorStyle.textFont = UIFont.italicSystemFont(ofSize: 13)
-messageHeader.set(typingIndicatorStyle: typingIndicatorStyle)
+messageHeader.typingIndicatorStyle = typingIndicatorStyle
```
---
diff --git a/ui-kit/ios/message-list.mdx b/ui-kit/ios/message-list.mdx
index 16ec1009b..a48dbf8e2 100644
--- a/ui-kit/ios/message-list.mdx
+++ b/ui-kit/ios/message-list.mdx
@@ -97,7 +97,7 @@ The `CometChatMessageList` component displays a scrollable list of messages in a
"onMessageReactionRemoved"
],
"compositionExample": {
- "description": "MessageList is typically used within CometChatMessages alongside MessageHeader and MessageComposer",
+ "description": "MessageList is typically used in your own chat screen alongside MessageHeader and MessageComposer",
"components": ["CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
"flow": "User views messages → types in composer → sends message → MessageList updates"
},
@@ -129,7 +129,7 @@ The `CometChatMessageList` component displays a scrollable list of messages in a
## Where It Fits
-`CometChatMessageList` is the core component for displaying messages in a chat. It's typically used within `CometChatMessages` alongside `CometChatMessageHeader` and `CometChatMessageComposer`.
+`CometChatMessageList` is the core component for displaying messages in a chat. It's typically used in your own chat screen alongside `CometChatMessageHeader` and `CometChatMessageComposer`.
```swift lines
import UIKit
@@ -166,7 +166,7 @@ class ChatViewController: UIViewController {
}
private func openThreadView(for message: BaseMessage) {
- let threadMessages = CometChatMessages()
+ let threadMessages = MessagesVC() // your own VC — see /ui-kit/ios/guide-threaded-messages
threadMessages.set(user: message.sender as? User)
threadMessages.set(parentMessage: message)
navigationController?.pushViewController(threadMessages, animated: true)
@@ -271,7 +271,7 @@ let messageList = CometChatMessageList()
messageList.set(onThreadRepliesClick: { [weak self] message, template in
guard let self = self else { return }
- let threadMessages = CometChatMessages()
+ let threadMessages = MessagesVC() // your own VC — see /ui-kit/ios/guide-threaded-messages
if let user = message.sender as? User {
threadMessages.set(user: user)
}
@@ -791,7 +791,7 @@ import CometChatSDK
let myCustomTextFormatter = MyCustomTextFormatter(trackingCharacter: "#")
-let cometChatMessages = CometChatMessages()
+let cometChatMessages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
.set(user: user)
.set(textFormatter: [myCustomTextFormatter])
```
@@ -2078,13 +2078,13 @@ messageList.disableSoundForMessages = true
let messageList = CometChatMessageList()
messageList.set(user: user)
-messageList.set(emptyStateView: {
- let label = UILabel()
- label.text = "Start a conversation!"
- label.textAlignment = .center
- label.textColor = .secondaryLabel
- return label
-})
+// emptyStateView is a UIView you assign — build it first.
+let label = UILabel()
+label.text = "Start a conversation!"
+label.textAlignment = .center
+label.textColor = .secondaryLabel
+
+messageList.emptyStateView = label // or: messageList.set(emptyView: label)
```
### Scroll to bottom on new messages
diff --git a/ui-kit/ios/message-template.mdx b/ui-kit/ios/message-template.mdx
index 6fff04600..d6c415f40 100644
--- a/ui-kit/ios/message-template.mdx
+++ b/ui-kit/ios/message-template.mdx
@@ -248,8 +248,8 @@ let messageTemplates: CometChatMessageTemplate = CometChatUIKit.getDataSource().
let messageListConfiguration = MessageListConfiguration()
.set(templates: [messageTemplates])
-// Apply to CometChatMessages
-let cometChatMessages = CometChatMessages()
+// Apply to your chat screen's CometChatMessageList
+let cometChatMessages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
.set(user: user)
.set(messageListConfiguration: messageListConfiguration)
```
@@ -816,7 +816,7 @@ for (index, template) in allTemplates.enumerated() {
allTemplates[index] = template
}
-let cometChatMessages = CometChatMessages()
+let cometChatMessages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
cometChatMessages.set(templates: allTemplates)
```
@@ -992,7 +992,7 @@ for (index, template) in allTemplates.enumerated() {
allTemplates[index] = template
}
-let cometChatMessages = CometChatMessages()
+let cometChatMessages = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
cometChatMessages.set(templates: allTemplates)
```
diff --git a/ui-kit/ios/ongoing-call.mdx b/ui-kit/ios/ongoing-call.mdx
index 0ce807c5e..bdabb6076 100644
--- a/ui-kit/ios/ongoing-call.mdx
+++ b/ui-kit/ios/ongoing-call.mdx
@@ -65,7 +65,7 @@ The `CometChatOngoingCall` component provides users with a dedicated interface f
let sessionID = "your_session_id"
let cometChatOngoingCall = CometChatOngoingCall()
-cometChatOngoingCall.set(sessionID: sessionID)
+cometChatOngoingCall.set(sessionId: sessionID)
cometChatOngoingCall.modalPresentationStyle = .fullScreen
self.present(cometChatOngoingCall, animated: true)
```
diff --git a/ui-kit/ios/search.mdx b/ui-kit/ios/search.mdx
index d2c182ff6..abad28b51 100644
--- a/ui-kit/ios/search.mdx
+++ b/ui-kit/ios/search.mdx
@@ -26,22 +26,16 @@ The `CometChatSearch` component is a powerful and customizable search interface
"data": {
"user": { "type": "User?", "default": "nil", "note": "Limits search to specific user" },
"group": { "type": "Group?", "default": "nil", "note": "Limits search to specific group" },
- "conversationsRequestBuilder": { "type": "ConversationsRequest.ConversationsRequestBuilder", "default": "SDK default" },
- "messagesRequestBuilder": { "type": "MessagesRequest.MessageRequestBuilder", "default": "SDK default" }
+ "note": "No request builder. Scope results with set(searchIn:) and set(searchFilters:initialFilter:); scope to one conversation with user/group above."
},
"callbacks": {
- "onConversationClicked": "(Conversation, IndexPath) -> Void",
- "onMessageClicked": "(BaseMessage) -> Void",
- "onBack": "() -> Void",
- "onError": "(CometChatException) -> Void",
- "onEmpty": "() -> Void"
+ "onConversationClicked": "(Conversation, IndexPath) -> Void (assignable property)",
+ "onMessageClicked": "(BaseMessage) -> Void (assignable property)",
+ "note": "No onBack / onError / onEmpty. Failures and empty results are VIEWS: set(errorView:), set(emptyView:), plus errorStateTitleText / errorStateSubTitleText."
},
"visibility": {
- "hideNavigationBar": { "type": "Bool", "default": false },
- "hideBackButton": { "type": "Bool", "default": false },
"hideUserStatus": { "type": "Bool", "default": false },
- "hideGroupType": { "type": "Bool", "default": false },
- "hideReceipts": { "type": "Bool", "default": false }
+ "hideGroupType": { "type": "Bool", "default": false }
},
"search": {
"searchFilters": { "type": "[SearchFilter]", "default": "All available filters" },
@@ -54,12 +48,12 @@ The `CometChatSearch` component is a powerful and customizable search interface
"titleViewForConversation": "(Conversation) -> UIView",
"subtitleViewForConversation": "(Conversation) -> UIView",
"tailViewForConversation": "(Conversation) -> UIView",
- "listItemViewForMessage": "(BaseMessage) -> UIView",
- "leadingViewForMessage": "(BaseMessage) -> UIView",
- "titleViewForMessage": "(BaseMessage) -> UIView",
- "subtitleViewForMessage": "(BaseMessage) -> UIView",
- "trailingViewForMessage": "(BaseMessage) -> UIView",
- "initialView": "UIView",
+ "listItemViewForMessage": "(BaseMessage) -> UIView (whole row — the ONLY message-level slot)",
+ "listItemViewForImage": "(MediaMessage) -> UIView",
+ "listItemViewForVideo": "(MediaMessage) -> UIView",
+ "listItemViewForAudio": "(MediaMessage) -> UIView",
+ "listItemViewForDocument": "(MediaMessage) -> UIView",
+ "listItemViewForLink": "(MediaMessage) -> UIView",
"loadingView": "UIView",
"emptyView": "UIView",
"errorView": "UIView"
@@ -69,7 +63,7 @@ The `CometChatSearch` component is a powerful and customizable search interface
"sdkListeners": [],
"compositionExample": {
"description": "Search is typically accessed from conversation list or message header",
- "components": ["CometChatConversations", "CometChatSearch", "CometChatMessages"],
+ "components": ["CometChatConversations", "CometChatSearch", "CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
"flow": "User taps search → enters query → taps result → navigates to conversation/message"
}
}
@@ -164,7 +158,7 @@ search.onBack = {
---
-#### 4. onError
+#### 4. Error state
Listens for any errors that occur in the Search component. This action doesn't change the component's behavior.
@@ -174,9 +168,13 @@ Listens for any errors that occur in the Search component. This action doesn't c
import CometChatUIKitSwift
let search = CometChatSearch()
-search.set(onError: { error in
- print("Search error:", error.localizedDescription)
-})
+
+// CometChatSearch surfaces failures as an error STATE, not an onError callback.
+// Supply your own view, or retitle the built-in one.
+search.set(errorView: myErrorView)
+
+search.errorStateTitleText = "Couldn't search"
+search.errorStateSubTitleText = "Check your connection and try again"
```
@@ -185,7 +183,7 @@ search.set(onError: { error in
#### 5. onEmpty
-Listens for the empty state of the Search component. This action doesn't change the component's behavior.
+The empty state is a **view you supply**, not a callback — assign it with `set(emptyView:)`.
@@ -193,9 +191,13 @@ Listens for the empty state of the Search component. This action doesn't change
import CometChatUIKitSwift
let search = CometChatSearch()
-search.set(onEmpty: {
- print("No results found")
-})
+
+let emptyView = UILabel()
+emptyView.text = "No results found"
+emptyView.textAlignment = .center
+emptyView.textColor = .secondaryLabel
+
+search.set(emptyView: emptyView)
```
@@ -252,7 +254,8 @@ search.set(searchFilters: [.unread, .groups, .photos, .videos], initialFilter: .
#### 1. ConversationsRequestBuilder
-Set the `ConversationsRequestBuilder` in the Search Component to filter the search results. For more options, refer to [ConversationRequestBuilder](/sdk/ios/retrieve-conversations).
+`CometChatSearch` does not take a request builder. Narrow the search with `set(searchIn:)` (which
+result types to return) and `set(searchFilters:initialFilter:)` (which filter chips to offer).
@@ -260,11 +263,13 @@ Set the `ConversationsRequestBuilder` in the Search Component to filter the sear
import CometChatUIKitSwift
import CometChatSDK
-let convBuilder = ConversationsRequest.ConversationsRequestBuilder()
- .set(limit: 20)
-
let search = CometChatSearch()
-search.set(conversationsRequestBuilder: convBuilder)
+
+// Conversations only
+search.set(searchIn: [.conversations])
+
+// Offer conversation-relevant filter chips, opening on "Unread"
+search.set(searchFilters: [.conversations, .unread, .groups], initialFilter: .unread)
```
@@ -273,7 +278,8 @@ search.set(conversationsRequestBuilder: convBuilder)
#### 2. MessagesRequestBuilder
-Set the `MessagesRequestBuilder` in the Search Component to filter the search results. For more options, refer to [MessagesRequestBuilder](/sdk/ios/additional-message-filtering).
+There is no `MessagesRequestBuilder` on `CometChatSearch` either. Restrict to messages with
+`set(searchIn:)`, and offer message-type filter chips with `set(searchFilters:initialFilter:)`.
@@ -281,12 +287,13 @@ Set the `MessagesRequestBuilder` in the Search Component to filter the search re
import CometChatUIKitSwift
import CometChatSDK
-let msgBuilder = MessagesRequest.MessageRequestBuilder()
- .set(limit: 30)
- .hide(deletedMessages: true)
-
let search = CometChatSearch()
-search.set(messagesRequestBuilder: msgBuilder)
+
+// Messages only
+search.set(searchIn: [.messages])
+
+// Message-type filter chips
+search.set(searchFilters: [.messages, .photos, .videos, .audio, .documents, .links])
```
@@ -360,7 +367,6 @@ These are small functional customizations that allow you to fine-tune the overal
| loadingView | Custom loader view | `search.set(loadingView: spinner)` |
| emptyView | Custom empty result view | `search.set(emptyView: emptyView)` |
| errorView | Custom error UI | `search.set(errorView: errorView)` |
-| initialView | Custom view before search query is entered | `search.set(initialView: initialView)` |
| disableTyping | Disable typing indicators | `search.disableTyping = true` |
| disableSoundForMessages | Disable message sounds | `search.disableSoundForMessages = true` |
| customSoundForMessages | Custom sound URL for messages | `search.customSoundForMessages = URL(string: "...")` |
@@ -399,7 +405,7 @@ searchVC.set(listItemViewForConversation: { conversation in
#### Message View Customization
-With message item view functions, you can assign custom views to different types of messages in the search result. For more information, refer to the [itemView](/ui-kit/ios/message-list#itemview) prop of the `CometChatMessages` component.
+With message item view functions, you can assign custom views to different types of messages in the search result. For more information, refer to the [itemView](/ui-kit/ios/message-list#itemview) prop of the `CometChatMessageList` component.
Here's how you can override the default message item view with a custom one for text messages:
@@ -589,16 +595,18 @@ searchVC.set(listItemViewForLink: { mediaMessage in
-#### Message Granular View Customization
+#### Granular View Customization
-For more granular control over message search results, you can customize individual parts of the message item:
+Granular per-part slots exist for **conversation** rows only, and they are assignable
+properties rather than `set(...)` methods. For **message** rows the component exposes a single
+whole-row slot, `set(listItemViewForMessage:)` (above).
-| Function | Description |
-|-----------------------------|----------------------------------------------------------|
-| leadingViewForMessage | Replaces the message avatar / left section |
-| titleViewForMessage | Replaces the message title text |
-| subtitleViewForMessage | Replaces the message subtitle text |
-| trailingViewForMessage | Replaces the message trailing section |
+| Property | Applies to | Description |
+|------------------------------|--------------|--------------------------------------------|
+| `leadingViewForConversation` | conversation | Replaces the avatar / leading section |
+| `titleViewForConversation` | conversation | Replaces the title text |
+| `subtitleViewForConversation`| conversation | Replaces the subtitle text |
+| `tailViewForConversation` | conversation | Replaces the trailing section |
@@ -607,94 +615,38 @@ import CometChatUIKitSwift
let searchVC = CometChatSearch()
-// Custom leading view for messages (avatar area)
-searchVC.set(leadingViewForMessage: { message in
+// Granular slots apply to CONVERSATION rows and are assigned, not set(...)
+searchVC.leadingViewForConversation = { conversation in
let customView = UIView()
customView.backgroundColor = .systemPurple
customView.layer.cornerRadius = 24
- // Configure custom leading view
return customView
-})
+}
-// Custom title view for messages
-searchVC.set(titleViewForMessage: { message in
+searchVC.titleViewForConversation = { conversation in
let label = UILabel()
- label.text = message.sender?.name ?? "Unknown"
+ label.text = (conversation.conversationWith as? User)?.name
+ ?? (conversation.conversationWith as? Group)?.name
label.font = .boldSystemFont(ofSize: 16)
return label
-})
+}
-// Custom subtitle view for messages
-searchVC.set(subtitleViewForMessage: { message in
+searchVC.subtitleViewForConversation = { conversation in
let label = UILabel()
- if let textMessage = message as? TextMessage {
- label.text = textMessage.text
- } else {
- label.text = message.type
- }
+ label.text = (conversation.lastMessage as? TextMessage)?.text
label.textColor = .secondaryLabel
return label
-})
+}
-// Custom trailing view for messages
-searchVC.set(trailingViewForMessage: { message in
+searchVC.tailViewForConversation = { conversation in
let label = UILabel()
- let date = Date(timeIntervalSince1970: TimeInterval(message.sentAt))
- let formatter = DateFormatter()
- formatter.dateFormat = "HH:mm"
- label.text = formatter.string(from: date)
- label.font = .systemFont(ofSize: 12)
- label.textColor = .tertiaryLabel
+ label.text = "\(conversation.unreadMessageCount)"
return label
-})
-```
-
-
-
-#### Initial View
-
-Customize the view displayed before the user enters a search query using the `initialView` property.
-
-
-
-```swift lines
-import CometChatUIKitSwift
-
-let searchVC = CometChatSearch()
-
-// Create a custom initial view
-let initialView = UIView()
-let imageView = UIImageView(image: UIImage(systemName: "magnifyingglass"))
-imageView.tintColor = .systemGray
-imageView.contentMode = .scaleAspectFit
-imageView.translatesAutoresizingMaskIntoConstraints = false
-
-let label = UILabel()
-label.text = "Search for conversations and messages"
-label.textColor = .secondaryLabel
-label.textAlignment = .center
-label.translatesAutoresizingMaskIntoConstraints = false
-
-initialView.addSubview(imageView)
-initialView.addSubview(label)
-
-NSLayoutConstraint.activate([
- imageView.centerXAnchor.constraint(equalTo: initialView.centerXAnchor),
- imageView.centerYAnchor.constraint(equalTo: initialView.centerYAnchor, constant: -20),
- imageView.widthAnchor.constraint(equalToConstant: 60),
- imageView.heightAnchor.constraint(equalToConstant: 60),
- label.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 16),
- label.leadingAnchor.constraint(equalTo: initialView.leadingAnchor, constant: 20),
- label.trailingAnchor.constraint(equalTo: initialView.trailingAnchor, constant: -20)
-])
-
-searchVC.set(initialView: initialView)
+}
```
----
-
#### Mention Configuration
Configure how @all mentions appear in search results using the `setMentionAllLabel` method.
@@ -767,7 +719,7 @@ Open the search screen from a conversations list:
searchVC.onConversationClicked = { [weak self] conversation, indexPath in
// Navigate to messages for the selected conversation
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
if let user = conversation.conversationWith as? User {
messagesVC.user = user
} else if let group = conversation.conversationWith as? Group {
@@ -778,7 +730,7 @@ Open the search screen from a conversations list:
searchVC.onMessageClicked = { [weak self] message in
// Navigate to the message in context
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
if let user = message.sender {
messagesVC.user = user
}
@@ -823,12 +775,8 @@ let searchVC = CometChatSearch()
// Set available filters with photos as the initial selection
searchVC.set(searchFilters: [.photos, .videos, .documents, .audio], initialFilter: .photos)
-// Or programmatically filter messages
-let msgBuilder = MessagesRequest.MessageRequestBuilder()
- .set(categories: ["message"])
- .set(types: ["image", "video"])
-
-searchVC.set(messagesRequestBuilder: msgBuilder)
+// Or restrict which result types are searched at all
+searchVC.set(searchIn: [.messages])
```
diff --git a/ui-kit/ios/shortcut-formatter-guide.mdx b/ui-kit/ios/shortcut-formatter-guide.mdx
index c9797c250..59ca9c05e 100644
--- a/ui-kit/ios/shortcut-formatter-guide.mdx
+++ b/ui-kit/ios/shortcut-formatter-guide.mdx
@@ -270,7 +270,7 @@ cometChatMessageComposer.set(textFormatter: [shortcutFormatter])
-Ensure to pass and present `cometChatConversationsWithMessages`. If a navigation controller is already in use, utilize the `pushViewController` function instead of directly presenting the view controller.
+Ensure to pass and present your own chat list controller. If a navigation controller is already in use, utilize the `pushViewController` function instead of directly presenting the view controller.
---
diff --git a/ui-kit/ios/threaded-messages-header.mdx b/ui-kit/ios/threaded-messages-header.mdx
index 6dbdac5c1..04f8f51d8 100644
--- a/ui-kit/ios/threaded-messages-header.mdx
+++ b/ui-kit/ios/threaded-messages-header.mdx
@@ -351,7 +351,7 @@ func openThread(for parentMessage: BaseMessage) {
if let user = parentMessage.sender {
messageList.set(user: user)
}
- messageList.set(parentMessage: parentMessage)
+ messageList.set(parentMessageId: parentMessage.id)
messageList.set(controller: threadVC)
messageList.translatesAutoresizingMaskIntoConstraints = false
@@ -360,7 +360,7 @@ func openThread(for parentMessage: BaseMessage) {
if let user = parentMessage.sender {
composer.set(user: user)
}
- composer.set(parentMessage: parentMessage)
+ composer.set(parentMessageId: parentMessage.id)
composer.set(controller: threadVC)
composer.translatesAutoresizingMaskIntoConstraints = false
diff --git a/ui-kit/ios/users.mdx b/ui-kit/ios/users.mdx
index 09e5103fb..d242f0bee 100644
--- a/ui-kit/ios/users.mdx
+++ b/ui-kit/ios/users.mdx
@@ -103,8 +103,8 @@ The `CometChatUsers` component displays a searchable list of all available users
],
"compositionExample": {
"description": "Users list for starting new conversations",
- "components": ["CometChatUsers", "CometChatMessages"],
- "flow": "User taps on a user → onItemClick fires → Navigate to CometChatMessages with selected user"
+ "components": ["CometChatUsers", "CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
+ "flow": "User taps on a user → onItemClick fires → push your own chat screen with the selected user"
},
"types": {
"User": {
@@ -160,7 +160,7 @@ class UsersViewController: UIViewController {
}
private func startConversation(with user: User) {
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: user)
navigationController?.pushViewController(messagesVC, animated: true)
}
@@ -236,7 +236,7 @@ let users = CometChatUsers()
users.set(onItemClick: { [weak self] user, indexPath in
guard let self = self else { return }
- let messagesVC = CometChatMessages()
+ let messagesVC = MessagesVC() // your own VC — see /ui-kit/ios/ios-conversation
messagesVC.set(user: user)
self.navigationController?.pushViewController(messagesVC, animated: true)
})
@@ -622,7 +622,7 @@ import CometChatSDK
let users = CometChatUsers()
-users.set(subtitleView: { user in
+users.set(subtitle: { user in
let view = CustomSubtitleView(lastActiveDate: "2 hours ago")
return view
})
@@ -664,7 +664,7 @@ import CometChatSDK
let users = CometChatUsers()
-users.set(trailView: { user in
+users.set(trailingView: { user in
let view = CustomTrailView()
return view
})
@@ -1165,7 +1165,7 @@ avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
avatarStyle.borderWidth = 1
avatarStyle.borderColor = UIColor.systemGray4
-users.set(avatarStyle: avatarStyle)
+users.avatarStyle = avatarStyle
```
### hideBackButton
@@ -1333,7 +1333,7 @@ statusIndicatorStyle.backgroundColor = UIColor.systemGreen
statusIndicatorStyle.borderWidth = 2
statusIndicatorStyle.borderColor = UIColor.white
-users.set(statusIndicatorStyle: statusIndicatorStyle)
+users.statusIndicatorStyle = statusIndicatorStyle
```
### usersRequestBuilder
@@ -1365,7 +1365,7 @@ let friendsBuilder = UsersRequest.UsersRequestBuilder(limit: 30)
.friendsOnly(true)
let users = CometChatUsers()
-users.set(usersRequestBuilder: friendsBuilder)
+users.set(userRequestBuilder: friendsBuilder)
```
### Online users only
@@ -1375,7 +1375,7 @@ let onlineBuilder = UsersRequest.UsersRequestBuilder(limit: 30)
.set(status: .online)
let users = CometChatUsers()
-users.set(usersRequestBuilder: onlineBuilder)
+users.set(userRequestBuilder: onlineBuilder)
```
### Custom empty state with CTA
@@ -1383,20 +1383,21 @@ users.set(usersRequestBuilder: onlineBuilder)
```swift lines
let users = CometChatUsers()
-users.set(emptyStateView: {
- let emptyView = UIView()
-
- let label = UILabel()
- label.text = "No users found"
- label.textAlignment = .center
- label.textColor = .secondaryLabel
-
- let button = UIButton(type: .system)
- button.setTitle("Invite friends", for: .normal)
-
- // Add subviews and constraints...
- return emptyView
-})
+// emptyStateView is a UIView you assign (inherited from CometChatListBase) —
+// build it first, then set it. set(emptyView:) is the equivalent builder form.
+let emptyView = UIView()
+
+let label = UILabel()
+label.text = "No users found"
+label.textAlignment = .center
+label.textColor = .secondaryLabel
+
+let button = UIButton(type: .system)
+button.setTitle("Invite friends", for: .normal)
+
+// Add subviews and constraints to emptyView...
+
+users.emptyStateView = emptyView // or: users.set(emptyView: emptyView)
```
### Hide all chrome — minimal list