@cometchat/skills 4.2.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +33 -12
- package/bin/install.js +59 -4
- package/package.json +14 -1
- package/skills/cometchat/SKILL.md +460 -77
- package/skills/cometchat/references/asking-questions.md +48 -0
- package/skills/cometchat-a11y/SKILL.md +3 -2
- package/skills/cometchat-android-v5/SKILL.md +2 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
- package/skills/cometchat-android-v5-calls/references/README.md +1 -1
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
- package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
- package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
- package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
- package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
- package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
- package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
- package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
- package/skills/cometchat-android-v5-components/SKILL.md +4 -3
- package/skills/cometchat-android-v5-core/SKILL.md +20 -2
- package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
- package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
- package/skills/cometchat-android-v5-features/SKILL.md +5 -4
- package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
- package/skills/cometchat-android-v5-production/SKILL.md +2 -1
- package/skills/cometchat-android-v5-push/SKILL.md +2 -3
- package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
- package/skills/cometchat-android-v6/SKILL.md +2 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
- package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
- package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
- package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
- package/skills/cometchat-android-v6-core/SKILL.md +389 -9
- package/skills/cometchat-android-v6-events/SKILL.md +4 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
- package/skills/cometchat-android-v6-features/SKILL.md +26 -2
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
- package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
- package/skills/cometchat-android-v6-production/SKILL.md +6 -3
- package/skills/cometchat-android-v6-push/SKILL.md +43 -2
- package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
- package/skills/cometchat-angular-calls/SKILL.md +256 -389
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
- package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
- package/skills/cometchat-angular-calls/references/call-session.md +2 -2
- package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
- package/skills/cometchat-angular-calls/references/device-management.md +53 -34
- package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
- package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
- package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
- package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
- package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
- package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
- package/skills/cometchat-angular-components/SKILL.md +149 -620
- package/skills/cometchat-angular-core/SKILL.md +235 -293
- package/skills/cometchat-angular-customization/SKILL.md +415 -223
- package/skills/cometchat-angular-features/SKILL.md +216 -334
- package/skills/cometchat-angular-patterns/SKILL.md +168 -359
- package/skills/cometchat-angular-placement/SKILL.md +189 -560
- package/skills/cometchat-angular-production/SKILL.md +241 -92
- package/skills/cometchat-angular-push/SKILL.md +280 -294
- package/skills/cometchat-angular-testing/SKILL.md +430 -158
- package/skills/cometchat-angular-theming/SKILL.md +190 -265
- package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
- package/skills/cometchat-astro-patterns/SKILL.md +22 -1
- package/skills/cometchat-calls/SKILL.md +25 -19
- package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
- package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
- package/skills/cometchat-calls/references/use-case-support.md +3 -4
- package/skills/cometchat-calls/references/use-case-team.md +23 -12
- package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
- package/skills/cometchat-components/SKILL.md +163 -25
- package/skills/cometchat-core/SKILL.md +412 -13
- package/skills/cometchat-customization/SKILL.md +50 -25
- package/skills/cometchat-features/SKILL.md +313 -34
- package/skills/cometchat-flutter-v5/SKILL.md +10 -4
- package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +20 -2
- package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
- package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
- package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
- package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6/SKILL.md +17 -16
- package/skills/cometchat-flutter-v6-calls/SKILL.md +78 -63
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +8 -6
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
- package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
- package/skills/cometchat-flutter-v6-core/SKILL.md +348 -10
- package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
- package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
- package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
- package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
- package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
- package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
- package/skills/cometchat-flutter-v6-push/SKILL.md +43 -21
- package/skills/cometchat-flutter-v6-testing/SKILL.md +6 -6
- package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
- package/skills/cometchat-i18n/SKILL.md +139 -78
- package/skills/cometchat-ios/SKILL.md +4 -2
- package/skills/cometchat-ios-calls/SKILL.md +225 -95
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
- package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
- package/skills/cometchat-ios-calls/references/call-session.md +51 -54
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
- package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
- package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
- package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
- package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
- package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
- package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
- package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
- package/skills/cometchat-ios-components/SKILL.md +200 -12
- package/skills/cometchat-ios-core/SKILL.md +281 -11
- package/skills/cometchat-ios-customization/SKILL.md +276 -110
- package/skills/cometchat-ios-features/SKILL.md +64 -36
- package/skills/cometchat-ios-placement/SKILL.md +15 -12
- package/skills/cometchat-ios-production/SKILL.md +12 -4
- package/skills/cometchat-ios-push/SKILL.md +53 -19
- package/skills/cometchat-ios-testing/SKILL.md +14 -9
- package/skills/cometchat-ios-theming/SKILL.md +39 -3
- package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
- package/skills/cometchat-native-bare-patterns/SKILL.md +56 -18
- package/skills/cometchat-native-calls/SKILL.md +89 -19
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
- package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
- package/skills/cometchat-native-calls/references/call-session.md +2 -2
- package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
- package/skills/cometchat-native-calls/references/device-management.md +53 -30
- package/skills/cometchat-native-calls/references/group-calls.md +35 -30
- package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
- package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
- package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
- package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
- package/skills/cometchat-native-calls/references/share-invite.md +7 -5
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
- package/skills/cometchat-native-components/SKILL.md +91 -57
- package/skills/cometchat-native-core/SKILL.md +281 -9
- package/skills/cometchat-native-customization/SKILL.md +150 -28
- package/skills/cometchat-native-expo-patterns/SKILL.md +77 -27
- package/skills/cometchat-native-features/SKILL.md +79 -49
- package/skills/cometchat-native-placement/SKILL.md +19 -10
- package/skills/cometchat-native-production/SKILL.md +9 -3
- package/skills/cometchat-native-push/SKILL.md +2 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -2
- package/skills/cometchat-native-theming/SKILL.md +54 -29
- package/skills/cometchat-native-troubleshooting/SKILL.md +71 -3
- package/skills/cometchat-nextjs-patterns/SKILL.md +48 -6
- package/skills/cometchat-placement/SKILL.md +42 -3
- package/skills/cometchat-production/SKILL.md +12 -5
- package/skills/cometchat-react-calls/SKILL.md +220 -10
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
- package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
- package/skills/cometchat-react-calls/references/call-session.md +1 -1
- package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
- package/skills/cometchat-react-calls/references/device-management.md +55 -51
- package/skills/cometchat-react-calls/references/group-calls.md +18 -23
- package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
- package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
- package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
- package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
- package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
- package/skills/cometchat-react-calls/references/share-invite.md +4 -5
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
- package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
- package/skills/cometchat-react-patterns/SKILL.md +57 -4
- package/skills/cometchat-react-push/SKILL.md +258 -72
- package/skills/cometchat-react-router-patterns/SKILL.md +43 -4
- package/skills/cometchat-react-testing/SKILL.md +14 -5
- package/skills/cometchat-theming/SKILL.md +181 -18
- package/skills/cometchat-troubleshooting/SKILL.md +40 -20
|
@@ -3,13 +3,14 @@ name: cometchat-ios-customization
|
|
|
3
3
|
description: "Customize CometChat iOS UI Kit beyond theming — custom views, message templates, text formatters, and event handling."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "CometChatUIKitSwift ^5; iOS 13+"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
10
9
|
tags: "chat cometchat ios customization templates formatters events"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `CometChatUIKitSwift ~> 5` (+ `CometChatCallsSDK ~> 5`) — Pods/SPM `.swiftinterface` + `ui-kit/ios`. **Official docs:** https://www.cometchat.com/docs/ui-kit/ios/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
|
|
13
|
+
|
|
13
14
|
## Purpose
|
|
14
15
|
|
|
15
16
|
This skill teaches advanced customization of CometChat iOS UI Kit — custom views, message templates, text formatters, event listeners, and request builder filters.
|
|
@@ -201,46 +202,49 @@ conversations.set(options: { (conversation: Conversation?) -> [CometChatConversa
|
|
|
201
202
|
guard let conversation = conversation else { return [] }
|
|
202
203
|
var options: [CometChatConversationOption] = []
|
|
203
204
|
|
|
205
|
+
// CometChatConversationOption.init takes NO `id`; the click handler is the
|
|
206
|
+
// `onClick` initializer parameter (not a settable property) and its closure is
|
|
207
|
+
// (User?, Int, CometChatConversationOption, UIViewController?) -> Void.
|
|
204
208
|
// Pin conversation
|
|
205
209
|
let pinOption = CometChatConversationOption(
|
|
206
|
-
id: "pin",
|
|
207
210
|
title: "Pin",
|
|
211
|
+
titleColor: nil,
|
|
208
212
|
icon: UIImage(systemName: "pin.fill"),
|
|
213
|
+
titleFont: nil,
|
|
214
|
+
iconTint: .white,
|
|
209
215
|
backgroundColor: .systemYellow,
|
|
210
|
-
|
|
216
|
+
onClick: { user, index, option, controller in
|
|
217
|
+
print("Pin conversation")
|
|
218
|
+
}
|
|
211
219
|
)
|
|
212
|
-
pinOption.onClick = { _, _, _, _ in
|
|
213
|
-
// Handle pin action
|
|
214
|
-
print("Pin conversation: \(conversation.conversationId ?? "")")
|
|
215
|
-
}
|
|
216
220
|
options.append(pinOption)
|
|
217
221
|
|
|
218
222
|
// Mute conversation
|
|
219
223
|
let muteOption = CometChatConversationOption(
|
|
220
|
-
id: "mute",
|
|
221
224
|
title: "Mute",
|
|
225
|
+
titleColor: nil,
|
|
222
226
|
icon: UIImage(systemName: "bell.slash.fill"),
|
|
227
|
+
titleFont: nil,
|
|
228
|
+
iconTint: .white,
|
|
223
229
|
backgroundColor: .systemGray,
|
|
224
|
-
|
|
230
|
+
onClick: { user, index, option, controller in
|
|
231
|
+
print("Mute conversation")
|
|
232
|
+
}
|
|
225
233
|
)
|
|
226
|
-
muteOption.onClick = { _, _, _, _ in
|
|
227
|
-
// Handle mute action
|
|
228
|
-
print("Mute conversation: \(conversation.conversationId ?? "")")
|
|
229
|
-
}
|
|
230
234
|
options.append(muteOption)
|
|
231
235
|
|
|
232
236
|
// Delete conversation
|
|
233
237
|
let deleteOption = CometChatConversationOption(
|
|
234
|
-
id: "delete",
|
|
235
238
|
title: "Delete",
|
|
239
|
+
titleColor: nil,
|
|
236
240
|
icon: UIImage(systemName: "trash.fill"),
|
|
241
|
+
titleFont: nil,
|
|
242
|
+
iconTint: .white,
|
|
237
243
|
backgroundColor: .systemRed,
|
|
238
|
-
|
|
244
|
+
onClick: { user, index, option, controller in
|
|
245
|
+
print("Delete conversation")
|
|
246
|
+
}
|
|
239
247
|
)
|
|
240
|
-
deleteOption.onClick = { _, _, _, _ in
|
|
241
|
-
// Handle delete action
|
|
242
|
-
print("Delete conversation: \(conversation.conversationId ?? "")")
|
|
243
|
-
}
|
|
244
248
|
options.append(deleteOption)
|
|
245
249
|
|
|
246
250
|
return options
|
|
@@ -252,15 +256,16 @@ conversations.set(options: { (conversation: Conversation?) -> [CometChatConversa
|
|
|
252
256
|
```swift
|
|
253
257
|
conversations.add(options: { (conversation: Conversation?) -> [CometChatConversationOption] in
|
|
254
258
|
let archiveOption = CometChatConversationOption(
|
|
255
|
-
id: "archive",
|
|
256
259
|
title: "Archive",
|
|
260
|
+
titleColor: nil,
|
|
257
261
|
icon: UIImage(systemName: "archivebox.fill"),
|
|
262
|
+
titleFont: nil,
|
|
263
|
+
iconTint: .white,
|
|
258
264
|
backgroundColor: .systemPurple,
|
|
259
|
-
|
|
265
|
+
onClick: { user, index, option, controller in
|
|
266
|
+
print("Archive conversation")
|
|
267
|
+
}
|
|
260
268
|
)
|
|
261
|
-
archiveOption.onClick = { _, _, _, _ in
|
|
262
|
-
print("Archive conversation")
|
|
263
|
-
}
|
|
264
269
|
|
|
265
270
|
return [archiveOption]
|
|
266
271
|
})
|
|
@@ -272,73 +277,84 @@ conversations.add(options: { (conversation: Conversation?) -> [CometChatConversa
|
|
|
272
277
|
|
|
273
278
|
### Creating a Custom Message Template
|
|
274
279
|
|
|
280
|
+
> ⚠️ **`CometChatMessageTemplate` is a `struct` with ONE memberwise initializer** — there is NO `CometChatMessageTemplate(type:category:)` convenience init, and the label order is **`category` first, then `type`**. The init requires ALL of these labels: `category:type:contentView:bubbleView:headerView:footerView:bottomView:options:` (the trailing `statusInfoView:` / `replyView:` default to `nil`). Pass `nil` for any view closure you don't need — you cannot omit the label. Verified: `CometChatMessageTemplate.swift:25-47`.
|
|
281
|
+
|
|
275
282
|
```swift
|
|
276
283
|
let messageList = CometChatMessageList()
|
|
277
284
|
|
|
278
|
-
// Get default templates
|
|
279
|
-
|
|
285
|
+
// Get default templates — the argument is required (pass nil for defaults).
|
|
286
|
+
// Starting from this list (not []) keeps every built-in bubble.
|
|
287
|
+
// CometChatUIKit.getDataSource() → CometChatUIKit.swift:287; getAllMessageTemplates(additionalConfiguration:) → DataSource.swift:63
|
|
288
|
+
var templates = CometChatUIKit.getDataSource().getAllMessageTemplates(additionalConfiguration: nil)
|
|
280
289
|
|
|
281
|
-
// Create custom template for a specific message type
|
|
290
|
+
// Create custom template for a specific message type.
|
|
291
|
+
// ALL labels below are required by the only initializer (CometChatMessageTemplate.swift:25).
|
|
292
|
+
// `category` comes BEFORE `type`. Each view closure is (BaseMessage?, MessageBubbleAlignment, UIViewController?) -> UIView?.
|
|
282
293
|
let customTemplate = CometChatMessageTemplate(
|
|
294
|
+
category: "custom",
|
|
283
295
|
type: "custom_poll",
|
|
284
|
-
category: "custom"
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
// Custom content view
|
|
288
|
-
customTemplate.contentView = { message, alignment, controller in
|
|
289
|
-
guard let customMessage = message as? CustomMessage,
|
|
290
|
-
let data = customMessage.customData else {
|
|
291
|
-
return UIView()
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
let pollView = PollBubbleView()
|
|
295
|
-
pollView.configure(with: data)
|
|
296
|
-
return pollView
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Custom header view (above the bubble)
|
|
300
|
-
customTemplate.headerView = { message, alignment, controller in
|
|
301
|
-
let label = UILabel()
|
|
302
|
-
label.text = "📊 Poll"
|
|
303
|
-
label.font = .boldSystemFont(ofSize: 12)
|
|
304
|
-
label.textColor = .secondaryLabel
|
|
305
|
-
return label
|
|
306
|
-
}
|
|
307
296
|
|
|
308
|
-
// Custom
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
297
|
+
// Custom content view — the inner bubble content
|
|
298
|
+
contentView: { message, alignment, controller in
|
|
299
|
+
guard let customMessage = message as? CustomMessage,
|
|
300
|
+
let data = customMessage.customData else {
|
|
301
|
+
return UIView()
|
|
302
|
+
}
|
|
303
|
+
let pollView = PollBubbleView()
|
|
304
|
+
pollView.configure(with: data)
|
|
305
|
+
return pollView
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
// Custom bubble view (wraps content). alignment is MessageBubbleAlignment (.left/.right/.center — UIKitConstants.swift:85).
|
|
309
|
+
bubbleView: { message, alignment, controller in
|
|
310
|
+
let bubble = UIView()
|
|
311
|
+
bubble.backgroundColor = alignment == .right
|
|
312
|
+
? CometChatTheme.primaryColor.withAlphaComponent(0.1)
|
|
313
|
+
: UIColor.secondarySystemBackground
|
|
314
|
+
bubble.layer.cornerRadius = 12
|
|
315
|
+
return bubble
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
// Custom header view (above the bubble)
|
|
319
|
+
headerView: { message, alignment, controller in
|
|
320
|
+
let label = UILabel()
|
|
321
|
+
label.text = "📊 Poll"
|
|
322
|
+
label.font = .boldSystemFont(ofSize: 12)
|
|
323
|
+
label.textColor = .secondaryLabel
|
|
324
|
+
return label
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
// Custom footer view (below the bubble)
|
|
328
|
+
footerView: { message, alignment, controller in
|
|
329
|
+
let label = UILabel()
|
|
330
|
+
label.text = "Tap to vote"
|
|
331
|
+
label.font = .systemFont(ofSize: 11)
|
|
332
|
+
label.textColor = .tertiaryLabel
|
|
333
|
+
return label
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
// bottomView — pass nil if unused (label still required)
|
|
337
|
+
bottomView: nil,
|
|
338
|
+
|
|
339
|
+
// Custom options (long press menu). Closure is (BaseMessage?, Group?, UIViewController?) -> [CometChatMessageOption]?
|
|
340
|
+
options: { message, group, controller in
|
|
341
|
+
let viewResultsOption = CometChatMessageOption(
|
|
342
|
+
id: "view_results",
|
|
343
|
+
title: "View Results",
|
|
344
|
+
icon: UIImage(systemName: "chart.bar.fill"),
|
|
345
|
+
onItemClick: { message in
|
|
346
|
+
// Show poll results — closure receives the BaseMessage? only
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
return [viewResultsOption]
|
|
336
350
|
}
|
|
337
|
-
|
|
338
|
-
return [viewResultsOption]
|
|
339
|
-
}
|
|
351
|
+
)
|
|
340
352
|
|
|
353
|
+
// APPEND to the default templates (do NOT start from []) so every built-in bubble survives.
|
|
341
354
|
templates.append(customTemplate)
|
|
355
|
+
|
|
356
|
+
// set(templates:) → CometChatMessageList + Properties.swift:54 (replaces the list, so we passed the merged array).
|
|
357
|
+
// add(templates:) (line 63) merges into the existing list if you prefer.
|
|
342
358
|
messageList.set(templates: templates)
|
|
343
359
|
```
|
|
344
360
|
|
|
@@ -603,11 +619,11 @@ class GroupEventListener: CometChatGroupEventListener {
|
|
|
603
619
|
print("Members added to group")
|
|
604
620
|
}
|
|
605
621
|
|
|
606
|
-
func ccGroupMemberKicked(
|
|
622
|
+
func ccGroupMemberKicked(action: ActionMessage, kickedUser: User, kickedBy: User, kickedFrom: Group) {
|
|
607
623
|
print("Member kicked from group")
|
|
608
624
|
}
|
|
609
625
|
|
|
610
|
-
func ccGroupMemberBanned(
|
|
626
|
+
func ccGroupMemberBanned(action: ActionMessage, bannedUser: User, bannedBy: User, bannedFrom: Group) {
|
|
611
627
|
print("Member banned from group")
|
|
612
628
|
}
|
|
613
629
|
|
|
@@ -641,7 +657,7 @@ class CallEventListener: CometChatCallEventListener {
|
|
|
641
657
|
print("Outgoing call initiated")
|
|
642
658
|
}
|
|
643
659
|
|
|
644
|
-
func
|
|
660
|
+
func onCallInitiated(call: Call) { // CometChatCallEventListener has onCallInitiated, not ccCallInitiated
|
|
645
661
|
print("Call initiated")
|
|
646
662
|
}
|
|
647
663
|
}
|
|
@@ -660,18 +676,15 @@ CometChatCallEvents.addListener("call-listener", CallEventListener())
|
|
|
660
676
|
let conversations = CometChatConversations()
|
|
661
677
|
|
|
662
678
|
// Only show user conversations (no groups)
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
.
|
|
666
|
-
)
|
|
667
|
-
|
|
668
|
-
// Only show conversations with specific tags
|
|
669
|
-
conversations.set(conversationsRequestBuilder: ConversationsRequest.ConversationsRequestBuilder()
|
|
670
|
-
.set(tags: ["vip", "premium"])
|
|
679
|
+
// ConversationRequestBuilder exposes setConversationType(conversationType:), not set(conversationType:)
|
|
680
|
+
conversations.set(conversationsRequestBuilder: ConversationRequest.ConversationRequestBuilder()
|
|
681
|
+
.setConversationType(conversationType: .user)
|
|
671
682
|
.set(limit: 30)
|
|
672
683
|
)
|
|
673
684
|
```
|
|
674
685
|
|
|
686
|
+
> Note: `ConversationRequestBuilder` has no tags filter — its only methods are `set(limit:)`, `setConversationType(conversationType:)`, and `build()`. To filter by tags, fetch and filter the resulting conversations client-side.
|
|
687
|
+
|
|
675
688
|
### Filter Messages
|
|
676
689
|
|
|
677
690
|
```swift
|
|
@@ -680,7 +693,7 @@ let messageList = CometChatMessageList()
|
|
|
680
693
|
// Only show text and image messages
|
|
681
694
|
messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
682
695
|
.set(uid: user.uid ?? "")
|
|
683
|
-
.set(types: [
|
|
696
|
+
.set(types: [MessageTypeConstants.text, MessageTypeConstants.image])
|
|
684
697
|
.set(limit: 30)
|
|
685
698
|
)
|
|
686
699
|
|
|
@@ -688,7 +701,7 @@ messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
|
688
701
|
let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
|
|
689
702
|
messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
690
703
|
.set(uid: user.uid ?? "")
|
|
691
|
-
.set(
|
|
704
|
+
.set(timeStamp: Int(startDate.timeIntervalSince1970))
|
|
692
705
|
.set(limit: 50)
|
|
693
706
|
)
|
|
694
707
|
|
|
@@ -752,20 +765,133 @@ groups.set(groupsRequestBuilder: GroupsRequest.GroupsRequestBuilder()
|
|
|
752
765
|
|
|
753
766
|
## 7. DataSource Decorator Pattern
|
|
754
767
|
|
|
755
|
-
|
|
768
|
+
> ⚠️ **REGISTRATION IS THE CATCH.** `DataSourceDecorator` is public (DataSourceDecorator.swift:12), but the only mechanism that installs a decorator — `ChatConfigurator.enable { ... }` — is **internal to CometChatUIKitSwift**. `ChatConfigurator` shows up in the public module interface (`uikit.swiftinterface:8591`) as a class with **no public members** (only `deinit`); its `enable`/`getDataSource` statics are NOT public. The kit's own extensions (Polls/Stickers/etc.) call `ChatConfigurator.enable` from *inside* the module via `ExtensionDataSource.addExtension()`, but **app code cannot call it**. So a hand-rolled `DataSourceDecorator` subclass compiles but **has no public way to be registered** in this kit version.
|
|
769
|
+
>
|
|
770
|
+
> **Use the public component-level setters instead** for the common cases:
|
|
771
|
+
> - **Attachment options** → `CometChatMessageComposer.set(attachmentOptions:)` (§7a below). Public. Verified `CometChatMessageComposer + Properties.swift:44`.
|
|
772
|
+
> - **Custom message type / override a built-in bubble / per-type long-press options** → build a `CometChatMessageTemplate` and apply it with `CometChatMessageList.set(templates:)` / `add(templates:)` (§3 and §7b). Public. Verified `CometChatMessageList + Properties.swift:54,63`.
|
|
773
|
+
> - **Message long-press options**: there is **NO** `set(options:)`/`add(options:)` for *message* options on `CometChatMessageList` (only Conversations/Users/Groups/GroupMembers/CallLogs expose those). Message options are customized **only through a template's `options` closure** (§7b).
|
|
774
|
+
>
|
|
775
|
+
> The decorator subclass below is documented for completeness / for code that lives inside a kit fork — its method signatures are the source of truth for the protocol — but prefer the component setters above for app integration.
|
|
776
|
+
|
|
777
|
+
### 7a. Add a composer attachment option (public path)
|
|
778
|
+
|
|
779
|
+
`set(attachmentOptions:)` REPLACES the attachment list with whatever the closure returns — there is no public "super" list at the composer level, so to keep the built-in photo/video/file actions you must construct them yourself or accept that only your returned actions show. The closure is `(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]`.
|
|
780
|
+
|
|
781
|
+
```swift
|
|
782
|
+
let composer = CometChatMessageComposer()
|
|
783
|
+
|
|
784
|
+
composer.set(attachmentOptions: { user, group, controller in
|
|
785
|
+
// NOTE: returning ONLY this array hides the default attachments.
|
|
786
|
+
// Re-add any defaults you still want here.
|
|
787
|
+
let location = CometChatMessageComposerAction(
|
|
788
|
+
id: "location",
|
|
789
|
+
text: "Send Location",
|
|
790
|
+
startIcon: UIImage(systemName: "location.fill"),
|
|
791
|
+
startIconTint: CometChatTheme.iconColorPrimary,
|
|
792
|
+
textColor: CometChatTheme.textColorPrimary,
|
|
793
|
+
textFont: CometChatTypography.Body.regular,
|
|
794
|
+
onActionClick: { /* present location picker, then send (see §8) */ }
|
|
795
|
+
)
|
|
796
|
+
return [location]
|
|
797
|
+
})
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
### 7b. Override a built-in type's bubble / add per-type options (public path)
|
|
801
|
+
|
|
802
|
+
To replace the content view of a built-in type (e.g. text) — or attach a custom long-press option to it — start from the default template for that type, rebuild it with your closures, and apply via `add(templates:)`. `CometChatMessageTemplate` is a struct, so you create a NEW one (you cannot mutate a `let` from `getAllMessageTemplates`); copy `category`/`type` from the default and supply the closures you want.
|
|
803
|
+
|
|
804
|
+
```swift
|
|
805
|
+
let messageList = CometChatMessageList()
|
|
806
|
+
|
|
807
|
+
// Built-in text type identifiers (CometChatSDK constants):
|
|
808
|
+
// category = "message", type = "text" (matches MessagesDataSource.getTextMessageTemplate → "message"/"text")
|
|
809
|
+
let overriddenText = CometChatMessageTemplate(
|
|
810
|
+
category: "message",
|
|
811
|
+
type: "text",
|
|
812
|
+
contentView: { message, alignment, controller in // ← override the bubble content
|
|
813
|
+
let label = UILabel()
|
|
814
|
+
label.numberOfLines = 0
|
|
815
|
+
label.text = (message as? TextMessage)?.text
|
|
816
|
+
label.textColor = alignment == .right ? .white : .label
|
|
817
|
+
return label
|
|
818
|
+
},
|
|
819
|
+
bubbleView: nil, headerView: nil, footerView: nil, bottomView: nil,
|
|
820
|
+
options: { message, group, controller in // ← add a long-press option to text bubbles
|
|
821
|
+
let star = CometChatMessageOption(
|
|
822
|
+
id: "star",
|
|
823
|
+
title: "Star",
|
|
824
|
+
icon: UIImage(systemName: "star.fill"),
|
|
825
|
+
onItemClick: { msg in print("starred \(msg?.id ?? 0)") }
|
|
826
|
+
)
|
|
827
|
+
return [star]
|
|
828
|
+
}
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
// add(templates:) MERGES by "category_type" key — it overwrites the default text template
|
|
832
|
+
// with ours and leaves every OTHER built-in bubble intact (CometChatMessageList + Properties.swift:63).
|
|
833
|
+
messageList.add(templates: [overriddenText])
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### 7c. Decorator signatures (reference — registration is internal)
|
|
756
837
|
|
|
757
838
|
```swift
|
|
758
839
|
class CustomDataSource: DataSourceDecorator {
|
|
759
840
|
|
|
760
|
-
|
|
761
|
-
|
|
841
|
+
// ⚠️ Signature MUST match the protocol exactly — it takes `additionalConfiguration:`.
|
|
842
|
+
// Omitting the parameter does NOT override the kit method; your templates never appear.
|
|
843
|
+
override func getAllMessageTemplates(
|
|
844
|
+
additionalConfiguration: AdditionalConfiguration?
|
|
845
|
+
) -> [CometChatMessageTemplate] {
|
|
846
|
+
// Call super to KEEP every default template (text/image/video/file/…).
|
|
847
|
+
var templates = super.getAllMessageTemplates(additionalConfiguration: additionalConfiguration)
|
|
762
848
|
|
|
763
|
-
//
|
|
764
|
-
|
|
849
|
+
// Append — never replace the array, or all default bubbles disappear.
|
|
850
|
+
// ⚠️ Same init rule as §3: `category` first, then `type`, and ALL view-closure labels
|
|
851
|
+
// are required (pass nil). NO `CometChatMessageTemplate(type:category:)` shorthand exists.
|
|
852
|
+
let customTemplate = CometChatMessageTemplate(
|
|
853
|
+
category: "custom",
|
|
854
|
+
type: "custom_type",
|
|
855
|
+
contentView: { message, alignment, controller in UIView() },
|
|
856
|
+
bubbleView: nil, headerView: nil, footerView: nil, bottomView: nil, options: nil
|
|
857
|
+
)
|
|
765
858
|
templates.append(customTemplate)
|
|
766
859
|
|
|
767
860
|
return templates
|
|
768
861
|
}
|
|
862
|
+
|
|
863
|
+
// Add a composer attachment option WITHOUT wiping the defaults (photo/video/file/…).
|
|
864
|
+
// Same rule: start from super's list, then append.
|
|
865
|
+
// ⚠️ `additionalConfiguration: AdditionalConfiguration` is REQUIRED with NO default value
|
|
866
|
+
// in the protocol (DataSource.swift:74) and the decorator (DataSourceDecorator.swift:24).
|
|
867
|
+
// Do NOT add `= AdditionalConfiguration()` here — match the signature exactly.
|
|
868
|
+
override func getAttachmentOptions(
|
|
869
|
+
controller: UIViewController,
|
|
870
|
+
user: User?,
|
|
871
|
+
group: Group?,
|
|
872
|
+
id: [String: Any]?,
|
|
873
|
+
additionalConfiguration: AdditionalConfiguration
|
|
874
|
+
) -> [CometChatMessageComposerAction]? {
|
|
875
|
+
var options = super.getAttachmentOptions(
|
|
876
|
+
controller: controller, user: user, group: group,
|
|
877
|
+
id: id, additionalConfiguration: additionalConfiguration
|
|
878
|
+
) ?? []
|
|
879
|
+
// ⚠️ There is NO zero-arg `CometChatMessageComposerAction()` init. The only
|
|
880
|
+
// initializer requires id/text/startIcon/startIconTint/textColor/textFont
|
|
881
|
+
// (endIcon, tints, colors, border, onActionClick all default).
|
|
882
|
+
// Verified: CometChatMessageComposerAction.swift:28-56.
|
|
883
|
+
let location = CometChatMessageComposerAction(
|
|
884
|
+
id: "location",
|
|
885
|
+
text: "Send Location",
|
|
886
|
+
startIcon: UIImage(systemName: "location.fill"),
|
|
887
|
+
startIconTint: CometChatTheme.iconColorPrimary,
|
|
888
|
+
textColor: CometChatTheme.textColorPrimary,
|
|
889
|
+
textFont: CometChatTypography.Body.regular,
|
|
890
|
+
onActionClick: { /* present location picker, then send (see §8) */ }
|
|
891
|
+
)
|
|
892
|
+
options.append(location)
|
|
893
|
+
return options
|
|
894
|
+
}
|
|
769
895
|
|
|
770
896
|
override func getAllMessageTypes() -> [String]? {
|
|
771
897
|
var types = super.getAllMessageTypes() ?? []
|
|
@@ -779,42 +905,78 @@ class CustomDataSource: DataSourceDecorator {
|
|
|
779
905
|
return categories
|
|
780
906
|
}
|
|
781
907
|
|
|
908
|
+
// ⚠️ `additionalConfiguration: AdditionalConfiguration` is REQUIRED (no default) on this
|
|
909
|
+
// method too — omitting it means you DON'T override the protocol method and your option
|
|
910
|
+
// never appears. Verified: DataSource.swift:67, DataSourceDecorator.swift:36.
|
|
782
911
|
override func getMessageOptions(
|
|
783
912
|
loggedInUser: User,
|
|
784
913
|
messageObject: BaseMessage,
|
|
785
914
|
controller: UIViewController?,
|
|
786
|
-
group: Group
|
|
915
|
+
group: Group?,
|
|
916
|
+
additionalConfiguration: AdditionalConfiguration
|
|
787
917
|
) -> [CometChatMessageOption]? {
|
|
788
918
|
var options = super.getMessageOptions(
|
|
789
919
|
loggedInUser: loggedInUser,
|
|
790
920
|
messageObject: messageObject,
|
|
791
921
|
controller: controller,
|
|
792
|
-
group: group
|
|
922
|
+
group: group,
|
|
923
|
+
additionalConfiguration: additionalConfiguration
|
|
793
924
|
) ?? []
|
|
794
925
|
|
|
795
|
-
// Add custom option
|
|
926
|
+
// Add custom option. ⚠️ The click handler is `onItemClick: (BaseMessage?) -> Void`
|
|
927
|
+
// — there is NO `onClick` property and NO 4-arg closure. Set it via the initializer
|
|
928
|
+
// (it's a struct; `onItemClick` is the only callback). Verified: CometChatMessageOption.swift:30,33-45.
|
|
796
929
|
let customOption = CometChatMessageOption(
|
|
797
930
|
id: "custom_action",
|
|
798
931
|
title: "Custom Action",
|
|
799
|
-
icon: UIImage(systemName: "star.fill")
|
|
932
|
+
icon: UIImage(systemName: "star.fill"),
|
|
933
|
+
onItemClick: { message in
|
|
934
|
+
print("Custom action triggered for \(message?.id ?? 0)")
|
|
935
|
+
}
|
|
800
936
|
)
|
|
801
|
-
customOption.onClick = { _, _, _, _ in
|
|
802
|
-
print("Custom action triggered")
|
|
803
|
-
}
|
|
804
937
|
options.append(customOption)
|
|
805
938
|
|
|
806
939
|
return options
|
|
807
940
|
}
|
|
808
941
|
}
|
|
809
942
|
|
|
810
|
-
//
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
943
|
+
// ⚠️ NO PUBLIC REGISTRATION. The only installer, `ChatConfigurator.enable { dataSource in
|
|
944
|
+
// return CustomDataSource(dataSource: dataSource) }`, is INTERNAL to CometChatUIKitSwift
|
|
945
|
+
// and does NOT compile from app code (ChatConfigurator exposes no public members —
|
|
946
|
+
// uikit.swiftinterface:8591). Subclassing `ExtensionDataSource` does not help either: its
|
|
947
|
+
// base `addExtension()` is empty and the only way to make it do anything is to call the same
|
|
948
|
+
// internal `ChatConfigurator.enable` from inside it.
|
|
949
|
+
// → For app integration, use the public component setters in §7a / §7b instead.
|
|
950
|
+
// (This decorator block stands only as the authoritative signature reference, and works
|
|
951
|
+
// for code compiled INSIDE a kit fork.)
|
|
814
952
|
```
|
|
815
953
|
|
|
816
954
|
---
|
|
817
955
|
|
|
956
|
+
## 8. Sending a Custom Message — use the UIKit path, not the raw SDK
|
|
957
|
+
|
|
958
|
+
A custom `contentView`/template only renders messages of that `type`; you still have to **send** one. Use **`CometChatUIKit.sendCustomMessage(message:)`**, not `CometChat.sendCustomMessage(...)`. The UIKit wrapper stamps `muid` + sender and fires the `ccMessageSent` event, which is what makes the new bubble **append** to the open list. The raw SDK call skips those, giving the two classic failures: a "cannot determine recipient" state and the realtime message **replacing** an existing bubble instead of appending (no `muid` for dedup).
|
|
959
|
+
|
|
960
|
+
```swift
|
|
961
|
+
// Build with the receiver set — receiverUid + .user (or a guid + .group)
|
|
962
|
+
let custom = CustomMessage(
|
|
963
|
+
receiverUid: selectedUser.uid,
|
|
964
|
+
receiverType: .user, // CometChat.ReceiverType
|
|
965
|
+
customData: ["question": "Lunch?", "options": ["Yes", "No"]],
|
|
966
|
+
type: "custom_poll" // MUST match the template/contentView type
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
// ✅ kit path — sets muid + sender, emits ccMessageSent → list appends
|
|
970
|
+
CometChatUIKit.sendCustomMessage(message: custom)
|
|
971
|
+
|
|
972
|
+
// ❌ raw SDK — no muid/sender/event → recipient error + realtime replace
|
|
973
|
+
// CometChat.sendCustomMessage(message: custom, onSuccess: { _ in }, onError: { _ in })
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
Verified: `CustomMessage(receiverUid:receiverType:customData:type:)` (CometChatSDK) and static `CometChatUIKit.sendCustomMessage(message:)` (CometChatUIKitSwift).
|
|
977
|
+
|
|
978
|
+
---
|
|
979
|
+
|
|
818
980
|
## Best Practices
|
|
819
981
|
|
|
820
982
|
1. **Keep custom views lightweight** — Complex views affect scroll performance
|
|
@@ -823,3 +985,7 @@ ChatConfigurator.enable { dataSource in
|
|
|
823
985
|
4. **Test with real data** — Use actual conversations for testing
|
|
824
986
|
5. **Clean up listeners** — Remove event listeners when views are deallocated
|
|
825
987
|
6. **Use weak references** — Avoid retain cycles in closures
|
|
988
|
+
|
|
989
|
+
## Sound (in-app message + call sounds)
|
|
990
|
+
|
|
991
|
+
Sound is a customization sub-dimension. The UI Kit plays incoming/outgoing message + call sounds via `CometChatSoundManager` — mute it, swap custom audio, or play a specific sound. The full API + recipe lives in **`cometchat-ios-theming`** (Sound section). Verify the access path against the installed kit before relying on it.
|