From 132fbccc1ad046e9c3646d0c4d1d31c0c0245142 Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 13:38:32 +0530 Subject: [PATCH 1/6] =?UTF-8?q?fix(ios):=20correct=20v5=20docs=20API=20aga?= =?UTF-8?q?inst=20the=20shipped=205.1.19=20kit=20=E2=80=94=20components-ov?= =?UTF-8?q?erview,=20conversations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every change verified against the public API surface of the CometChatUIKitSwift 5.1.19 xcframework (the artifact github.com/cometchat/cometchat-uikit-ios pins, sha256 a0f19887…). Nothing here is inferred from prose or from another page. components-overview.mdx - Removes the "Composite Components" section and every reference to CometChatMessages / CometChat{Users,Groups,Conversations}WithMessages. These are v4 components; 5.1.19 contains none of them (0 occurrences in the public .swiftinterface, no ObjC @interface, absent from the source tree). The page was actively RECOMMENDING them as the quick-integration path. - Replaces them with the host-composed pattern the clean recipe pages already teach: a list component + your own chat screen (MessageHeader + MessageList + MessageComposer), linking to ios-conversation / ios-one-to-one-chat / ios-tab-based-chat rather than duplicating them. - Rewrites "Configurations": MessageHeaderConfiguration, MessageListConfiguration and MessageComposerConfiguration do not exist in v5 either — that whole section described the v4 pass-config-into-a-composite model. Now shows per-instance configuration with verified API: set(user:), set(controller:), set(subtitleView:), set(emptyView:), set(errorView:), placeholderText, hideBackButton. - Re-roots the hierarchy diagram at YourNavigationController / MessagesVC so the ownership boundary is explicit. - AI Quick Reference: compositeComponents -> a `composition` block that positively states no composite ships and names the three parts. An agent reading only that block now gets the right answer instead of a phantom. conversations.mdx - Six styles + onSearchClick are public VARS, not set(label:) methods. Converted to property assignment: conversations.avatarStyle = …, .badgeStyle, .dateStyle, .receiptStyle, .statusIndicatorStyle, .typingIndicatorStyle, .onSearchClick. - CometChatMentionTextFormatter and CometChatURLTextFormatter do not exist. The kit ships CometChatTextFormatter and CometChatMentionsFormatter (plural) only — there is no URL formatter at all, so the example no longer implies one. - Custom empty state: the API takes a UIView, not a closure. Now assigns emptyStateView (inherited from CometChatListBase) with set(emptyView:) noted as the builder equivalent, plus emptyStateTitleText/emptyStateSubTitleText for the keep-the-default case. - CometChatMessages -> your own MessagesVC, with user/group passed from conversation.conversationWith. - AI Quick Reference slot names: tailView -> trailView, loadingStateView -> loadingView, and emptyStateView/errorStateView retyped as UIView rather than () -> UIView. Both pages now pass the docs-vs-kit API check with zero findings. Ref: cometchat-skills DOCS-BACKLOG G12 / features.ios-v5.json IOS-DOCS-001. --- ui-kit/ios/components-overview.mdx | 154 ++++++++++++++++------------- ui-kit/ios/conversations.mdx | 103 ++++++++++--------- 2 files changed, 138 insertions(+), 119 deletions(-) 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..fd2a3a657 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": { @@ -120,7 +120,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 +148,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) } @@ -226,13 +223,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 +953,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 +986,7 @@ avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8) avatarStyle.borderWidth = 1 avatarStyle.borderColor = UIColor.systemGray4 -conversations.set(avatarStyle: avatarStyle) +conversations.avatarStyle = avatarStyle ``` ### badgeStyle @@ -1015,7 +1009,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 +1039,7 @@ let dateStyle = DateStyle() dateStyle.textColor = UIColor.secondaryLabel dateStyle.textFont = UIFont.systemFont(ofSize: 12) -conversations.set(dateStyle: dateStyle) +conversations.dateStyle = dateStyle ``` ### dateTimeFormatter @@ -1181,10 +1175,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 +1232,7 @@ receiptStyle.sentIconTint = UIColor.systemGray receiptStyle.deliveredIconTint = UIColor.systemGray receiptStyle.readIconTint = UIColor.systemBlue -conversations.set(receiptStyle: receiptStyle) +conversations.receiptStyle = receiptStyle ``` ### selectionMode @@ -1269,7 +1263,7 @@ statusIndicatorStyle.backgroundColor = UIColor.systemGreen statusIndicatorStyle.borderWidth = 2 statusIndicatorStyle.borderColor = UIColor.white -conversations.set(statusIndicatorStyle: statusIndicatorStyle) +conversations.statusIndicatorStyle = statusIndicatorStyle ``` ### textFormatters @@ -1299,7 +1293,7 @@ let typingIndicatorStyle = TypingIndicatorStyle() typingIndicatorStyle.textColor = UIColor.systemGray typingIndicatorStyle.textFont = UIFont.italicSystemFont(ofSize: 14) -conversations.set(typingIndicatorStyle: typingIndicatorStyle) +conversations.typingIndicatorStyle = typingIndicatorStyle ``` --- @@ -1448,13 +1442,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 +1510,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 +1528,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 From 2d12af589f9a4d9647cb7e2ec895deb61ef9f839 Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 13:54:11 +0530 Subject: [PATCH 2/6] fix(ios): correct search.mdx against the shipped 5.1.19 kit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CometChatSearch's documented API diverged furthest from the shipped component. Every replacement below is taken from the 5.1.19 public .swiftinterface. Removed — these do not exist on CometChatSearch: set(onError:) / set(onEmpty:) failures and empty results are VIEWS, not callbacks: set(errorView:), set(emptyView:), errorStateTitleText, errorStateSubTitleText set(conversationsRequestBuilder:) no request builder at all; scope with set(messagesRequestBuilder:) set(searchIn:) + set(searchFilters:initialFilter:), or user/group for a single conversation set(initialView:) no pre-search view API exists — section removed rather than left describing something unbuildable set(leadingViewForMessage:) the ForMessage granular slots do not exist. The set(titleViewForMessage:) only message-level slot is set(listItemViewForMessage:) set(subtitleViewForMessage:) (plus the per-media variants). The granular slots set(trailingViewForMessage:) exist for CONVERSATIONS only, as assignable properties: leading/title/subtitle/tailViewForConversation Documented correctly for the first time: SearchScope = .conversations | .messages SearchFilter = .messages | .conversations | .unread | .groups | .photos | .videos | .links | .documents | .audio AI Quick Reference (the block agents read first) had nine wrong entries. Fixed: dropped the two request builders, onBack/onError/onEmpty, and hideNavigationBar/ hideBackButton/hideReceipts — CometChatSearch inherits UIViewController, NOT CometChatListBase, so it has none of the list-base chrome. Added the five per-media listItemViewFor* slots that were missing, and marked onConversationClicked/onMessageClicked as assignable properties. Also replaced the CometChatMessages composite references (IOS-DOCS-001) with the host-composed MessagesVC, and repointed an itemView cross-reference from CometChatMessages to CometChatMessageList. search.mdx now passes the docs-vs-kit API check with zero findings. Running total across ui-kit/ios: 19 pages / 76 findings -> 17 pages / 55 findings. --- ui-kit/ios/search.mdx | 196 ++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 124 deletions(-) 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]) ``` From db8010123a56333926124a9729f32a6438765955 Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 14:53:21 +0530 Subject: [PATCH 3/6] fix(ios): users + groups API, and clear the v4 composite from every v5 page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit users.mdx — verified against 5.1.19: set(usersRequestBuilder:) -> set(userRequestBuilder:) (singular "user") set(subtitleView:) -> set(subtitle:) ((User?) -> UIView) set(trailView:) -> set(trailingView:) ((User?) -> UIView) set(avatarStyle:) / set(statusIndicatorStyle:) -> public vars, assigned set(emptyStateView:) closure -> emptyStateView is a UIView you assign (inherited from CometChatListBase) set(onSelection:) left as-is — it IS real on CometChatUsers. groups.mdx — same subtitle/trailingView/style/emptyStateView corrections, plus: set(onSelection:) -> onSelectedItemProceed. CometChatGroups has NO onSelection (CometChatUsers does). Groups exposes onDidSelect (per row) and onSelectedItemProceed (multi-select confirm). Note for future edits: these renames are PER TYPE, not global. CometChatGroupMembers genuinely ships set(subtitleView:) and set(trailView:) — the kit is internally inconsistent, so a blanket search-and-replace would break the one page that is right. IOS-DOCS-001 cleanup — CometChatMessages and the *WithMessages composites are now gone from every v5 page (12 files). Code samples instantiate the developer's own MessagesVC / ChatListVC with a pointer to the recipe page; prose and AI Quick Reference component lists name the three real components instead. The v2/v3/v4 trees are untouched, and upgrading-from-v4.mdx keeps its 4 references — a migration page must name what it migrates away from. Running total for ui-kit/ios: 19 pages / 76 findings -> 10 pages / 24 findings. --- ui-kit/ios/ai-assistant-chat-history.mdx | 20 +++++----- ui-kit/ios/ai-features.mdx | 18 ++++----- ui-kit/ios/call-features.mdx | 10 ++--- ui-kit/ios/core-features.mdx | 34 ++++++++-------- ui-kit/ios/group-members.mdx | 10 ++--- ui-kit/ios/groups.mdx | 48 +++++++++++------------ ui-kit/ios/guide-ai-agent.mdx | 4 +- ui-kit/ios/guide-block-unblock-user.mdx | 6 +-- ui-kit/ios/guide-group-chat.mdx | 2 +- ui-kit/ios/guide-message-privately.mdx | 8 ++-- ui-kit/ios/message-header.mdx | 4 +- ui-kit/ios/message-list.mdx | 10 ++--- ui-kit/ios/message-template.mdx | 8 ++-- ui-kit/ios/shortcut-formatter-guide.mdx | 2 +- ui-kit/ios/users.mdx | 49 ++++++++++++------------ 15 files changed, 117 insertions(+), 116 deletions(-) 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-features.mdx b/ui-kit/ios/call-features.mdx index 863aef8e3..813ba7c48 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 { diff --git a/ui-kit/ios/core-features.mdx b/ui-kit/ios/core-features.mdx index ae494ff0d..14504cc79 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 { @@ -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..24175de72 100644 --- a/ui-kit/ios/group-members.mdx +++ b/ui-kit/ios/group-members.mdx @@ -113,7 +113,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 +174,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 +251,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) }) @@ -917,7 +917,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) } @@ -1178,7 +1178,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) } diff --git a/ui-kit/ios/groups.mdx b/ui-kit/ios/groups.mdx index 8be5fe225..a901af089 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 @@ -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..86360a74b 100644 --- a/ui-kit/ios/guide-ai-agent.mdx +++ b/ui-kit/ios/guide-ai-agent.mdx @@ -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) } diff --git a/ui-kit/ios/guide-block-unblock-user.mdx b/ui-kit/ios/guide-block-unblock-user.mdx index 191856c88..e47bf5888 100644 --- a/ui-kit/ios/guide-block-unblock-user.mdx +++ b/ui-kit/ios/guide-block-unblock-user.mdx @@ -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) } @@ -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..bbd1f6ceb 100644 --- a/ui-kit/ios/message-header.mdx +++ b/ui-kit/ios/message-header.mdx @@ -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 diff --git a/ui-kit/ios/message-list.mdx b/ui-kit/ios/message-list.mdx index 16ec1009b..be7ea936e 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]) ``` 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/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/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 From 2d43fda91bdc62f1f3864855ee78f1709e7124ef Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 14:57:12 +0530 Subject: [PATCH 4/6] =?UTF-8?q?fix(ios):=20clear=20the=20last=2024=20API?= =?UTF-8?q?=20defects=20=E2=80=94=20ui-kit/ios=20now=20verifies=20clean=20?= =?UTF-8?q?against=205.1.19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrong CALL FORM (member exists as a settable property, not set(label:)): CometChatCallButtons onVoiceCallClick, onVideoCallClick CometChatMessageHeader avatarStyle, statusIndicatorStyle, typingIndicatorStyle, onAiChatHistoryClicked, onAiNewChatClicked (the two AI hooks also take (User) -> Void, not () -> Void) CometChatGroupMembers menus ([UIBarButtonItem]?), onSelectedItemProceed, emptyStateView CometChatMessageList emptyStateView Renamed: set(callSettingBuilder:) -> set(callSettingsBuilder:) (plural) set(onDeclineClick:) -> set(onCancelClick:) ((Call?, UIViewController?) -> Void) set(sessionID:) -> set(sessionId:) (casing — would not compile) CometChatDateStyle -> DateStyle (this one is un-prefixed) Absent, replaced with what actually ships: CometChatMessageList/Composer set(parentMessage:) -> set(parentMessageId: Int). Note CometChatThreadedMessageHeader DOES take set(parentMessage: BaseMessage) — left untouched. Three components, two different parent APIs. CometChatGroupMembers set(onSelection:) -> onSelectedItemProceed (no onSelection here) CometChatMessageHeaderOption -> CometChatPopupMenu.MenuItem(title:icon:action:); set(options:) takes [CometChatPopupMenu.MenuItem]?, not a closure returning options CometChatAddMembers -> no such component. Sample now builds its own picker and points at CometChat.addMembersToGroup(guid:groupMembers:bannedUIDs:onSuccess:onError:) (/sdk/ios/group-add-members) — UI Kit first, SDK where the kit has nothing. CometChatAvatar set(user:) -> setAvatar(avatarUrl:with:) (its only other API is set(image:)) ui-kit/ios: 51 pages scanned, 0 findings. Started at 19 pages / 76 findings. --- ui-kit/ios/call-buttons.mdx | 10 ++--- ui-kit/ios/call-features.mdx | 10 ++--- ui-kit/ios/component-styling.mdx | 2 +- ui-kit/ios/core-features.mdx | 4 +- ui-kit/ios/group-members.mdx | 36 ++++++++-------- ui-kit/ios/guide-block-unblock-user.mdx | 4 +- ui-kit/ios/message-header.mdx | 56 +++++++++++-------------- ui-kit/ios/message-list.mdx | 14 +++---- ui-kit/ios/ongoing-call.mdx | 2 +- ui-kit/ios/threaded-messages-header.mdx | 4 +- 10 files changed, 68 insertions(+), 74 deletions(-) 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 813ba7c48..890844cda 100644 --- a/ui-kit/ios/call-features.mdx +++ b/ui-kit/ios/call-features.mdx @@ -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/core-features.mdx b/ui-kit/ios/core-features.mdx index 14504cc79..32f7b1fba 100644 --- a/ui-kit/ios/core-features.mdx +++ b/ui-kit/ios/core-features.mdx @@ -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 diff --git a/ui-kit/ios/group-members.mdx b/ui-kit/ios/group-members.mdx index 24175de72..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" } @@ -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 | @@ -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 { @@ -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/guide-block-unblock-user.mdx b/ui-kit/ios/guide-block-unblock-user.mdx index e47bf5888..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) @@ -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) } diff --git a/ui-kit/ios/message-header.mdx b/ui-kit/ios/message-header.mdx index bbd1f6ceb..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": [], @@ -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 be7ea936e..a48dbf8e2 100644 --- a/ui-kit/ios/message-list.mdx +++ b/ui-kit/ios/message-list.mdx @@ -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/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/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 From e9301601cb0822f03263280089a7564929229a5b Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 15:32:35 +0530 Subject: [PATCH 5/6] fix(ios): three defects a verifier blind spot had hidden, plus a stale table row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit guide-ai-agent.mdx declares its components as `private var messageList: CometChatMessageList!` and assigns them later. The checker only resolved let/var-with-initialiser and lazy-var forms, so every call on those receivers was silently skipped — hiding messageList/messageComposer set(parentMessage:) (they take set(parentMessageId: Int); only CometChatThreadedMessageHeader takes a BaseMessage) and messageList.set(emptyStateView:) (an assignable UIView). Fixed the receiver resolution in test-suite/scripts/verify-swift-docs-api.mjs rather than hand-patching the page, so the whole class is caught from now on. groups.mdx also had a prose table row still naming `set(onSelection:)`, which CometChatGroups does not have. The checker scans code fences only, so prose and tables need a separate sweep — noted for the remaining docs work. ui-kit/ios: 51 pages, 0 findings. --- ui-kit/ios/groups.mdx | 2 +- ui-kit/ios/guide-ai-agent.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui-kit/ios/groups.mdx b/ui-kit/ios/groups.mdx index a901af089..6d0f85a73 100644 --- a/ui-kit/ios/groups.mdx +++ b/ui-kit/ios/groups.mdx @@ -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 | diff --git a/ui-kit/ios/guide-ai-agent.mdx b/ui-kit/ios/guide-ai-agent.mdx index 86360a74b..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) @@ -405,7 +405,7 @@ label.textAlignment = .center label.textColor = .secondaryLabel emptyView.addSubview(label) -messageList.set(emptyStateView: emptyView) +messageList.emptyStateView = emptyView ``` ### Streaming Speed From 2ead0a8167c9cce0401b91b7a72ae5cf09c03f3c Mon Sep 17 00:00:00 2001 From: Ashfaaq Ali Date: Thu, 20 Aug 2026 16:22:59 +0530 Subject: [PATCH 6/6] =?UTF-8?q?fix(ios):=20conversation-type=20filter=20AP?= =?UTF-8?q?I=20=E2=80=94=20setConversationType,=20and=20there=20is=20no=20?= =?UTF-8?q?.both?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit conversations.mdx taught `.set(conversationType: .both)`. Two errors, both verified against CometChatSDK 4.1.7 as shipped inside the 5.1.19 kit: method ConversationRequestBuilder ships setConversationType(conversationType:), NOT set(conversationType:). Zero matches for the documented form. case CometChat.ConversationType has .user / .group / .none. There is no .both. To get both 1:1s and groups you omit the call — that is the default. Fixed the Filtering example, both Filter Recipes rows, the two later usages, and the ConversationType block in the AI Quick Reference. Found by reviewing the iOS core skill against the kit rather than by the checker: the checker only indexed top-level declarations, so a NESTED type (ConversationRequest.ConversationRequestBuilder) was never indexed and every call on it was silently skipped. Checker fixed alongside. --- ui-kit/ios/conversations.mdx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ui-kit/ios/conversations.mdx b/ui-kit/ios/conversations.mdx index fd2a3a657..fc108b494 100644 --- a/ui-kit/ios/conversations.mdx +++ b/ui-kit/ios/conversations.mdx @@ -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." } } } @@ -188,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) ``` @@ -198,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)` | @@ -1569,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) ```