@cometchat/skills 4.4.2 → 5.0.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/.claude-plugin/marketplace.json +55 -0
- package/.claude-plugin/plugin.json +14 -0
- package/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +41 -163
- package/RULES.md +114 -0
- package/bin/cometchat-skills.mjs +1180 -0
- package/bin/legacy-skills.json +95 -0
- package/catalogs/android-v6.json +1646 -0
- package/catalogs/flutter-v6.json +651 -0
- package/catalogs/ios-v5.json +1383 -0
- package/catalogs/rn-calls-v5.json +134 -0
- package/catalogs/rn-calls-v5.symbols.txt +58 -0
- package/catalogs/rn-sdk-v4.json +672 -0
- package/catalogs/rn-v5.json +449 -0
- package/catalogs/rn-v5.symbols.txt +216 -0
- package/catalogs/sdk-android-v5.json +514 -0
- package/contracts.android-calls-v5.json +122 -0
- package/contracts.android-v6.json +135 -0
- package/contracts.angular-v5.json +694 -0
- package/contracts.flutter-calls-v5.json +77 -0
- package/contracts.flutter-v6.json +126 -0
- package/contracts.ios-calls-v5.json +67 -0
- package/contracts.ios-v5.json +436 -0
- package/contracts.json +82 -0
- package/contracts.rn-calls-v5.json +77 -0
- package/contracts.rn-v5.json +727 -0
- package/contracts.sdk-android-v5.json +15 -0
- package/contracts.web-calls-v5.json +45 -0
- package/features.android-calls-v5.json +246 -0
- package/features.android-v6.json +65 -0
- package/features.angular-v5.json +521 -0
- package/features.flutter-calls-v5.json +286 -0
- package/features.flutter-v6.json +484 -0
- package/features.ios-calls-v5.json +236 -0
- package/features.ios-v5.json +573 -0
- package/features.json +61 -0
- package/features.rn-calls-v5.json +187 -0
- package/features.rn-v5.json +614 -0
- package/features.sdk-android-v5.json +40 -0
- package/features.sdk-jsv4.json +24 -0
- package/features.web-calls-v5.json +108 -0
- package/package.json +151 -74
- package/peers.yaml +312 -0
- package/registry/README.md +31 -0
- package/registry/android-calls-v5.json +54 -0
- package/registry/android-v6.json +137 -0
- package/registry/angular-v5.json +114 -0
- package/registry/flutter-calls-v5.json +54 -0
- package/registry/flutter-v6.json +119 -0
- package/registry/ios-calls-v5.json +59 -0
- package/registry/ios-v5.json +97 -0
- package/registry/rn-calls-v5.json +59 -0
- package/registry/rn-v5.json +129 -0
- package/registry/sdk-android-v5.json +53 -0
- package/registry/sdk-jsv4.json +53 -0
- package/registry/web-calls-v5.json +54 -0
- package/registry/web-v7.json +99 -0
- package/skills/cometchat/SKILL.md +42 -2096
- package/skills/cometchat-android-v5-calls-sdk/SKILL.md +206 -0
- package/skills/cometchat-android-v5-calls-sdk/references/build-truth.md +63 -0
- package/skills/cometchat-android-v5-calls-sdk/references/docs-map.md +119 -0
- package/skills/cometchat-android-v5-calls-sdk/references/method-map.md +53 -0
- package/skills/cometchat-android-v5-calls-sdk/references/pitfalls.md +72 -0
- package/skills/cometchat-android-v5-calls-sdk/references/ringing.md +92 -0
- package/skills/cometchat-android-v5-calls-sdk/references/user-switch.md +90 -0
- package/skills/cometchat-android-v5-sdk/SKILL.md +127 -0
- package/skills/cometchat-android-v5-sdk/references/app-surface.md +88 -0
- package/skills/cometchat-android-v5-sdk/references/docs-map.md +91 -0
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +51 -137
- package/skills/cometchat-android-v6-calls/SKILL.md +128 -413
- package/skills/cometchat-android-v6-compose-components/SKILL.md +84 -194
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +66 -411
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +154 -237
- package/skills/cometchat-android-v6-core/SKILL.md +236 -672
- package/skills/cometchat-android-v6-core/references/anti-patterns.md +31 -0
- package/skills/cometchat-android-v6-core/references/component-props.md +168 -0
- package/skills/cometchat-android-v6-core/references/docs-map.md +153 -0
- package/skills/cometchat-android-v6-core/references/layout.md +112 -0
- package/skills/cometchat-android-v6-core/references/lifecycle.md +75 -0
- package/skills/cometchat-android-v6-core/references/setup-credentials.md +105 -0
- package/skills/cometchat-android-v6-core/references/troubleshooting.md +36 -0
- package/skills/cometchat-android-v6-events/SKILL.md +46 -184
- package/skills/cometchat-android-v6-extensions/SKILL.md +39 -179
- package/skills/cometchat-android-v6-features/SKILL.md +74 -143
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +75 -193
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +67 -419
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +77 -223
- package/skills/cometchat-android-v6-migration/SKILL.md +67 -378
- package/skills/cometchat-android-v6-production/SKILL.md +40 -179
- package/skills/cometchat-android-v6-push/SKILL.md +39 -289
- package/skills/cometchat-android-v6-testing/SKILL.md +50 -265
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +70 -254
- package/skills/cometchat-angular-v5-calls/SKILL.md +193 -0
- package/skills/cometchat-angular-v5-components/SKILL.md +131 -0
- package/skills/cometchat-angular-v5-components/references/catalog.md +111 -0
- package/skills/cometchat-angular-v5-components/references/host-composed.md +46 -0
- package/skills/cometchat-angular-v5-core/SKILL.md +300 -0
- package/skills/cometchat-angular-v5-core/references/anti-patterns.md +49 -0
- package/skills/cometchat-angular-v5-core/references/component-props.md +55 -0
- package/skills/cometchat-angular-v5-core/references/dependencies.md +66 -0
- package/skills/cometchat-angular-v5-core/references/docs-map.md +132 -0
- package/skills/cometchat-angular-v5-core/references/layout.md +64 -0
- package/skills/cometchat-angular-v5-core/references/lifecycle.md +202 -0
- package/skills/cometchat-angular-v5-core/references/setup-credentials.md +137 -0
- package/skills/cometchat-angular-v5-core/references/theming.md +70 -0
- package/skills/cometchat-angular-v5-core/references/troubleshooting.md +27 -0
- package/skills/cometchat-angular-v5-customization/SKILL.md +94 -0
- package/skills/cometchat-angular-v5-features/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-features/references/custom-messages.md +133 -0
- package/skills/cometchat-angular-v5-features/references/formatters.md +28 -0
- package/skills/cometchat-angular-v5-features/references/host-composed-extensions.md +85 -0
- package/skills/cometchat-angular-v5-migration/SKILL.md +40 -0
- package/skills/cometchat-angular-v5-migration/references/migration-guide.md +165 -0
- package/skills/cometchat-angular-v5-patterns/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-placement/SKILL.md +133 -0
- package/skills/cometchat-angular-v5-placement/references/combined-app.md +174 -0
- package/skills/cometchat-angular-v5-placement/references/core-surface.md +199 -0
- package/skills/cometchat-angular-v5-production/SKILL.md +101 -0
- package/skills/cometchat-angular-v5-push/SKILL.md +61 -0
- package/skills/cometchat-angular-v5-testing/SKILL.md +112 -0
- package/skills/cometchat-angular-v5-troubleshooting/SKILL.md +96 -0
- package/skills/cometchat-flutter-v5-sdk/SKILL.md +188 -0
- package/skills/cometchat-flutter-v5-sdk/references/doc-corrections.md +55 -0
- package/skills/cometchat-flutter-v5-sdk/references/docs-map.md +211 -0
- package/skills/cometchat-flutter-v5-sdk/references/platform-notes.md +48 -0
- package/skills/cometchat-flutter-v5-sdk/references/transcription.md +87 -0
- package/skills/cometchat-flutter-v6-calls/SKILL.md +75 -389
- package/skills/cometchat-flutter-v6-components/SKILL.md +88 -361
- package/skills/cometchat-flutter-v6-core/SKILL.md +154 -593
- package/skills/cometchat-flutter-v6-core/references/anti-patterns.md +55 -0
- package/skills/cometchat-flutter-v6-core/references/docs-map.md +143 -0
- package/skills/cometchat-flutter-v6-core/references/layout.md +45 -0
- package/skills/cometchat-flutter-v6-core/references/lifecycle.md +87 -0
- package/skills/cometchat-flutter-v6-core/references/setup-credentials.md +84 -0
- package/skills/cometchat-flutter-v6-core/references/troubleshooting.md +26 -0
- package/skills/cometchat-flutter-v6-customization/SKILL.md +70 -712
- package/skills/cometchat-flutter-v6-events/SKILL.md +79 -174
- package/skills/cometchat-flutter-v6-features/SKILL.md +55 -394
- package/skills/cometchat-flutter-v6-migration/SKILL.md +68 -367
- package/skills/cometchat-flutter-v6-migration/references/migration-guide.md +131 -0
- package/skills/cometchat-flutter-v6-patterns/SKILL.md +61 -0
- package/skills/cometchat-flutter-v6-placement/SKILL.md +94 -381
- package/skills/cometchat-flutter-v6-production/SKILL.md +58 -615
- package/skills/cometchat-flutter-v6-push/SKILL.md +46 -455
- package/skills/cometchat-flutter-v6-testing/SKILL.md +68 -299
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +54 -878
- package/skills/cometchat-ios-calls/SKILL.md +112 -563
- package/skills/cometchat-ios-components/SKILL.md +44 -834
- package/skills/cometchat-ios-core/SKILL.md +181 -1068
- package/skills/cometchat-ios-core/references/anti-patterns.md +80 -0
- package/skills/cometchat-ios-core/references/docs-map.md +123 -0
- package/skills/cometchat-ios-core/references/install.md +23 -0
- package/skills/cometchat-ios-core/references/layout.md +186 -0
- package/skills/cometchat-ios-core/references/setup-credentials.md +197 -0
- package/skills/cometchat-ios-core/references/swiftui.md +91 -0
- package/skills/cometchat-ios-core/references/troubleshooting.md +100 -0
- package/skills/cometchat-ios-customization/SKILL.md +33 -968
- package/skills/cometchat-ios-features/SKILL.md +29 -738
- package/skills/cometchat-ios-migration/SKILL.md +39 -0
- package/skills/cometchat-ios-placement/SKILL.md +51 -729
- package/skills/cometchat-ios-push/SKILL.md +24 -602
- package/skills/cometchat-ios-v5-sdk/SKILL.md +161 -0
- package/skills/cometchat-ios-v5-sdk/references/docs-map.md +326 -0
- package/skills/cometchat-js-v5-sdk/SKILL.md +95 -0
- package/skills/cometchat-js-v5-sdk/references/docs-map.md +114 -0
- package/skills/cometchat-onboarding/SKILL.md +89 -0
- package/skills/cometchat-onboarding/references/archetypes.md +51 -0
- package/skills/cometchat-onboarding/references/calling-first.md +77 -0
- package/skills/cometchat-onboarding/references/not-in-this-pack.md +8 -0
- package/skills/cometchat-onboarding/references/plan-artifact.md +133 -0
- package/skills/cometchat-onboarding/references/platforms.md +90 -0
- package/skills/cometchat-react-native-bare-patterns/SKILL.md +120 -0
- package/skills/cometchat-react-native-calls/SKILL.md +200 -0
- package/skills/cometchat-react-native-components/SKILL.md +142 -0
- package/skills/cometchat-react-native-core/SKILL.md +313 -0
- package/skills/cometchat-react-native-core/references/anti-patterns.md +79 -0
- package/skills/cometchat-react-native-core/references/component-props.md +105 -0
- package/skills/cometchat-react-native-core/references/dependencies.md +62 -0
- package/skills/cometchat-react-native-core/references/docs-map.md +126 -0
- package/skills/cometchat-react-native-core/references/layout.md +61 -0
- package/skills/cometchat-react-native-core/references/lifecycle.md +64 -0
- package/skills/cometchat-react-native-core/references/setup-credentials.md +39 -0
- package/skills/cometchat-react-native-customization/SKILL.md +198 -0
- package/skills/cometchat-react-native-expo-patterns/SKILL.md +116 -0
- package/skills/cometchat-react-native-features/SKILL.md +122 -0
- package/skills/cometchat-react-native-migration/SKILL.md +103 -0
- package/skills/cometchat-react-native-placement/SKILL.md +158 -0
- package/skills/cometchat-react-native-production/SKILL.md +78 -0
- package/skills/cometchat-react-native-push/SKILL.md +88 -0
- package/skills/cometchat-react-native-sdk/SKILL.md +126 -0
- package/skills/cometchat-react-native-sdk/references/method-map.md +239 -0
- package/skills/cometchat-react-native-sdk/references/page-map.md +96 -0
- package/skills/cometchat-react-native-testing/SKILL.md +94 -0
- package/skills/cometchat-react-native-troubleshooting/SKILL.md +116 -0
- package/skills/cometchat-react-native-v5-sdk/SKILL.md +150 -0
- package/skills/cometchat-react-native-v5-sdk/references/docs-map.md +127 -0
- package/skills/cometchat-react-native-v5-sdk/references/ringing-voip.md +369 -0
- package/skills/cometchat-react-v7-calls/SKILL.md +75 -0
- package/skills/cometchat-react-v7-components/SKILL.md +72 -0
- package/skills/cometchat-react-v7-core/SKILL.md +101 -0
- package/skills/cometchat-react-v7-core/references/anti-patterns.md +19 -0
- package/skills/cometchat-react-v7-core/references/component-props.md +82 -0
- package/skills/cometchat-react-v7-core/references/dependencies.md +23 -0
- package/skills/cometchat-react-v7-core/references/docs-map.md +117 -0
- package/skills/cometchat-react-v7-core/references/i18n-rtl-a11y.md +22 -0
- package/skills/cometchat-react-v7-core/references/layout.md +158 -0
- package/skills/cometchat-react-v7-core/references/lifecycle.md +74 -0
- package/skills/cometchat-react-v7-core/references/setup-credentials.md +58 -0
- package/skills/cometchat-react-v7-core/references/ssr.md +11 -0
- package/skills/cometchat-react-v7-core/references/theming.md +52 -0
- package/skills/cometchat-react-v7-core/references/troubleshooting.md +28 -0
- package/skills/cometchat-react-v7-customization/SKILL.md +84 -0
- package/skills/cometchat-react-v7-features/SKILL.md +92 -0
- package/skills/cometchat-react-v7-migration/SKILL.md +39 -0
- package/skills/cometchat-react-v7-migration/references/migration-guide.md +119 -0
- package/skills/cometchat-react-v7-patterns/SKILL.md +43 -0
- package/skills/cometchat-react-v7-placement/SKILL.md +106 -0
- package/skills/cometchat-react-v7-placement/references/recipes.md +354 -0
- package/skills/cometchat-react-v7-push/SKILL.md +53 -0
- package/test-suite/README.md +70 -0
- package/test-suite/catalogs/android-calls-v5.json +830 -0
- package/test-suite/catalogs/android-calls-v5.symbols.txt +499 -0
- package/test-suite/catalogs/android-v6.json +1646 -0
- package/test-suite/catalogs/android-v6.symbols.txt +298 -0
- package/test-suite/catalogs/angular-v5.json +7587 -0
- package/test-suite/catalogs/flutter-calls-v5.json +196 -0
- package/test-suite/catalogs/flutter-calls-v5.symbols.txt +59 -0
- package/test-suite/catalogs/flutter-v6.json +651 -0
- package/test-suite/catalogs/ios-calls-v5.json +158 -0
- package/test-suite/catalogs/ios-calls-v5.symbols.txt +70 -0
- package/test-suite/catalogs/ios-v5.json +1383 -0
- package/test-suite/catalogs/ios-v5.symbols.txt +699 -0
- package/test-suite/catalogs/rn-calls-v5.json +134 -0
- package/test-suite/catalogs/rn-sdk-v4.json +672 -0
- package/test-suite/catalogs/rn-v5.json +449 -0
- package/test-suite/catalogs/sdk-android-v5.json +514 -0
- package/test-suite/catalogs/sdk-android-v5.symbols.txt +254 -0
- package/test-suite/catalogs/sdk-jsv4.json +800 -0
- package/test-suite/catalogs/web-calls-v5.json +195 -0
- package/test-suite/catalogs/web-v7.json +1243 -0
- package/test-suite/scripts/build-registry.mjs +113 -0
- package/test-suite/scripts/catalog-refresh-dart.mjs +151 -0
- package/test-suite/scripts/catalog-refresh.mjs +100 -0
- package/test-suite/scripts/lint-skills.mjs +909 -0
- package/test-suite/scripts/measure-tokens.mjs +169 -0
- package/test-suite/scripts/typecheck-fences-dart.mjs +437 -0
- package/test-suite/scripts/typecheck-fences-kotlin.mjs +269 -0
- package/test-suite/scripts/typecheck-fences.mjs +206 -0
- package/test-suite/scripts/verify-catalog.mjs +242 -0
- package/test-suite/scripts/verify-contract-fences.mjs +94 -0
- package/test-suite/scripts/verify-detection.mjs +178 -0
- package/test-suite/scripts/verify-docs-base.mjs +91 -0
- package/test-suite/scripts/verify-family-agnostic.mjs +130 -0
- package/test-suite/scripts/verify-golden-path.mjs +138 -0
- package/test-suite/scripts/verify-oracle-components.mjs +133 -0
- package/test-suite/scripts/verify-template-bindings.mjs +148 -0
- package/test-suite/typecheck/angular-v5/package.json +21 -0
- package/test-suite/typecheck/angular-v5/tsconfig.json +21 -0
- package/test-suite/typecheck/flutter-v6/analysis_options.yaml +25 -0
- package/test-suite/typecheck/flutter-v6/pubspec.yaml +21 -0
- package/test-suite/typecheck/web-v7/package.json +18 -0
- package/test-suite/typecheck/web-v7/tsconfig.json +19 -0
- package/bin/install.js +0 -1003
- package/skills/.claude-plugin/marketplace.json +0 -86
- package/skills/cometchat/references/asking-questions.md +0 -48
- package/skills/cometchat-a11y/SKILL.md +0 -477
- package/skills/cometchat-android-v5/SKILL.md +0 -121
- package/skills/cometchat-android-v5-calls/SKILL.md +0 -429
- package/skills/cometchat-android-v5-calls/references/README.md +0 -53
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +0 -197
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +0 -91
- package/skills/cometchat-android-v5-calls/references/background-handling.md +0 -168
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +0 -131
- package/skills/cometchat-android-v5-calls/references/call-logs.md +0 -113
- package/skills/cometchat-android-v5-calls/references/call-session.md +0 -274
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +0 -150
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +0 -123
- package/skills/cometchat-android-v5-calls/references/group-calls.md +0 -205
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +0 -117
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +0 -134
- package/skills/cometchat-android-v5-calls/references/join-session.md +0 -120
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +0 -222
- package/skills/cometchat-android-v5-calls/references/participant-management.md +0 -110
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +0 -106
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +0 -248
- package/skills/cometchat-android-v5-calls/references/recording.md +0 -101
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +0 -152
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +0 -78
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +0 -215
- package/skills/cometchat-android-v5-calls/references/session-settings.md +0 -121
- package/skills/cometchat-android-v5-calls/references/setup.md +0 -137
- package/skills/cometchat-android-v5-calls/references/share-invite.md +0 -156
- package/skills/cometchat-android-v5-calls/references/video-controls.md +0 -87
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +0 -526
- package/skills/cometchat-android-v5-components/SKILL.md +0 -431
- package/skills/cometchat-android-v5-core/SKILL.md +0 -486
- package/skills/cometchat-android-v5-customization/SKILL.md +0 -469
- package/skills/cometchat-android-v5-extensions/SKILL.md +0 -127
- package/skills/cometchat-android-v5-features/SKILL.md +0 -131
- package/skills/cometchat-android-v5-placement/SKILL.md +0 -277
- package/skills/cometchat-android-v5-production/SKILL.md +0 -95
- package/skills/cometchat-android-v5-push/SKILL.md +0 -619
- package/skills/cometchat-android-v5-testing/SKILL.md +0 -188
- package/skills/cometchat-android-v5-theming/SKILL.md +0 -167
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +0 -74
- package/skills/cometchat-android-v6/SKILL.md +0 -108
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +0 -97
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +0 -87
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +0 -100
- package/skills/cometchat-android-v6-calls/references/call-session.md +0 -163
- package/skills/cometchat-android-v6-calls/references/device-management.md +0 -172
- package/skills/cometchat-android-v6-calls/references/group-calls.md +0 -191
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +0 -110
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +0 -141
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +0 -188
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +0 -176
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +0 -127
- package/skills/cometchat-android-v6-calls/references/share-invite.md +0 -105
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +0 -250
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +0 -233
- package/skills/cometchat-angular-calls/SKILL.md +0 -380
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +0 -96
- package/skills/cometchat-angular-calls/references/call-layouts.md +0 -123
- package/skills/cometchat-angular-calls/references/call-session.md +0 -167
- package/skills/cometchat-angular-calls/references/custom-ui.md +0 -239
- package/skills/cometchat-angular-calls/references/device-management.md +0 -154
- package/skills/cometchat-angular-calls/references/group-calls.md +0 -433
- package/skills/cometchat-angular-calls/references/idle-timeout.md +0 -161
- package/skills/cometchat-angular-calls/references/in-call-chat.md +0 -148
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +0 -205
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +0 -53
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +0 -184
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +0 -285
- package/skills/cometchat-angular-calls/references/raise-hand.md +0 -172
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +0 -260
- package/skills/cometchat-angular-calls/references/ringing-integration.md +0 -133
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +0 -100
- package/skills/cometchat-angular-calls/references/share-invite.md +0 -122
- package/skills/cometchat-angular-calls/references/virtual-background.md +0 -29
- package/skills/cometchat-angular-components/SKILL.md +0 -235
- package/skills/cometchat-angular-core/SKILL.md +0 -386
- package/skills/cometchat-angular-customization/SKILL.md +0 -616
- package/skills/cometchat-angular-features/SKILL.md +0 -329
- package/skills/cometchat-angular-patterns/SKILL.md +0 -256
- package/skills/cometchat-angular-placement/SKILL.md +0 -314
- package/skills/cometchat-angular-production/SKILL.md +0 -564
- package/skills/cometchat-angular-push/SKILL.md +0 -389
- package/skills/cometchat-angular-testing/SKILL.md +0 -605
- package/skills/cometchat-angular-theming/SKILL.md +0 -290
- package/skills/cometchat-angular-troubleshooting/SKILL.md +0 -364
- package/skills/cometchat-astro-patterns/SKILL.md +0 -708
- package/skills/cometchat-calls/SKILL.md +0 -364
- package/skills/cometchat-calls/references/use-case-broadcast.md +0 -199
- package/skills/cometchat-calls/references/use-case-marketplace.md +0 -157
- package/skills/cometchat-calls/references/use-case-support.md +0 -189
- package/skills/cometchat-calls/references/use-case-team.md +0 -180
- package/skills/cometchat-calls/references/use-case-telehealth.md +0 -153
- package/skills/cometchat-components/SKILL.md +0 -1142
- package/skills/cometchat-core/SKILL.md +0 -1048
- package/skills/cometchat-customization/SKILL.md +0 -580
- package/skills/cometchat-customization/references/component-catalog.md +0 -236
- package/skills/cometchat-features/SKILL.md +0 -861
- package/skills/cometchat-flutter-v5/SKILL.md +0 -173
- package/skills/cometchat-flutter-v5-calls/SKILL.md +0 -455
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +0 -193
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +0 -103
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +0 -285
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +0 -124
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +0 -181
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +0 -99
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +0 -135
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +0 -210
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +0 -255
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +0 -196
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +0 -101
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +0 -148
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +0 -118
- package/skills/cometchat-flutter-v5-core/SKILL.md +0 -239
- package/skills/cometchat-flutter-v5-customization/SKILL.md +0 -358
- package/skills/cometchat-flutter-v5-events/SKILL.md +0 -156
- package/skills/cometchat-flutter-v5-messages/SKILL.md +0 -259
- package/skills/cometchat-flutter-v5-production/SKILL.md +0 -216
- package/skills/cometchat-flutter-v5-push/SKILL.md +0 -285
- package/skills/cometchat-flutter-v5-testing/SKILL.md +0 -401
- package/skills/cometchat-flutter-v5-theming/SKILL.md +0 -161
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +0 -130
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +0 -152
- package/skills/cometchat-flutter-v6/SKILL.md +0 -446
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +0 -136
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +0 -89
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +0 -229
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +0 -190
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +0 -88
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +0 -125
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +0 -275
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +0 -171
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +0 -93
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +0 -102
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +0 -238
- package/skills/cometchat-flutter-v6-messages/SKILL.md +0 -384
- package/skills/cometchat-flutter-v6-theming/SKILL.md +0 -293
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +0 -224
- package/skills/cometchat-i18n/SKILL.md +0 -419
- package/skills/cometchat-ios/SKILL.md +0 -325
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +0 -181
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +0 -45
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +0 -188
- package/skills/cometchat-ios-calls/references/call-layouts.md +0 -76
- package/skills/cometchat-ios-calls/references/call-session.md +0 -218
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +0 -357
- package/skills/cometchat-ios-calls/references/custom-ui.md +0 -322
- package/skills/cometchat-ios-calls/references/device-management.md +0 -171
- package/skills/cometchat-ios-calls/references/group-calls.md +0 -359
- package/skills/cometchat-ios-calls/references/idle-timeout.md +0 -184
- package/skills/cometchat-ios-calls/references/in-call-chat.md +0 -179
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +0 -196
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +0 -246
- package/skills/cometchat-ios-calls/references/raise-hand.md +0 -26
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +0 -252
- package/skills/cometchat-ios-calls/references/ringing-integration.md +0 -143
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +0 -267
- package/skills/cometchat-ios-calls/references/share-invite.md +0 -148
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +0 -246
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +0 -166
- package/skills/cometchat-ios-production/SKILL.md +0 -738
- package/skills/cometchat-ios-testing/SKILL.md +0 -376
- package/skills/cometchat-ios-theming/SKILL.md +0 -667
- package/skills/cometchat-ios-troubleshooting/SKILL.md +0 -1003
- package/skills/cometchat-native-bare-patterns/SKILL.md +0 -550
- package/skills/cometchat-native-calls/SKILL.md +0 -671
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +0 -203
- package/skills/cometchat-native-calls/references/call-layouts.md +0 -125
- package/skills/cometchat-native-calls/references/call-session.md +0 -182
- package/skills/cometchat-native-calls/references/custom-ui.md +0 -254
- package/skills/cometchat-native-calls/references/device-management.md +0 -158
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +0 -179
- package/skills/cometchat-native-calls/references/group-calls.md +0 -296
- package/skills/cometchat-native-calls/references/idle-timeout.md +0 -128
- package/skills/cometchat-native-calls/references/in-call-chat.md +0 -145
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +0 -72
- package/skills/cometchat-native-calls/references/picture-in-picture.md +0 -276
- package/skills/cometchat-native-calls/references/raise-hand.md +0 -205
- package/skills/cometchat-native-calls/references/recording-screen-share.md +0 -169
- package/skills/cometchat-native-calls/references/ringing-integration.md +0 -118
- package/skills/cometchat-native-calls/references/server-push-bridge.md +0 -135
- package/skills/cometchat-native-calls/references/server-push-payloads.md +0 -193
- package/skills/cometchat-native-calls/references/share-invite.md +0 -146
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +0 -319
- package/skills/cometchat-native-components/SKILL.md +0 -628
- package/skills/cometchat-native-core/SKILL.md +0 -679
- package/skills/cometchat-native-customization/SKILL.md +0 -716
- package/skills/cometchat-native-expo-patterns/SKILL.md +0 -552
- package/skills/cometchat-native-features/SKILL.md +0 -638
- package/skills/cometchat-native-placement/SKILL.md +0 -509
- package/skills/cometchat-native-production/SKILL.md +0 -700
- package/skills/cometchat-native-push/SKILL.md +0 -594
- package/skills/cometchat-native-testing/SKILL.md +0 -582
- package/skills/cometchat-native-theming/SKILL.md +0 -681
- package/skills/cometchat-native-troubleshooting/SKILL.md +0 -501
- package/skills/cometchat-nextjs-patterns/SKILL.md +0 -899
- package/skills/cometchat-placement/SKILL.md +0 -1360
- package/skills/cometchat-production/SKILL.md +0 -1027
- package/skills/cometchat-react-calls/SKILL.md +0 -752
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +0 -146
- package/skills/cometchat-react-calls/references/call-layouts.md +0 -160
- package/skills/cometchat-react-calls/references/call-session.md +0 -235
- package/skills/cometchat-react-calls/references/custom-ui.md +0 -247
- package/skills/cometchat-react-calls/references/device-management.md +0 -210
- package/skills/cometchat-react-calls/references/group-calls.md +0 -257
- package/skills/cometchat-react-calls/references/idle-timeout.md +0 -188
- package/skills/cometchat-react-calls/references/in-call-chat.md +0 -212
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +0 -170
- package/skills/cometchat-react-calls/references/picture-in-picture.md +0 -245
- package/skills/cometchat-react-calls/references/raise-hand.md +0 -238
- package/skills/cometchat-react-calls/references/recording-screen-share.md +0 -144
- package/skills/cometchat-react-calls/references/ringing-integration.md +0 -255
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +0 -241
- package/skills/cometchat-react-calls/references/share-invite.md +0 -175
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +0 -216
- package/skills/cometchat-react-calls/references/virtual-background.md +0 -32
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +0 -165
- package/skills/cometchat-react-patterns/SKILL.md +0 -628
- package/skills/cometchat-react-push/SKILL.md +0 -634
- package/skills/cometchat-react-router-patterns/SKILL.md +0 -758
- package/skills/cometchat-react-testing/SKILL.md +0 -413
- package/skills/cometchat-theming/SKILL.md +0 -498
- package/skills/cometchat-troubleshooting/SKILL.md +0 -294
|
@@ -1,1092 +1,205 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cometchat-ios-core
|
|
3
|
-
description: "
|
|
3
|
+
description: "Add CometChat chat to an iOS app end-to-end — detect the project, get & verify dashboard credentials, init→login→render, and the drop-in conversation UI composed into a chat screen. The core knowledge every other iOS skill builds on. Triggers: 'integrate cometchat swift', 'set up cometchat credentials ios', 'show conversations and messages ios'."
|
|
4
4
|
license: "MIT"
|
|
5
|
-
compatibility: "
|
|
5
|
+
compatibility: "Xcode 16+; iOS 15.1+ (the kit's deployment floor); Swift 5.0+; CometChatUIKitSwift 5.1.22 + CometChatSDK 4.1.7 + CometChatCallsSDK 5.0.3 (exact — see Install)"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "CometChat"
|
|
8
|
-
version: "
|
|
9
|
-
tags: "
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat ios swift uikit core chat integration v5 setup credentials"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
> **Ground truth:** `CometChatUIKitSwift
|
|
12
|
+
> **Ground truth:** `CometChatUIKitSwift` 5.1.22 (a prebuilt binary xcframework) + `CometChatSDK` 4.1.7. Every symbol below is verified against the shipped `.swiftinterface` (`catalogs/ios-v5.json`); the golden-path composition and its layout constraints are verified on a simulator by the native harness, not reasoned from the web pack. This file is the THIN map loaded every run; deep detail lives in `references/*`, loaded only when the task needs it.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
<!-- core is the companion the other iOS skills read; it has no Companion block of its own. -->
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Use this skill when
|
|
17
|
+
"add chat to my iOS app", "integrate CometChat in Swift", "set up CometChat credentials", "show a conversations + messages screen", "build a chat app". An unscoped "add chat" means a **production-ready core chat surface** — a `CometChatConversations` list that pushes to a chat screen you compose — NOT a bare list, and NOT the whole combined app. It **grows on request** (users/groups tabs, group details, threads, calls); those recipes live in `cometchat-ios-placement` and `cometchat-ios-features`.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
## Three things that are NOT like the web UI Kit
|
|
20
|
+
Setter-based API (not props) · **no** composite component in v5 (the `*WithMessages` names are v4) · navigation stack, not side-by-side panes. Full detail + why each one compiles-but-fails: `references/anti-patterns.md`.
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## 1. Installation
|
|
23
|
-
|
|
24
|
-
### 0. First — confirm a dependency manifest exists (or create one)
|
|
25
|
-
|
|
26
|
-
A freshly-created Xcode project (`File → New → App` from the GUI) ships **no `Podfile`, no `Package.swift`, and no Swift Package Manager refs in `*.xcodeproj/project.pbxproj`**. Before touching any of the integration code below, you MUST establish a dependency-management mechanism — otherwise `import CometChatUIKitSwift` will hit `Unable to resolve module dependency: 'CometChatSDK'` at the first build attempt and the entire integration is dead on arrival.
|
|
27
|
-
|
|
28
|
-
**Detection:**
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
ls Podfile Package.swift 2>/dev/null
|
|
32
|
-
grep -l "XCRemoteSwiftPackageReference\|repositoryURL.*cometchat" *.xcodeproj/project.pbxproj 2>/dev/null
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
If all three return empty → **fresh Xcode project, no dep manager**. Pick one and set it up before continuing:
|
|
36
|
-
|
|
37
|
-
**Option A — CocoaPods (most common, easiest to script):**
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
cd <project-root>
|
|
41
|
-
cat > Podfile <<'POD'
|
|
42
|
-
platform :ios, '13.0'
|
|
43
|
-
use_frameworks!
|
|
44
|
-
|
|
45
|
-
target 'YourAppTargetName' do
|
|
46
|
-
pod 'CometChatUIKitSwift', '~> 5.1'
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
post_install do |installer|
|
|
50
|
-
installer.pods_project.targets.each do |target|
|
|
51
|
-
target.build_configurations.each do |config|
|
|
52
|
-
config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO'
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
POD
|
|
57
|
-
pod install
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
After `pod install`, work from `YourApp.xcworkspace` (NOT `.xcodeproj`) — CocoaPods rewires the workspace to include the Pods project.
|
|
61
|
-
|
|
62
|
-
**Option B — Swift Package Manager (no Podfile, no `.xcworkspace`):**
|
|
63
|
-
|
|
64
|
-
The user must add the package via Xcode's GUI (the SPM dependency lives in `*.xcodeproj/project.pbxproj` and there's no clean CLI tooling to edit that file safely). Print these instructions verbatim:
|
|
65
|
-
|
|
66
|
-
> 1. Open `<YourApp>.xcodeproj` in Xcode
|
|
67
|
-
> 2. **File → Add Package Dependencies…**
|
|
68
|
-
> 3. Paste URL: `https://github.com/cometchat/cometchat-uikit-ios`
|
|
69
|
-
> 4. **Add Package** → keep "Up to Next Major Version" defaults → **Add Package** again
|
|
70
|
-
> 5. Confirm `CometChatUIKitSwift` appears under your app target's *Frameworks, Libraries, and Embedded Content*
|
|
71
|
-
|
|
72
|
-
**Then verify the package landed:**
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
grep -E "cometchat-uikit-ios|CometChatUIKitSwift" *.xcodeproj/project.pbxproj | head -2
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
If grep returns matches, the SPM dep is in. If it doesn't, the user didn't complete step 4 in Xcode — surface that explicitly and stop until they have.
|
|
79
|
-
|
|
80
|
-
**HARD STOP if neither option is in place.** Do not write `import CometChatUIKitSwift` into any Swift file until either `pod install` completes successfully or the SPM grep above returns matches. Skipping this step produces an integration that compiles only after the user does extra setup work — a worse outcome than asking them up-front.
|
|
81
|
-
|
|
82
|
-
### CocoaPods (full reference — only if you skipped Option A above)
|
|
83
|
-
|
|
84
|
-
Add to your `Podfile`:
|
|
22
|
+
## Install — Swift Package Manager only
|
|
23
|
+
**SPM only. Never CocoaPods**, even if a `Podfile` exists (its distribution is winding down; a Podfile is a detection signal, not an instruction). Add three packages at EXACT versions — the kit is a prebuilt binary compiled against one Chat SDK version and SPM will not resolve that transitively: `CometChatUIKitSwift` **5.1.22** · `CometChatSDK` **4.1.7** · `CometChatCallsSDK` **5.0.3** (required even for chat-only — see `references/install.md` for the repos, the Calls-SDK reason, and the Xcode steps).
|
|
85
24
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
25
|
+
## Setup & credentials (essentials — full chain: `references/setup-credentials.md`)
|
|
26
|
+
1. **Detect** the project shape AND its lifecycle — a stock Xcode project is a SwiftUI `@main App` with **no AppDelegate/SceneDelegate**, so there is no launch hook for `init → login` until you add one (`references/swiftui.md`). A `Podfile` is a detection signal only; integrate via SPM.
|
|
27
|
+
2. **version_conflict — STOP** if a non-v5 kit is installed (v4 shows `*WithMessages` components). Reconcile first, never mix majors (`RULES.md`); v4 → v5 is `cometchat-ios-migration`.
|
|
28
|
+
3. **Credentials — OFFER to fetch from the dashboard FIRST; never silently default to "paste it yourself."** Load the CLI on demand (`references/setup-credentials.md` has the exact command), ask which EXISTING app, never auto-create. Manual paste is the fallback.
|
|
29
|
+
4. **Wire them**: gitignored `Secrets.xcconfig` → ATTACH to the build configurations → DECLARE each key in `Info.plist` as `$(COMETCHAT_APP_ID)` → read via `Bundle.main`, rejecting the literal `$(`. Miss a step and you get the literal, not the value. Modern projects generate `Info.plist` and cannot take custom keys through build settings — `references/setup-credentials.md` §2-§3.
|
|
30
|
+
5. **Authorize** = init and login both resolve. An auth failure is usually the wrong Region.
|
|
89
31
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
end
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Then run:
|
|
96
|
-
```bash
|
|
97
|
-
pod install
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**Important: Disable User Script Sandboxing (Xcode 15+)**
|
|
101
|
-
|
|
102
|
-
After running `pod install`, you must disable user script sandboxing in your project's Build Settings:
|
|
103
|
-
|
|
104
|
-
1. Open your `.xcworkspace` file
|
|
105
|
-
2. Select your app target
|
|
106
|
-
3. Go to **Build Settings**
|
|
107
|
-
4. Search for "User Script Sandboxing"
|
|
108
|
-
5. Set **ENABLE_USER_SCRIPT_SANDBOXING** to **No**
|
|
109
|
-
|
|
110
|
-
Or add this to your `Podfile` to do it automatically:
|
|
111
|
-
|
|
112
|
-
```ruby
|
|
113
|
-
post_install do |installer|
|
|
114
|
-
installer.pods_project.targets.each do |target|
|
|
115
|
-
target.build_configurations.each do |config|
|
|
116
|
-
config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO'
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Swift Package Manager
|
|
123
|
-
|
|
124
|
-
Add the package URL in Xcode (File → Add Package Dependencies):
|
|
125
|
-
|
|
126
|
-
**CometChat UI Kit (includes SDK):**
|
|
127
|
-
```
|
|
128
|
-
https://github.com/cometchat/cometchat-uikit-ios
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**CometChat SDK only (if needed separately):**
|
|
132
|
-
```
|
|
133
|
-
https://github.com/cometchat/chat-sdk-ios
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**CometChat Calls SDK (for voice/video calls):**
|
|
137
|
-
```
|
|
138
|
-
https://github.com/cometchat/calls-sdk-ios
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Or add to `Package.swift`:
|
|
142
|
-
```swift
|
|
143
|
-
dependencies: [
|
|
144
|
-
.package(url: "https://github.com/cometchat/cometchat-uikit-ios", from: "5.0.0"),
|
|
145
|
-
// Optional: Add calls SDK for voice/video
|
|
146
|
-
// .package(url: "https://github.com/cometchat/calls-sdk-ios", from: "5.0.0") // requires iOS 16+
|
|
147
|
-
]
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### GitHub Repositories
|
|
151
|
-
|
|
152
|
-
| Package | Repository | Description |
|
|
153
|
-
|---------|------------|-------------|
|
|
154
|
-
| UI Kit | https://github.com/cometchat/cometchat-uikit-ios | Ready-to-use UI components |
|
|
155
|
-
| Chat SDK | https://github.com/cometchat/chat-sdk-ios | Core messaging SDK |
|
|
156
|
-
| Calls SDK | https://github.com/cometchat/calls-sdk-ios | Voice & video calling |
|
|
157
|
-
| Sample App | https://github.com/cometchat/cometchat-sample-app-ios | Sample implementation |
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## 2. Initialization
|
|
162
|
-
|
|
163
|
-
CometChat must be initialized exactly once before any UI component is used. Initialization is asynchronous and must complete fully before mounting any `CometChat*` view controller.
|
|
164
|
-
|
|
165
|
-
### File-based init with `cometchat-settings.json` (recommended)
|
|
166
|
-
|
|
167
|
-
> **Version requirement (ENG-35866 — Skills Telemetry).** `CometChatUIKit.initFromSettings(completion:)` reads a bundled `cometchat-settings.json` and lets the SDK self-report `integrationSource = "ai-agent"` to `/user_sessions`. It ships GA in **`CometChatUIKitSwift >= 5.1.15`** (public CocoaPods + SPM; pulls `CometChatSDK 4.1.x`). The `~> 5.1` Pod range / `from: "5.0.0"` SPM range below already resolve it. On an older UI Kit (`< 5.1.15`) the method does not exist — use the **`UIKitSettings` builder fallback** below.
|
|
168
|
-
|
|
169
|
-
Unlike the web/RN kits, the iOS `initFromSettings` takes **no settings argument** — it reads the file straight from the app bundle, so the file must be added to the target's **Copy Bundle Resources**.
|
|
170
|
-
|
|
171
|
-
**Step 1 — create `cometchat-settings.json`** and add it to the app target (`File → Add Files…`, *and* confirm it appears under *Build Phases → Copy Bundle Resources*). Fill `appId` / `region` / `credentials.authKey`; leave the rest at the defaults:
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"appId": "APP_ID_HERE",
|
|
176
|
-
"region": "us",
|
|
177
|
-
"credentials": {
|
|
178
|
-
"authKey": "AUTH_KEY_HERE"
|
|
179
|
-
},
|
|
180
|
-
"chatSDK": {
|
|
181
|
-
"presenceSubscription": {
|
|
182
|
-
"type": "ALL_USERS",
|
|
183
|
-
"roles": []
|
|
184
|
-
},
|
|
185
|
-
"autoEstablishSocketConnection": true,
|
|
186
|
-
"adminHost": null,
|
|
187
|
-
"clientHost": null
|
|
188
|
-
},
|
|
189
|
-
"callsSDK": {
|
|
190
|
-
"host": null,
|
|
191
|
-
"adminHost": null,
|
|
192
|
-
"clientHost": null,
|
|
193
|
-
"callsHost": null
|
|
194
|
-
},
|
|
195
|
-
"uiKit": {
|
|
196
|
-
"subscribePresenceForAllUsers": true
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**Step 2 — init (no builder, no args — the SDK reads the bundled file):**
|
|
202
|
-
|
|
203
|
-
```swift
|
|
204
|
-
// initFromSettings ships GA in CometChatUIKitSwift >= 5.1.15 (ENG-35866)
|
|
205
|
-
import CometChatUIKitSwift
|
|
206
|
-
|
|
207
|
-
CometChatUIKit.initFromSettings { success, error in
|
|
208
|
-
if let error = error {
|
|
209
|
-
print("CometChat init failed: \(error.errorCode) — \(error.errorDescription)")
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
print("CometChat initialized")
|
|
213
|
-
// then: CometChatUIKit.login(uid:) — see §3
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
- If init throws `cometchat-settings.json not found`, the file isn't in **Copy Bundle Resources** — add it there (adding it to the project navigator alone is not enough).
|
|
218
|
-
- **Commit `cometchat-settings.json` — do not gitignore it** (the file is part of the integration). Its `authKey` is an **optional demo/POC credential**: a quick-start affordance so a PM or developer can see working chat *before* the backend auth-token flow is wired (that flow often waits on internal approvals). Because the file is committed to source control, treat the key as public — use a **dedicated demo CometChat app** (a committed key trips secret scanners and stays in git history; never reuse a production app's key). Switch to a server-minted `authToken` via `loginWithAuthToken` before production, where `authKey` must not ship.
|
|
219
|
-
|
|
220
|
-
### UIKitSettings Builder (fallback — UI Kit before file-based init)
|
|
221
|
-
|
|
222
|
-
```swift
|
|
223
|
-
import CometChatUIKitSwift
|
|
224
|
-
|
|
225
|
-
let uiKitSettings = UIKitSettings()
|
|
226
|
-
.set(appID: "YOUR_APP_ID")
|
|
227
|
-
.set(authKey: "YOUR_AUTH_KEY") // Required for dev mode
|
|
228
|
-
.set(region: "us") // "us", "eu", or "in"
|
|
229
|
-
.subscribePresenceForAllUsers() // Enable online/offline indicators
|
|
230
|
-
.build()
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Init must happen once
|
|
234
|
-
|
|
235
|
-
Use a singleton manager to prevent double-init:
|
|
32
|
+
## Integration ordering (BAKED — invariant)
|
|
33
|
+
`init` → `login` → **only then** render. Both are async and both must COMPLETE before the next step. Calling `login()` before init resolves fails **silently** — no crash, no error, just a screen that never populates.
|
|
236
34
|
|
|
237
35
|
```swift
|
|
238
36
|
import CometChatUIKitSwift
|
|
239
37
|
import CometChatSDK
|
|
240
38
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
private init() {}
|
|
248
|
-
|
|
249
|
-
func initialize(
|
|
250
|
-
appID: String,
|
|
251
|
-
authKey: String,
|
|
252
|
-
region: String,
|
|
253
|
-
completion: @escaping (Result<Bool, Error>) -> Void
|
|
254
|
-
) {
|
|
255
|
-
guard !isInitialized else {
|
|
256
|
-
completion(.success(true))
|
|
257
|
-
return
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
let uiKitSettings = UIKitSettings()
|
|
261
|
-
.set(appID: appID)
|
|
262
|
-
.set(authKey: authKey)
|
|
263
|
-
.set(region: region)
|
|
264
|
-
.subscribePresenceForAllUsers()
|
|
265
|
-
.build()
|
|
266
|
-
|
|
267
|
-
CometChatUIKit(uiKitSettings: uiKitSettings) { result in
|
|
268
|
-
switch result {
|
|
269
|
-
case .success(let success):
|
|
270
|
-
self.isInitialized = success
|
|
271
|
-
completion(.success(success))
|
|
272
|
-
case .failure(let error):
|
|
273
|
-
self.initializationError = error
|
|
274
|
-
completion(.failure(error))
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Init in AppDelegate (UIKit apps)
|
|
282
|
-
|
|
283
|
-
> **Scene-based app (the modern Xcode default — has a `SceneDelegate.swift`)?** Init in `scene(_:willConnectTo:)` instead — that's the canonical pattern the reference app uses (see "Init code — SceneDelegate (canonical)" below). The `didFinishLaunchingWithOptions` example here is correct for the **SDK init call itself** (it needs no window), but scene-based apps that load settings + apply theme + set the root view controller in one pass should do all of it in `scene(_:willConnectTo:)`, where the window/scene exists. Use this AppDelegate form only for apps with no SceneDelegate.
|
|
284
|
-
|
|
285
|
-
```swift
|
|
286
|
-
import UIKit
|
|
287
|
-
import CometChatUIKitSwift
|
|
288
|
-
|
|
289
|
-
@main
|
|
290
|
-
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
291
|
-
|
|
292
|
-
func application(
|
|
293
|
-
_ application: UIApplication,
|
|
294
|
-
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
295
|
-
) -> Bool {
|
|
296
|
-
|
|
297
|
-
CometChatManager.shared.initialize(
|
|
298
|
-
appID: "YOUR_APP_ID",
|
|
299
|
-
authKey: "YOUR_AUTH_KEY",
|
|
300
|
-
region: "us"
|
|
301
|
-
) { result in
|
|
302
|
-
switch result {
|
|
303
|
-
case .success:
|
|
304
|
-
print("CometChat initialized successfully")
|
|
305
|
-
case .failure(let error):
|
|
306
|
-
print("CometChat initialization failed: \(error)")
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return true
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Init in App struct (SwiftUI apps)
|
|
316
|
-
|
|
317
|
-
```swift
|
|
318
|
-
import SwiftUI
|
|
319
|
-
import CometChatUIKitSwift
|
|
320
|
-
|
|
321
|
-
@main
|
|
322
|
-
struct YourApp: App {
|
|
323
|
-
|
|
324
|
-
init() {
|
|
325
|
-
CometChatManager.shared.initialize(
|
|
326
|
-
appID: "YOUR_APP_ID",
|
|
327
|
-
authKey: "YOUR_AUTH_KEY",
|
|
328
|
-
region: "us"
|
|
329
|
-
) { result in
|
|
330
|
-
switch result {
|
|
331
|
-
case .success:
|
|
332
|
-
print("CometChat initialized successfully")
|
|
333
|
-
case .failure(let error):
|
|
334
|
-
print("CometChat initialization failed: \(error)")
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
var body: some Scene {
|
|
340
|
-
WindowGroup {
|
|
341
|
-
ContentView()
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## 3. Login
|
|
350
|
-
|
|
351
|
-
### Development mode
|
|
352
|
-
|
|
353
|
-
Use `CometChatUIKit.login(uid:)` with a test UID. Every new CometChat app comes with five pre-created test users: `cometchat-uid-1` through `cometchat-uid-5`.
|
|
354
|
-
|
|
355
|
-
**Important:** The login callback uses `.success` and `.onError` cases, NOT Swift's standard `Result` type.
|
|
356
|
-
|
|
357
|
-
```swift
|
|
358
|
-
CometChatUIKit.login(uid: "cometchat-uid-1") { result in
|
|
359
|
-
switch result {
|
|
360
|
-
case .success(let user):
|
|
361
|
-
print("Logged in as: \(user.name ?? "")")
|
|
362
|
-
// Proceed to chat UI
|
|
363
|
-
case .onError(let error):
|
|
364
|
-
print("Login failed: \(error.errorDescription)")
|
|
365
|
-
@unknown default:
|
|
366
|
-
break
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### Production mode
|
|
372
|
-
|
|
373
|
-
Use `CometChatUIKit.login(authToken:)` with a token obtained from your backend:
|
|
374
|
-
|
|
375
|
-
```swift
|
|
376
|
-
CometChatUIKit.login(authToken: authToken) { result in
|
|
377
|
-
switch result {
|
|
378
|
-
case .success(let user):
|
|
379
|
-
print("Logged in as: \(user.name ?? "")")
|
|
380
|
-
case .onError(let error):
|
|
381
|
-
print("Login failed: \(error.errorDescription)")
|
|
382
|
-
@unknown default:
|
|
383
|
-
break
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Getting the current logged-in user
|
|
389
|
-
|
|
390
|
-
```swift
|
|
391
|
-
// Synchronous — use when you know init is complete
|
|
392
|
-
if let currentUser = CometChatUIKit.getLoggedInUser() {
|
|
393
|
-
print("Logged in as: \(currentUser.name ?? "")")
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### Logout
|
|
39
|
+
let settings = UIKitSettings()
|
|
40
|
+
.set(appID: appID) // from Secrets.xcconfig — never a literal
|
|
41
|
+
.set(region: region)
|
|
42
|
+
.set(authKey: authKey) // DEV ONLY; prod uses login(authToken:)
|
|
43
|
+
.subscribePresenceForAllUsers()
|
|
44
|
+
.build()
|
|
398
45
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
46
|
+
// ATTRIBUTION FIRST, then the credential-bearing init — BOTH, in this order.
|
|
47
|
+
// `initFromSettings` stamps integrationSource = "ai-agent". It takes no parameters because it
|
|
48
|
+
// reads a bundled `cometchat-settings.json` (see references/setup-credentials.md §6). Skip it and
|
|
49
|
+
// the app is stamped "manual" — attributed to a hand-written integration, which is worse than
|
|
50
|
+
// unattributed. On 5.1.19 it does NOT initialise the UI Kit layer, so calling it INSTEAD of the
|
|
51
|
+
// classic init makes login fail with Err_101; it runs BEFORE, never in place of.
|
|
52
|
+
CometChatUIKit.initFromSettings { _, _ in
|
|
53
|
+
// Ignore the result deliberately: attribution is best-effort. A missing or malformed
|
|
54
|
+
// settings file must not stop the app from initialising below.
|
|
55
|
+
CometChatUIKit(uiKitSettings: settings) { result in
|
|
402
56
|
switch result {
|
|
403
57
|
case .success:
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
---
|
|
415
|
-
|
|
416
|
-
## 3.1 Error Handling
|
|
417
|
-
|
|
418
|
-
CometChat uses `CometChatException` for errors. **Important:** Use `errorDescription` property, NOT `localizedDescription`.
|
|
419
|
-
|
|
420
|
-
### CometChatException Properties
|
|
421
|
-
|
|
422
|
-
```swift
|
|
423
|
-
// CometChatException has these properties:
|
|
424
|
-
error.errorCode // String - error code like "ERR_UID_NOT_FOUND"
|
|
425
|
-
error.errorDescription // String - human-readable description
|
|
426
|
-
// NOTE: CometChatException exposes ONLY errorCode + errorDescription.
|
|
427
|
-
// There is no `details` property — don't reference one.
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### Correct Error Handling
|
|
431
|
-
|
|
432
|
-
```swift
|
|
433
|
-
CometChatUIKit.login(uid: "user-123") { result in
|
|
434
|
-
switch result {
|
|
435
|
-
case .success(let user):
|
|
436
|
-
print("Logged in: \(user.name ?? "")")
|
|
437
|
-
case .onError(let error):
|
|
438
|
-
print("Error: \(error.errorDescription)")
|
|
439
|
-
print("Code: \(error.errorCode)")
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
### Error Handling in Closures
|
|
445
|
-
|
|
446
|
-
```swift
|
|
447
|
-
// For onError closures where error might be optional:
|
|
448
|
-
CometChat.getUser(UID: "user-123") { user in
|
|
449
|
-
print("User: \(user?.name ?? "")")
|
|
450
|
-
} onError: { error in
|
|
451
|
-
// error is CometChatException? (optional)
|
|
452
|
-
print("Error: \(error?.errorDescription ?? "Unknown error")")
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// For ApiStatus enum results:
|
|
456
|
-
CometChatUIKit.create(user: newUser) { result in
|
|
457
|
-
switch result {
|
|
458
|
-
case .success(let user):
|
|
459
|
-
print("Created: \(user.name ?? "")")
|
|
460
|
-
case .onError(let error):
|
|
461
|
-
// error is CometChatException (non-optional)
|
|
462
|
-
print("Error: \(error.errorDescription)")
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### Common Error Codes
|
|
468
|
-
|
|
469
|
-
| Code | Description |
|
|
470
|
-
|---|---|
|
|
471
|
-
| `ERR_UID_NOT_FOUND` | User doesn't exist |
|
|
472
|
-
| `ERR_ALREADY_LOGGED_IN` | User already logged in |
|
|
473
|
-
| `ERR_NOT_LOGGED_IN` | No active session |
|
|
474
|
-
| `AUTH_ERR_AUTH_TOKEN_NOT_FOUND` | Invalid auth token |
|
|
475
|
-
| `ERR_INVALID_APP_ID` | Wrong App ID |
|
|
476
|
-
| `ERR_INVALID_API_KEY` | Wrong API/Auth Key |
|
|
477
|
-
|
|
478
|
-
---
|
|
479
|
-
|
|
480
|
-
## 4. Credentials Management
|
|
481
|
-
|
|
482
|
-
### Using a Constants file (Development)
|
|
483
|
-
|
|
484
|
-
```swift
|
|
485
|
-
// Constants.swift
|
|
486
|
-
struct CometChatConstants {
|
|
487
|
-
static let appID = "YOUR_APP_ID"
|
|
488
|
-
static let authKey = "YOUR_AUTH_KEY"
|
|
489
|
-
static let region = "us"
|
|
490
|
-
}
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
**Important:** Add `Constants.swift` to `.gitignore` for production apps.
|
|
494
|
-
|
|
495
|
-
### Using Info.plist
|
|
496
|
-
|
|
497
|
-
Add keys to your `Info.plist`:
|
|
498
|
-
```xml
|
|
499
|
-
<key>CometChatAppID</key>
|
|
500
|
-
<string>YOUR_APP_ID</string>
|
|
501
|
-
<key>CometChatAuthKey</key>
|
|
502
|
-
<string>YOUR_AUTH_KEY</string>
|
|
503
|
-
<key>CometChatRegion</key>
|
|
504
|
-
<string>us</string>
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
Read them in code:
|
|
508
|
-
```swift
|
|
509
|
-
guard let appID = Bundle.main.object(forInfoDictionaryKey: "CometChatAppID") as? String,
|
|
510
|
-
let authKey = Bundle.main.object(forInfoDictionaryKey: "CometChatAuthKey") as? String,
|
|
511
|
-
let region = Bundle.main.object(forInfoDictionaryKey: "CometChatRegion") as? String else {
|
|
512
|
-
fatalError("CometChat credentials not found in Info.plist")
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### Using xcconfig files (Recommended for production)
|
|
517
|
-
|
|
518
|
-
Create `Debug.xcconfig` and `Release.xcconfig`:
|
|
519
|
-
```
|
|
520
|
-
// Debug.xcconfig
|
|
521
|
-
COMETCHAT_APP_ID = your_app_id
|
|
522
|
-
COMETCHAT_AUTH_KEY = your_auth_key
|
|
523
|
-
COMETCHAT_REGION = us
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
Reference in `Info.plist`:
|
|
527
|
-
```xml
|
|
528
|
-
<key>CometChatAppID</key>
|
|
529
|
-
<string>$(COMETCHAT_APP_ID)</string>
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
---
|
|
533
|
-
|
|
534
|
-
## 5. The Manager Pattern
|
|
535
|
-
|
|
536
|
-
The recommended pattern for iOS is a singleton manager that handles initialization, login state, and provides a clean API for the rest of the app.
|
|
537
|
-
|
|
538
|
-
### Complete CometChatManager
|
|
539
|
-
|
|
540
|
-
**Important:** `CometChatException` does NOT conform to Swift's `Error` protocol. Use `CometChatException` directly in your callbacks, not `Result<T, Error>`.
|
|
541
|
-
|
|
542
|
-
```swift
|
|
543
|
-
import Foundation
|
|
544
|
-
import CometChatUIKitSwift
|
|
545
|
-
import CometChatSDK
|
|
546
|
-
|
|
547
|
-
final class CometChatManager {
|
|
548
|
-
|
|
549
|
-
// MARK: - Singleton
|
|
550
|
-
static let shared = CometChatManager()
|
|
551
|
-
|
|
552
|
-
// MARK: - State
|
|
553
|
-
private(set) var isInitialized = false
|
|
554
|
-
private(set) var currentUser: User?
|
|
555
|
-
|
|
556
|
-
// MARK: - Callbacks
|
|
557
|
-
var onLoginStateChanged: ((User?) -> Void)?
|
|
558
|
-
|
|
559
|
-
private init() {}
|
|
560
|
-
|
|
561
|
-
// MARK: - Initialization
|
|
562
|
-
func initialize(
|
|
563
|
-
appID: String,
|
|
564
|
-
authKey: String,
|
|
565
|
-
region: String,
|
|
566
|
-
completion: @escaping (Bool, CometChatException?) -> Void
|
|
567
|
-
) {
|
|
568
|
-
guard !isInitialized else {
|
|
569
|
-
completion(true, nil)
|
|
570
|
-
return
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
let uiKitSettings = UIKitSettings()
|
|
574
|
-
.set(appID: appID)
|
|
575
|
-
.set(authKey: authKey)
|
|
576
|
-
.set(region: region)
|
|
577
|
-
.subscribePresenceForAllUsers()
|
|
578
|
-
.build()
|
|
579
|
-
|
|
580
|
-
CometChatUIKit.init(uiKitSettings: uiKitSettings) { [weak self] result in
|
|
581
|
-
DispatchQueue.main.async {
|
|
582
|
-
switch result {
|
|
583
|
-
case .success(let success):
|
|
584
|
-
self?.isInitialized = success
|
|
585
|
-
self?.currentUser = CometChatUIKit.getLoggedInUser()
|
|
586
|
-
completion(success, nil)
|
|
587
|
-
case .failure(let error):
|
|
588
|
-
completion(false, error as? CometChatException)
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// MARK: - Login with UID (Development)
|
|
595
|
-
func login(uid: String, completion: @escaping (User?, CometChatException?) -> Void) {
|
|
596
|
-
guard isInitialized else {
|
|
597
|
-
print("CometChat not initialized")
|
|
598
|
-
completion(nil, nil)
|
|
599
|
-
return
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
if let user = currentUser {
|
|
603
|
-
completion(user, nil)
|
|
604
|
-
return
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
CometChatUIKit.login(uid: uid) { [weak self] result in
|
|
608
|
-
DispatchQueue.main.async {
|
|
609
|
-
switch result {
|
|
610
|
-
case .success(let user):
|
|
611
|
-
self?.currentUser = user
|
|
612
|
-
self?.onLoginStateChanged?(user)
|
|
613
|
-
completion(user, nil)
|
|
614
|
-
case .onError(let error):
|
|
615
|
-
completion(nil, error)
|
|
616
|
-
@unknown default:
|
|
617
|
-
completion(nil, nil)
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// MARK: - Login with Auth Token (Production)
|
|
624
|
-
func loginWithToken(_ authToken: String, completion: @escaping (User?, CometChatException?) -> Void) {
|
|
625
|
-
guard isInitialized else {
|
|
626
|
-
print("CometChat not initialized")
|
|
627
|
-
completion(nil, nil)
|
|
628
|
-
return
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
CometChatUIKit.login(authToken: authToken) { [weak self] result in
|
|
632
|
-
DispatchQueue.main.async {
|
|
633
|
-
switch result {
|
|
634
|
-
case .success(let user):
|
|
635
|
-
self?.currentUser = user
|
|
636
|
-
self?.onLoginStateChanged?(user)
|
|
637
|
-
completion(user, nil)
|
|
638
|
-
case .onError(let error):
|
|
639
|
-
completion(nil, error)
|
|
640
|
-
@unknown default:
|
|
641
|
-
completion(nil, nil)
|
|
642
|
-
}
|
|
58
|
+
// Guard re-login: getLoggedInUser() is SYNCHRONOUS.
|
|
59
|
+
// This init callback is NOT guaranteed on the main queue — hop before any UI work.
|
|
60
|
+
guard CometChatUIKit.getLoggedInUser() == nil else {
|
|
61
|
+
DispatchQueue.main.async { showChat() }
|
|
62
|
+
return
|
|
643
63
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
completion(true, nil)
|
|
651
|
-
return
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
CometChatUIKit.logout(user: user) { [weak self] result in
|
|
655
|
-
DispatchQueue.main.async {
|
|
656
|
-
switch result {
|
|
657
|
-
case .success:
|
|
658
|
-
self?.currentUser = nil
|
|
659
|
-
self?.onLoginStateChanged?(nil)
|
|
660
|
-
completion(true, nil)
|
|
661
|
-
case .onError(let error):
|
|
662
|
-
completion(false, error)
|
|
663
|
-
@unknown default:
|
|
664
|
-
completion(false, nil)
|
|
64
|
+
CometChatUIKit.login(uid: uid) { loginResult in
|
|
65
|
+
switch loginResult {
|
|
66
|
+
case .success: DispatchQueue.main.async { showChat() }
|
|
67
|
+
case .onError(let error): // surface it — do not render on failure
|
|
68
|
+
break
|
|
69
|
+
@unknown default: break
|
|
665
70
|
}
|
|
666
71
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
)
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
6. **Do NOT call login while another login is in progress.** Check `currentUser` first. Concurrent login calls cause errors.
|
|
803
|
-
|
|
804
|
-
7. **Do NOT forget to handle logout.** When your app's user logs out, call `CometChatManager.shared.logout()` to clear the CometChat session.
|
|
805
|
-
|
|
806
|
-
8. **Do NOT ignore memory management.** CometChat view controllers should be properly deallocated. Avoid retain cycles with closures.
|
|
807
|
-
|
|
808
|
-
9. **Do NOT block the main thread.** All CometChat callbacks are on the main thread. Don't do heavy work in callbacks.
|
|
809
|
-
|
|
810
|
-
10. **Do NOT invent component names.** CometChat exports specific components with specific names. Check the `cometchat-ios-components` skill before writing any code.
|
|
811
|
-
|
|
812
|
-
---
|
|
813
|
-
|
|
814
|
-
## 9. SDK Types Reference
|
|
815
|
-
|
|
816
|
-
Common types from `CometChatSDK`:
|
|
817
|
-
|
|
818
|
-
```swift
|
|
819
|
-
import CometChatSDK
|
|
820
|
-
|
|
821
|
-
// User — represents a chat user
|
|
822
|
-
let user: User
|
|
823
|
-
|
|
824
|
-
// Group — represents a chat group
|
|
825
|
-
let group: Group
|
|
826
|
-
|
|
827
|
-
// Conversation — wraps User or Group
|
|
828
|
-
let conversation: Conversation
|
|
829
|
-
|
|
830
|
-
// BaseMessage — base class for all messages
|
|
831
|
-
let message: BaseMessage
|
|
832
|
-
|
|
833
|
-
// TextMessage — a text message
|
|
834
|
-
let textMessage: TextMessage
|
|
835
|
-
|
|
836
|
-
// MediaMessage — image, video, audio, file
|
|
837
|
-
let mediaMessage: MediaMessage
|
|
838
|
-
|
|
839
|
-
// CustomMessage — custom data message
|
|
840
|
-
let customMessage: CustomMessage
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
### Getting entities
|
|
844
|
-
|
|
845
|
-
```swift
|
|
846
|
-
// Get a user by UID
|
|
847
|
-
CometChat.getUser(UID: "user-uid") { user in
|
|
848
|
-
print("User: \(user?.name ?? "")")
|
|
849
|
-
} onError: { error in
|
|
850
|
-
print("Error: \(error?.errorDescription ?? "")")
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
// Get a group by GUID
|
|
854
|
-
CometChat.getGroup(GUID: "group-guid") { group in
|
|
855
|
-
print("Group: \(group?.name ?? "")")
|
|
856
|
-
} onError: { error in
|
|
857
|
-
print("Error: \(error?.errorDescription ?? "")")
|
|
858
|
-
}
|
|
859
|
-
```
|
|
860
|
-
|
|
861
|
-
---
|
|
862
|
-
|
|
863
|
-
## 10. Package Dependencies
|
|
864
|
-
|
|
865
|
-
Every CometChat iOS integration requires:
|
|
866
|
-
|
|
867
|
-
```ruby
|
|
868
|
-
# Podfile
|
|
869
|
-
pod 'CometChatUIKitSwift', '~> 5.1'
|
|
870
|
-
```
|
|
871
|
-
|
|
872
|
-
This automatically includes:
|
|
873
|
-
- `CometChatSDK` — Core SDK with types and methods
|
|
874
|
-
- UI components and views
|
|
875
|
-
- Localization resources
|
|
876
|
-
- Asset bundles
|
|
877
|
-
|
|
878
|
-
### Optional: Calling SDK
|
|
879
|
-
|
|
880
|
-
For voice/video calls, add:
|
|
881
|
-
|
|
882
|
-
```ruby
|
|
883
|
-
pod 'CometChatCallsSDK', '~> 5.0' # requires iOS 16+ deployment target
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
The UI Kit automatically detects and enables calling features when the Calls SDK is present.
|
|
887
|
-
|
|
888
|
-
## Visual Builder integration
|
|
889
|
-
|
|
890
|
-
When the dispatcher's Step 3.1 sets `customize=visual` and the platform resolves to `ios`, skills runs **`cometchat builder export --platform ios`** — a single CLI command that downloads the canonical static template ZIP from `preview.cometchat.com/downloads/cometchat-builder-ios.zip`, fetches the per-builder settings JSON, applies F3 + F10 missing-field defaults, and writes 3 files to `--output` (default: `CometChat/`):
|
|
891
|
-
|
|
892
|
-
- `MessagesVC.swift` — verbatim view controller composing header + list + composer
|
|
893
|
-
- `ThreadedMessagesVC.swift` — verbatim helper VC (imported by MessagesVC)
|
|
894
|
-
- `cometchat-builder-settings.json` — **envelope-shape JSON** `{ builderId, settings: {...} }` (the iOS canonical has no top-level `name`; `CometChatBuilderSettings.loadFromJSON()` reads only `settings.*`) (no sentinel — JSON forbids `//` comments)
|
|
895
|
-
|
|
896
|
-
> ℹ️ **Version-history note (ENG-35337) — RESOLVED end-to-end; `pod 'CometChatBuilder'` (1.1.2) builds AND launches.** A freshly-exported iOS builder ZIP was built end-to-end (`pod 'CometChatBuilder'` unversioned → resolves 1.1.2, with CometChatUIKitSwift 5.1.13 / CometChatSDK 4.1.3 / CometChatCallsSDK 5.0.0) → **`BUILD SUCCEEDED`**, then **installed + launched clean on a physical iPhone** (verified 2026-06-17 — the earlier sim-only `EXCLUDED_ARCHS` quirk was an environment issue, not a project defect). The current `ThreadedMessagesVC.swift` no longer reads `CometChatBuilderSettings.shared.layout.compactMessageComposer` (grep-confirmed absent), so the older compile failure is gone — do NOT pin `> 1.1.2` (a `1.1.3` may not exist; pinning it would break `pod install`). **Only if** you have an OLDER export whose `ThreadedMessagesVC.swift` still references `.layout.compactMessageComposer` and you hit `"value of type 'Layout' has no member 'compactMessageComposer'"`, re-export from the dashboard (preferred) or pin a newer `CometChatBuilder` if one is published.
|
|
897
|
-
|
|
898
|
-
### 1. Run `cometchat builder export`
|
|
899
|
-
|
|
900
|
-
```bash
|
|
901
|
-
cometchat builder export --platform ios --json
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
Defaults to `--output CometChat/`. Adjust the output if the customer's project uses a different chat-surface group name (e.g. `--output Chat/` for projects that use a `Chat` group).
|
|
905
|
-
|
|
906
|
-
`CometChatBuilderSettings.loadFromJSON()` looks for the envelope shape — handing it the raw settings blob causes `CometChatBuilderSettings.shared` to fall back to defaults silently (no error logged). The CLI always writes the envelope, so this trap is closed.
|
|
907
|
-
|
|
908
|
-
Resync = re-run the same command with `--force`. See `cometchat-core` §11.6 for the resync contract.
|
|
909
|
-
|
|
910
|
-
### 2. Files skills writes (after `builder export`)
|
|
911
|
-
|
|
912
|
-
| Path | Content |
|
|
913
|
-
|---|---|
|
|
914
|
-
| `CometChat/CometChatApp.swift` | **Optional, SwiftUI-host only.** Skills-authored convenience wrapper that mounts `CometChatConversations` + pushes `MessagesVC` on tap. Feature flags read from `CometChatBuilderSettings.shared`. Skills emits this — not from the ZIP. The canonical (reference-app) entry is the UIKit SceneDelegate → `FrameworkManager` → `HomeScreenViewController` path, not this wrapper. |
|
|
915
|
-
|
|
916
|
-
### Files patched
|
|
917
|
-
|
|
918
|
-
| Path | Patch |
|
|
919
|
-
|---|---|
|
|
920
|
-
| `Podfile` | Add `pod 'CometChatBuilder', '> 1.1.2'` (the canonical pod surfacing `CometChatBuilderSettings.shared` + `loadFromJSON()`; **pin `> 1.1.2`** — ≤1.1.2 lacks `Layout.compactMessageComposer` and fails to compile, see the build-breaker caveat above). Add `pod 'CometChatUIKitSwift', '~> 5.1'` if not already declared. SPM equivalent: `.package(url: "https://github.com/cometchat/cometchat-builder-ios", from: "1.1.3")` |
|
|
921
|
-
| `SceneDelegate.swift` (UIKit — canonical) / `App.swift` (SwiftUI — alternative) | Add `CometChatBuilderSettings.loadFromJSON()` + theme application + `CometChatUIKit.init(uiKitSettings:)`. **For scene-based apps (the reference app and any project with a `SceneDelegate`), init in `scene(_:willConnectTo:)` — NOT in `AppDelegate.didFinishLaunchingWithOptions`** (that runs before the scene/window exists). See init code below |
|
|
922
|
-
| App target | Toggle `cometchat-builder-settings.json` for **target membership** in Xcode (else `loadFromJSON()` silently returns defaults) |
|
|
923
|
-
| Entry view — root `UIViewController` (UIKit) / `ContentView.swift` (SwiftUI) | Mount the chat surface per Step 3c placement (modal sheet, push-navigation destination, tab item, or embedded view) |
|
|
924
|
-
| `Info.plist` | `NSMicrophoneUsageDescription` + `NSCameraUsageDescription` if `CometChatBuilderSettings.shared.callFeatures` has any enabled feature |
|
|
925
|
-
|
|
926
|
-
### Init code — SceneDelegate (canonical)
|
|
927
|
-
|
|
928
|
-
The reference app (`CometChatBuilderSwift`) is **pure UIKit, scene-based**: `@main AppDelegate` does nothing but vend the scene configuration, and `SceneDelegate.scene(_:willConnectTo:)` calls into a `FrameworkManager.initialize(with:completion:)` helper that loads settings → applies theme → inits the kit. Mirror that — do **not** init in `AppDelegate.didFinishLaunchingWithOptions` for a scene-based app (the window/scene doesn't exist yet there).
|
|
929
|
-
|
|
930
|
-
```swift
|
|
931
|
-
// SceneDelegate.swift
|
|
932
|
-
import UIKit
|
|
933
|
-
import CometChatBuilder
|
|
934
|
-
|
|
935
|
-
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|
936
|
-
var window: UIWindow?
|
|
937
|
-
|
|
938
|
-
func scene(_ scene: UIScene,
|
|
939
|
-
willConnectTo session: UISceneSession,
|
|
940
|
-
options connectionOptions: UIScene.ConnectionOptions) {
|
|
941
|
-
guard (scene as? UIWindowScene) != nil else { return }
|
|
942
|
-
FrameworkManager.initialize(with: scene) {
|
|
943
|
-
print("Framework initialized ✅")
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
```
|
|
948
|
-
|
|
949
|
-
```swift
|
|
950
|
-
// FrameworkManager.swift — load settings → applyTheme → init kit
|
|
951
|
-
import UIKit
|
|
952
|
-
import CometChatUIKitSwift
|
|
953
|
-
import CometChatSDK
|
|
954
|
-
import CometChatBuilder
|
|
955
|
-
|
|
956
|
-
enum FrameworkManager {
|
|
957
|
-
static func initialize(with scene: UIScene, completion: @escaping () -> Void) {
|
|
958
|
-
// 1. Load builder settings from bundled JSON
|
|
959
|
-
CometChatBuilderSettings.loadFromJSON()
|
|
960
|
-
|
|
961
|
-
// 2. Apply builder theme tokens to the kit's global theme
|
|
962
|
-
applyTheme()
|
|
963
|
-
|
|
964
|
-
// 3. Standard UI Kit init (this file's §2 — credentials from Secrets.swift)
|
|
965
|
-
let settings = UIKitSettings()
|
|
966
|
-
.set(appID: Secrets.appID)
|
|
967
|
-
.set(authKey: Secrets.authKey)
|
|
968
|
-
.set(region: Secrets.region)
|
|
969
|
-
.subscribePresenceForAllUsers()
|
|
970
|
-
.build()
|
|
971
|
-
CometChatUIKit.init(uiKitSettings: settings) { _ in
|
|
972
|
-
// set the root view controller on `scene` here, then:
|
|
973
|
-
completion()
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
static func applyTheme() {
|
|
978
|
-
let color = CometChatBuilderSettings.shared.style.color
|
|
979
|
-
CometChatTheme.primaryColor = UIColor.dynamicColor(
|
|
980
|
-
lightModeColor: UIColor(hex: color.brandColor),
|
|
981
|
-
darkModeColor: UIColor(hex: color.brandColor)
|
|
982
|
-
)
|
|
983
|
-
CometChatTheme.textColorPrimary = UIColor.dynamicColor(
|
|
984
|
-
lightModeColor: UIColor(hex: color.primaryTextLight),
|
|
985
|
-
darkModeColor: UIColor(hex: color.primaryTextDark)
|
|
986
|
-
)
|
|
987
|
-
CometChatTheme.textColorSecondary = UIColor.dynamicColor(
|
|
988
|
-
lightModeColor: UIColor(hex: color.secondaryTextLight),
|
|
989
|
-
darkModeColor: UIColor(hex: color.secondaryTextDark)
|
|
990
|
-
)
|
|
991
|
-
// ⚠️ Map the builder's raw font label to a registered PostScript name
|
|
992
|
-
// BEFORE handing it to setFont — passing the raw value (e.g. "Roboto")
|
|
993
|
-
// does NOT resolve to a real font and silently falls back to the system font.
|
|
994
|
-
let rawFont = CometChatBuilderSettings.shared.style.typography.font
|
|
995
|
-
CometChatTypography.setFont(name: fontName(rawFont) ?? "")
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
/// Resolves a builder font label to its registered PostScript name.
|
|
999
|
-
/// (Verbatim from the reference app's FrameworkManager.fontName.)
|
|
1000
|
-
static func fontName(_ name: String) -> String? {
|
|
1001
|
-
switch name.lowercased() {
|
|
1002
|
-
case "times new roman": return "TimesNewRomanPSMT"
|
|
1003
|
-
case "arial": return "ArialMT"
|
|
1004
|
-
case "roboto": return "Roboto-Regular"
|
|
1005
|
-
case "inter": return "Inter-Regular"
|
|
1006
|
-
default: return "\(name.capitalized)-Regular"
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
```
|
|
1011
|
-
|
|
1012
|
-
> **Font trap (D4).** `style.typography.font` in the builder JSON is a human label like `"Roboto"` or `"Arial"` — **not** a PostScript font name. Passing it straight to `CometChatTypography.setFont(name:)` (e.g. `setFont(name: settings.style.typography.font)`) silently fails to load the font. Always route it through the `fontName(_:)` lookup above (or otherwise resolve to a registered PostScript name, and register any custom `.ttf`/`.otf` in `Info.plist` under `UIAppFonts`).
|
|
1013
|
-
|
|
1014
|
-
`loadFromJSON()` reads `cometchat-builder-settings.json` from the main bundle. If the file isn't a target member (Xcode → file inspector → Target Membership), `CometChatBuilderSettings.shared` silently falls back to defaults — this is the #1 integration bug. Sanity-check by printing `CometChatBuilderSettings.shared.style.color.brandColor` after `loadFromJSON()`.
|
|
1015
|
-
|
|
1016
|
-
### The wrapper template (SwiftUI convenience — optional)
|
|
1017
|
-
|
|
1018
|
-
`CometChatApp.swift` below is a **skills-authored convenience wrapper** for teams who want to mount the chat surface inside a SwiftUI hierarchy. It is **not** the canonical entry point — the reference app is pure UIKit and routes from `SceneDelegate` → `FrameworkManager` → `HomeScreenViewController` (a `UITabBarController`). For UIKit projects, prefer the SceneDelegate path above and mount `CometChatConversations()` / `HomeScreenViewController` directly; use this SwiftUI wrapper only when the host app is SwiftUI.
|
|
1019
|
-
|
|
1020
|
-
```swift
|
|
1021
|
-
// CometChat/CometChatApp.swift — skills-authored SwiftUI convenience wrapper (NOT the canonical app)
|
|
1022
|
-
import SwiftUI
|
|
1023
|
-
import UIKit
|
|
1024
|
-
import CometChatBuilder
|
|
1025
|
-
import CometChatUIKitSwift
|
|
1026
|
-
import CometChatSDK
|
|
1027
|
-
|
|
1028
|
-
/// SwiftUI convenience wrapper around the chat surface (skills-authored, not from the ZIP).
|
|
1029
|
-
/// Master/detail SwiftUI host: `CometChatConversations` at root, `MessagesVC` pushed on tap.
|
|
1030
|
-
/// Feature visibility flags are read from `CometChatBuilderSettings.shared`.
|
|
1031
|
-
public struct CometChatApp: View {
|
|
1032
|
-
public init() {}
|
|
1033
|
-
public var body: some View {
|
|
1034
|
-
ConversationsContainer().ignoresSafeArea()
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
private struct ConversationsContainer: UIViewControllerRepresentable {
|
|
1039
|
-
func makeUIViewController(context: Context) -> UINavigationController {
|
|
1040
|
-
let conversationsVC = CometChatConversations()
|
|
1041
|
-
let core = CometChatBuilderSettings.shared.chatFeatures.coreMessagingExperience
|
|
1042
|
-
conversationsVC.hideUserStatus = !core.userAndFriendsPresence
|
|
1043
|
-
conversationsVC.hideReceipts = !core.messageDeliveryAndReadReceipts
|
|
1044
|
-
|
|
1045
|
-
let nav = UINavigationController(rootViewController: conversationsVC)
|
|
1046
|
-
conversationsVC.set(onItemClick: { [weak nav] conversation, _ in
|
|
1047
|
-
let vc = MessagesVC()
|
|
1048
|
-
// Qualify with CometChatSDK. — this file imports SwiftUI, which also
|
|
1049
|
-
// exports a `Group` type, so a bare `Group` is "ambiguous for type lookup"
|
|
1050
|
-
// and won't compile. (User is unambiguous but qualified here for parity.)
|
|
1051
|
-
if let user = conversation.conversationWith as? CometChatSDK.User { vc.user = user }
|
|
1052
|
-
else if let group = conversation.conversationWith as? CometChatSDK.Group { vc.group = group }
|
|
1053
|
-
nav?.pushViewController(vc, animated: true)
|
|
1054
|
-
})
|
|
1055
|
-
return nav
|
|
1056
|
-
}
|
|
1057
|
-
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
private extension UIColor {
|
|
1061
|
-
convenience init?(hex: String) {
|
|
1062
|
-
let s = hex.replacingOccurrences(of: "#", with: "")
|
|
1063
|
-
guard s.count == 6, let rgb = UInt32(s, radix: 16) else { return nil }
|
|
1064
|
-
self.init(red: CGFloat((rgb >> 16) & 0xFF) / 255,
|
|
1065
|
-
green: CGFloat((rgb >> 8) & 0xFF) / 255,
|
|
1066
|
-
blue: CGFloat(rgb & 0xFF) / 255,
|
|
1067
|
-
alpha: 1)
|
|
1068
|
-
}
|
|
1069
|
-
static func dynamicColor(lightModeColor: UIColor?, darkModeColor: UIColor?) -> UIColor {
|
|
1070
|
-
UIColor { traits in
|
|
1071
|
-
(traits.userInterfaceStyle == .dark ? darkModeColor : lightModeColor) ?? UIColor.label
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
```
|
|
1076
|
-
|
|
1077
|
-
`MessagesVC.swift` is **copied verbatim** from `CometChatBuilderSwift/BuilderApp/View Controllers/CometChat Components/MessagesVC.swift` (inside the Ios Visual Builder ZIP at https://preview.cometchat.com/downloads/cometchat-builder-ios.zip). It composes header + list + composer in a `UIViewController` and wires reaction / thread / typing per `CometChatBuilderSettings.shared.chatFeatures.*`. Do not hand-roll this — the canonical file is the reference.
|
|
1078
|
-
|
|
1079
|
-
`Secrets.swift` is the credentials enum (`enum Secrets { static let appID = "..."; static let region = "..."; static let authKey = "..." }`) populated by Step 2c provision. Added to `.gitignore`. (Note: this is the convention for integrating into the user's OWN app. The dashboard-exported **reference builder app** instead ships `AppConstants.swift` — a `public class AppConstants` with mutable `APP_ID`/`AUTH_KEY`/`REGION` statics persisted to `UserDefaults` + a `ChangeAppCredentialsVC` for runtime entry; verified 2026-06-14 against a real exported ZIP. If you're editing the exported app directly, set creds in `AppConstants.swift`.)
|
|
1080
|
-
|
|
1081
|
-
**UIKit (canonical) vs SwiftUI hosts.** The reference app is **pure UIKit**: `FrameworkManager.setRootViewController(...)` (called from the init `completion:` above) sets either `UINavigationController(rootViewController: HomeScreenViewController())` or a `SplitViewController` on iPad — see `CometChatBuilderSwift/BuilderApp/SceneDelegate.swift` + `FrameworkManager.swift` + `View Controllers/HomeScreenViewController.swift` (inside the Ios Visual Builder ZIP at https://preview.cometchat.com/downloads/cometchat-builder-ios.zip). The `CometChatApp` SwiftUI wrapper above is the alternative for SwiftUI-hosted apps; it wraps the same `CometChatConversations` surface in a `UIViewControllerRepresentable`.
|
|
1082
|
-
|
|
1083
|
-
### Calls + builder
|
|
1084
|
-
|
|
1085
|
-
If `CometChatBuilderSettings.shared.callFeatures` has any enabled feature:
|
|
1086
|
-
1. Init Calls SDK at the same site as UI Kit (see `cometchat-ios-calls`)
|
|
1087
|
-
2. Mount `CometChatIncomingCall` at app root (SwiftUI App's `WindowGroup` root, or UIKit's `keyWindow.rootViewController` overlay — the builder repo's `BuilderApplication`-equivalent pattern in `SceneDelegate.swift` is the reference)
|
|
1088
|
-
3. PushKit + CallKit wiring — defer to `cometchat-ios-push`
|
|
1089
|
-
|
|
1090
|
-
### What is NOT honored in v1
|
|
1091
|
-
|
|
1092
|
-
The builder repo's `HomeScreenViewController` is a `UITabBarController` with up to 4 tabs (Chats / Calls / Users / Groups) driven by `CometChatBuilderSettings.shared.layout.tabs`. Skills' thin wrapper emits a single conversations surface, not the tabbed shape. Theme color + typography + chat-feature toggles ARE honored. To get the tabbed shape, copy `HomeScreenViewController.swift` from the builder repo instead of the wrapper template above.
|
|
72
|
+
case .failure(let error):
|
|
73
|
+
break // usually a wrong Region or App ID
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
> **Which UID?** `login()` needs a user that ALREADY EXISTS — it does not create one. ASK, or take one from Dashboard → **Users**. Never invent a UID and never suggest remembered "classic sample" UIDs; the only tentative suggestion allowed is `cometchat-uid-1`, labelled "if this is a fresh app."
|
|
79
|
+
> **Login result is an enum, not an error-first callback:** `ApiStatus.success(User)` / `.onError(CometChatException)`. Handle `@unknown default`.
|
|
80
|
+
> **UI work belongs on the main queue** — the callbacks are not guaranteed to be.
|
|
81
|
+
|
|
82
|
+
## Component / API map (BAKED closed list — all catalog-verified)
|
|
83
|
+
Init/auth: `CometChatUIKit`, `UIKitSettings`.
|
|
84
|
+
Core surface: `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatCompactMessageComposer`.
|
|
85
|
+
Wired affordances: `CometChatThreadedMessageHeader`, `CometChatSearch`.
|
|
86
|
+
Grow set (on request): `CometChatUsers`, `CometChatGroups`, `CometChatGroupMembers`, `CometChatCallLogs`, `CometChatIncomingCall`.
|
|
87
|
+
> **Never emit:** `CometChatMessages`, `CometChatUsersWithMessages`, `CometChatGroupsWithMessages`, `CometChatConversationsWithMessages`, `CometChatAddMembers`, `CometChatMessageHeaderOption` — all v4 or non-existent. Anything not in this list → check `catalogs/ios-v5.json` before you write it.
|
|
88
|
+
|
|
89
|
+
## Hot-path API (BAKED — the golden path needs NO fetch)
|
|
90
|
+
- `CometChatConversations`: `set(onItemClick:)` (push the chat screen) · `set(conversationRequestBuilder:)` (scope the list) · `onSearchClick` (**property**, not a setter) · `set(subtitleView:)` / `set(trailView:)`.
|
|
91
|
+
- `CometChatMessageHeader` / `CometChatMessageList` / `CometChatCompactMessageComposer`: `set(user:)` **or** `set(group:)` — exactly one · `set(controller:)` on all three.
|
|
92
|
+
- **Thread scoping — the LIST takes its parent in the SAME call as its target.** `CometChatMessageList.set(user:parentMessage:withParent:)` (or `set(group:parentMessage:)`). A separate `set(user:)` followed by `set(parentMessageId:)` does NOT scope the list: the first call already built a request for the whole conversation, so the thread screen renders the entire conversation with the parent in it. The COMPOSER is different — `set(user:)` then `set(parentMessageId:)`. The header takes `set(parentMessage:)`. **Three components, three shapes** — verified against the shipped 5.1.22 interface by compiling each.
|
|
93
|
+
- Styles are **properties**, not setters: `conversations.avatarStyle = …`, `.badgeStyle`, `.dateStyle`, `.receiptStyle`, `.statusIndicatorStyle`, `.typingIndicatorStyle`.
|
|
94
|
+
> Exhaustive API or any other component → fetch its `.md` twin via `references/docs-map.md`. **Never** read the `.swiftinterface` or guess from memory.
|
|
95
|
+
|
|
96
|
+
## Golden path — the production-ready CORE surface
|
|
97
|
+
Setup → init/login (guarded) → a `CometChatConversations` list inside a `UINavigationController` → `set(onItemClick:)` pushes **your own** `MessagesVC` composing header + list + composer. This composition and its constraints are **verified on a simulator**; the five rules below are what the runtime gate actually checks, and each one is a real failure that compiles cleanly.
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
// List → chat screen. An unwired list is the iOS form of a dead-end affordance.
|
|
101
|
+
let conversations = CometChatConversations()
|
|
102
|
+
let nav = UINavigationController(rootViewController: conversations)
|
|
103
|
+
conversations.set(onItemClick: { [weak nav] conversation, _ in
|
|
104
|
+
let messages = MessagesVC()
|
|
105
|
+
messages.user = conversation.conversationWith as? CometChatSDK.User // exactly one is
|
|
106
|
+
messages.group = conversation.conversationWith as? CometChatSDK.Group // non-nil. Qualify:
|
|
107
|
+
// SwiftUI has its own `Group`.
|
|
108
|
+
nav?.pushViewController(messages, animated: true)
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```swift
|
|
113
|
+
final class MessagesVC: UIViewController {
|
|
114
|
+
var user: CometChatSDK.User?
|
|
115
|
+
var group: CometChatSDK.Group?
|
|
116
|
+
|
|
117
|
+
private lazy var headerView: CometChatMessageHeader = {
|
|
118
|
+
let v = CometChatMessageHeader()
|
|
119
|
+
v.translatesAutoresizingMaskIntoConstraints = false
|
|
120
|
+
if let user { v.set(user: user) } else if let group { v.set(group: group) }
|
|
121
|
+
v.set(controller: self) // REQUIRED — see rule 2
|
|
122
|
+
return v
|
|
123
|
+
}()
|
|
124
|
+
private lazy var messageListView: CometChatMessageList = {
|
|
125
|
+
let v = CometChatMessageList()
|
|
126
|
+
v.translatesAutoresizingMaskIntoConstraints = false
|
|
127
|
+
if let user { v.set(user: user) } else if let group { v.set(group: group) }
|
|
128
|
+
v.set(controller: self)
|
|
129
|
+
return v
|
|
130
|
+
}()
|
|
131
|
+
private lazy var composerView: CometChatCompactMessageComposer = {
|
|
132
|
+
let v = CometChatCompactMessageComposer()
|
|
133
|
+
v.translatesAutoresizingMaskIntoConstraints = false
|
|
134
|
+
if let user { v.set(user: user) } else if let group { v.set(group: group) }
|
|
135
|
+
v.set(controller: self)
|
|
136
|
+
return v
|
|
137
|
+
}()
|
|
138
|
+
|
|
139
|
+
override func viewDidLoad() {
|
|
140
|
+
super.viewDidLoad()
|
|
141
|
+
view.backgroundColor = .systemBackground
|
|
142
|
+
navigationController?.setNavigationBarHidden(true, animated: false) // rule 5
|
|
143
|
+
[headerView, messageListView, composerView].forEach(view.addSubview)
|
|
144
|
+
NSLayoutConstraint.activate([
|
|
145
|
+
headerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), // rule 3
|
|
146
|
+
headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
147
|
+
headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
148
|
+
headerView.heightAnchor.constraint(equalToConstant: 50),
|
|
149
|
+
|
|
150
|
+
messageListView.topAnchor.constraint(equalTo: headerView.bottomAnchor),
|
|
151
|
+
messageListView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
152
|
+
messageListView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
153
|
+
messageListView.bottomAnchor.constraint(equalTo: composerView.topAnchor), // rule 4
|
|
154
|
+
|
|
155
|
+
composerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
156
|
+
composerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
157
|
+
composerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), // rule 3
|
|
158
|
+
])
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
override func viewWillDisappear(_ animated: Bool) {
|
|
162
|
+
super.viewWillDisappear(animated)
|
|
163
|
+
navigationController?.setNavigationBarHidden(false, animated: true) // rule 5
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
> **Swift concurrency: several kit initialisers are `@MainActor`-isolated** (`CometChatUsers` among them). Any factory method that constructs kit components must be `@MainActor` too, or the build fails with *"call to main actor-isolated initializer … in a synchronous nonisolated context"*. Inside a `UIViewController` this is free — it is already main-actor — so it only bites in a `static`/`enum` factory.
|
|
169
|
+
> **The message header has NO tap callback.** `CometChatMessageHeader` exposes no `onItemClick`; its only interactive surface is `set(options:)` taking `[CometChatPopupMenu.MenuItem]`. So "tap the header to open details" is not a thing on iOS — a details or members screen is an overflow **menu item** you add.
|
|
170
|
+
|
|
171
|
+
**The five rules — each one compiles fine and fails at runtime:**
|
|
172
|
+
1. **One target, never both.** `conversationWith` is a `User` **or** a `Group`; pass the same single target to all three components. Two targets, or none, and the screen loads empty.
|
|
173
|
+
2. **`set(controller:)` on every component — omitting it CRASHES the app.** No React analogue: it hands the kit a controller to present its OWN sub-screens from. Long-press a message without it and the process dies (`EXC_BREAKPOINT`, nil force-unwrap in `MessagePopupViewController.buildUI`). Not a no-op, not a degraded mode — a crash on a gesture users perform within minutes. Call it on the header, the list AND the composer.
|
|
174
|
+
**Be precise about why, because this was measured.** Omitting it does *not* break rendering or list→chat navigation: the harness ran a fixture with it removed everywhere and got a byte-identical surface (393x750) plus a passing navigation step. What is genuinely unverified is the kit-presented sub-screens above — driving those needs an element the kit ships no accessibility identifier for. So follow the docs and call it, but do **not** tell a user their surface will break without it.
|
|
175
|
+
3. **Pin both to the SAFE AREA — never the composer to the keyboard.** Header to `safeAreaLayoutGuide.topAnchor`, composer to `safeAreaLayoutGuide.bottomAnchor`, as the published recipe shows. it does its OWN keyboard adjustment; pinning it to `keyboardLayoutGuide` double-applies it and the message list collapses to height 0 the moment the keyboard rises (measured — `references/layout.md`).
|
|
176
|
+
4. **Divide the space explicitly.** Header fixed height, composer at the bottom, list filling between — so the list scrolls internally instead of growing its parent. A list with no bottom constraint collapses; that is the single most common broken surface.
|
|
177
|
+
5. **One navigation bar — own it on the NAVIGATION CONTROLLER.** The kit header carries its own title and back control, so a visible host bar means two headers. Hiding it in the message screen's `viewDidLoad` is what the docs publish and is NOT enough: it never runs again, and on a push the outgoing screen's `viewWillDisappear` restore lands after the incoming hide, so the bar returns and the pane loses 91pt (measured). Use a `UINavigationControllerDelegate` — `references/layout.md`.
|
|
178
|
+
|
|
179
|
+
> **Surface errors — the list components fail silently otherwise.** `set(onError:)` on the conversation list and message list, or assign `errorStateView` / `errorStateTitleText` (inherited from `CometChatListBase`). Without it a failed fetch renders an empty list indistinguishable from "no conversations yet", leaving the user nothing to act on.
|
|
180
|
+
> ```swift
|
|
181
|
+
> conversations.set(onError: { error in /* surface it — do not swallow */ })
|
|
182
|
+
> ```
|
|
183
|
+
> **Wire or hide every default-on affordance.** `CometChatConversations` HIDES its search entry by default (`hideSearch` is true on `CometChatListBase`). Assigning `onSearchClick` alone renders NOTHING — measured: 0 search fields. To ship search you need BOTH `conversations.hideSearch = false` and `conversations.onSearchClick = { … }` (which then shows 1 search field); wire it to `CometChatSearch` or leave search off deliberately. `CometChatMessageList` shows a thread indicator that dead-ends until `set(onThreadRepliesClick:)` opens a thread screen. Anything you PRESENT modally owns its own dismissal; a pushed screen gets its back control from the navigation controller for free.
|
|
184
|
+
> **Scope the list to the request.** A 1:1-only ask should not show the app's seeded groups — use `set(conversationRequestBuilder:)` with `ConversationRequest.ConversationRequestBuilder(limit: 30).setConversationType(conversationType: .user)` (`.group` for groups-only). Note the method is **`setConversationType(conversationType:)`**, not `set(conversationType:)`, and the cases are `.user` / `.group` / `.none` — there is **no `.both`**; omit the call entirely to keep both.
|
|
185
|
+
> **Grows on request → the full app.** Users/groups tabs, group details, call logs, threads, calls — `cometchat-ios-placement` (composition) and `cometchat-ios-features` (per-feature).
|
|
186
|
+
|
|
187
|
+
## Deep references (load ONLY when the task needs them)
|
|
188
|
+
- `references/setup-credentials.md` — detect, `Secrets.xcconfig` → `Info.plist` → `Bundle.main`, `Info.plist` usage descriptions, version_conflict, prod auth token.
|
|
189
|
+
- `references/swiftui.md` — where `init → login` goes per lifecycle, and showing a UIKit-only component from SwiftUI.
|
|
190
|
+
- `references/docs-map.md` — intent → the exact docs `.md` twin to fetch, plus the SDK-fallback section. **Never** read the `.swiftinterface`; never answer API from memory.
|
|
191
|
+
- `references/layout.md` — the iOS sizing standard (safe area · keyboard layout guide · explicit vertical division), the five rules above in depth, and why each fails at runtime rather than compile time.
|
|
192
|
+
- `references/anti-patterns.md` — the v4-carryover phantoms, the two-parent-API thread trap, missing `set(controller:)`, and the wrong-call-form class (styles are properties).
|
|
193
|
+
- `references/troubleshooting.md` — symptom → cause → fix (blank screen, list renders but taps do nothing, composer hidden by the keyboard, two headers, replies never send).
|
|
194
|
+
|
|
195
|
+
## Common pitfalls (top 4 — full list in `references/anti-patterns.md`)
|
|
196
|
+
Emitting a v4 composite · omitting `set(controller:)` · composer pinned to `keyboardLayoutGuide` instead of the safe area (double-applies the kit's own keyboard handling — see rule 3) · rendering before `login()` resolves.
|
|
197
|
+
|
|
198
|
+
## Verify it works
|
|
199
|
+
Build and run → `init` then `login` both resolve → the conversation list renders full-screen (not a sliver) → tap a conversation → the chat screen pushes and shows header, messages and composer → tap the composer and confirm **it rises above the keyboard** → send a message and see it appear → back returns to the list. A blank screen means something rendered before `login()` resolved, or the Region/App ID is wrong. A list whose taps do nothing means `set(onItemClick:)` was never wired; affordances that render but do nothing when tapped mean `set(controller:)` was omitted.
|
|
200
|
+
|
|
201
|
+
## Explain what you built (REQUIRED close)
|
|
202
|
+
After it builds, tell the user briefly: **(1) what I wired** (3–5 bullets, NAME the files); **(2) decisions & why**, flagging dev-only as dev-only (the **Auth Key** is dev-only → server-minted auth token for production; the `<uid>` you used); **(3) what I did NOT touch** (additive — their navigation, auth and styling are intact). Then **offer these THREE options as a selectable choice and WAIT — do not auto-continue:**
|
|
203
|
+
- **① Add another feature** → first read what is already wired and ASK which dashboard-gated features are on, then suggest only the GAP (calls · search · threads · push · AI) → `cometchat-ios-features` / `cometchat-ios-calls`.
|
|
204
|
+
- **② Customize theming** → ask whether they have a brand/preset or want to talk through options → `cometchat-ios-customization`.
|
|
205
|
+
- **③ Test it manually** → do nothing further; hand it back.
|