@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,267 +0,0 @@
|
|
|
1
|
-
# Server-side APNs PushKit for iOS VoIP
|
|
2
|
-
|
|
3
|
-
When a CometChat call event fires (`onIncomingCallReceived` → CometChat backend webhook), your server sends a **VoIP push** to the recipient's iPhone via Apple's PushKit. Your app's PushKit delegate then triggers CallKit's incoming-call UI. Without VoIP push, the recipient's phone won't ring when the app is backgrounded.
|
|
4
|
-
|
|
5
|
-
**Canonical docs:** https://developer.apple.com/documentation/pushkit, https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Hard rules
|
|
10
|
-
|
|
11
|
-
1. **VoIP push is .p8 only** (token-auth). Old .pem cert auth was deprecated in 2020 and is no longer supported for VoIP.
|
|
12
|
-
2. **Use a separate APNs topic.** VoIP topic = `<bundle-id>.voip`. NOT the same as your regular APNs topic.
|
|
13
|
-
3. **`apns-push-type: voip`** header is mandatory. Apple drops the push silently if missing.
|
|
14
|
-
4. **`apns-priority: 10`** (immediate). VoIP must be high-priority.
|
|
15
|
-
5. **Must report to CallKit within ~5 seconds.** PushKit gives you a tiny window — if you don't call `CXProvider.reportNewIncomingCall(with:update:)` fast, iOS terminates your app and counts a strike. Three strikes in 24h and Apple revokes your VoIP entitlement.
|
|
16
|
-
6. **VoIP push payload size ≤ 4KB.** Include the minimum (`sessionId`, `callerName`, `callType`); fetch the rest after CallKit is reported.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## .p8 setup
|
|
21
|
-
|
|
22
|
-
1. Apple Developer Portal → Certificates, Identifiers & Profiles → **Keys** → "+"
|
|
23
|
-
2. Enable **Apple Push Notifications service (APNs)** → Continue → Register
|
|
24
|
-
3. Download the `.p8` file. **Save it — Apple shows it once.**
|
|
25
|
-
4. Note the **Key ID** (10-char alphanumeric).
|
|
26
|
-
5. Note your **Team ID** (top-right of Apple Developer dashboard).
|
|
27
|
-
|
|
28
|
-
Store securely on your server (Secret Manager / Vault — never in source).
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Node.js template
|
|
33
|
-
|
|
34
|
-
```js
|
|
35
|
-
// npm install @parse/node-apn
|
|
36
|
-
import apn from "@parse/node-apn";
|
|
37
|
-
import fs from "fs";
|
|
38
|
-
|
|
39
|
-
const provider = new apn.Provider({
|
|
40
|
-
token: {
|
|
41
|
-
key: fs.readFileSync("/secrets/AuthKey_ABC123.p8"),
|
|
42
|
-
keyId: process.env.APNS_KEY_ID, // e.g. "ABC123XYZ"
|
|
43
|
-
teamId: process.env.APNS_TEAM_ID, // e.g. "TEAM12345"
|
|
44
|
-
},
|
|
45
|
-
production: process.env.NODE_ENV === "production",
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Called from your CometChat call-event webhook handler.
|
|
50
|
-
* Looks up the recipient's PushKit token (you stored it when their app
|
|
51
|
-
* registered) and fires the VoIP push.
|
|
52
|
-
*/
|
|
53
|
-
export async function sendVoipPush(opts) {
|
|
54
|
-
const { recipientUid, sessionId, callerName, callerUid, callType } = opts;
|
|
55
|
-
|
|
56
|
-
const pushKitToken = await db.getVoipToken(recipientUid);
|
|
57
|
-
if (!pushKitToken) return; // user not on iOS or token expired
|
|
58
|
-
|
|
59
|
-
const note = new apn.Notification();
|
|
60
|
-
note.topic = `${process.env.APNS_BUNDLE_ID}.voip`; // <bundle>.voip — required
|
|
61
|
-
note.pushType = "voip"; // apns-push-type: voip
|
|
62
|
-
note.priority = 10; // apns-priority: 10 — immediate
|
|
63
|
-
note.expiry = Math.floor(Date.now() / 1000) + 30; // 30s — VoIP push must fire fast
|
|
64
|
-
|
|
65
|
-
// Custom payload — keep ≤4KB, include only what CallKit needs
|
|
66
|
-
note.rawPayload = {
|
|
67
|
-
aps: { "content-available": 1 },
|
|
68
|
-
sessionId,
|
|
69
|
-
callerName,
|
|
70
|
-
callerUid,
|
|
71
|
-
callType, // "audio" | "video"
|
|
72
|
-
timestamp: Date.now(),
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const result = await provider.send(note, pushKitToken);
|
|
76
|
-
if (result.failed.length > 0) {
|
|
77
|
-
const fail = result.failed[0];
|
|
78
|
-
if (fail.status === "410" || fail.response?.reason === "Unregistered") {
|
|
79
|
-
// Token is dead — remove from DB so we don't keep retrying
|
|
80
|
-
await db.removeVoipToken(recipientUid, pushKitToken);
|
|
81
|
-
}
|
|
82
|
-
console.error("APNs VoIP push failed", fail);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Python template
|
|
91
|
-
|
|
92
|
-
```python
|
|
93
|
-
# pip install httpx pyjwt cryptography
|
|
94
|
-
import time, json, jwt, httpx
|
|
95
|
-
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
|
96
|
-
|
|
97
|
-
PRIVATE_KEY = load_pem_private_key(
|
|
98
|
-
open("/secrets/AuthKey_ABC123.p8", "rb").read(), password=None
|
|
99
|
-
)
|
|
100
|
-
KEY_ID = os.environ["APNS_KEY_ID"]
|
|
101
|
-
TEAM_ID = os.environ["APNS_TEAM_ID"]
|
|
102
|
-
BUNDLE_ID = os.environ["APNS_BUNDLE_ID"]
|
|
103
|
-
APNS_HOST = "https://api.push.apple.com" if os.environ.get("ENV") == "production" else "https://api.sandbox.push.apple.com"
|
|
104
|
-
|
|
105
|
-
# Provider tokens are valid for 1h; cache + refresh
|
|
106
|
-
_token_cache = {"token": None, "issued_at": 0}
|
|
107
|
-
|
|
108
|
-
def provider_token() -> str:
|
|
109
|
-
if time.time() - _token_cache["issued_at"] < 3000: # refresh every 50min
|
|
110
|
-
return _token_cache["token"]
|
|
111
|
-
token = jwt.encode(
|
|
112
|
-
{"iss": TEAM_ID, "iat": int(time.time())},
|
|
113
|
-
PRIVATE_KEY,
|
|
114
|
-
algorithm="ES256",
|
|
115
|
-
headers={"kid": KEY_ID},
|
|
116
|
-
)
|
|
117
|
-
_token_cache.update(token=token, issued_at=time.time())
|
|
118
|
-
return token
|
|
119
|
-
|
|
120
|
-
async def send_voip_push(pushkit_token: str, payload: dict):
|
|
121
|
-
headers = {
|
|
122
|
-
"authorization": f"bearer {provider_token()}",
|
|
123
|
-
"apns-topic": f"{BUNDLE_ID}.voip",
|
|
124
|
-
"apns-push-type": "voip",
|
|
125
|
-
"apns-priority": "10",
|
|
126
|
-
"apns-expiration": str(int(time.time()) + 30),
|
|
127
|
-
}
|
|
128
|
-
async with httpx.AsyncClient(http2=True) as client:
|
|
129
|
-
r = await client.post(
|
|
130
|
-
f"{APNS_HOST}/3/device/{pushkit_token}",
|
|
131
|
-
headers=headers,
|
|
132
|
-
content=json.dumps(payload),
|
|
133
|
-
)
|
|
134
|
-
if r.status_code == 410:
|
|
135
|
-
# Token unregistered — remove from DB
|
|
136
|
-
return "unregistered"
|
|
137
|
-
if r.status_code != 200:
|
|
138
|
-
raise RuntimeError(f"APNs error {r.status_code}: {r.text}")
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Webhook payload from CometChat
|
|
144
|
-
|
|
145
|
-
In the CometChat dashboard, configure a **Webhook** → "Call events" → POST to `https://yourserver.com/webhooks/call`. The body shape:
|
|
146
|
-
|
|
147
|
-
```json
|
|
148
|
-
{
|
|
149
|
-
"trigger": "call_initiated",
|
|
150
|
-
"data": {
|
|
151
|
-
"id": "session-uuid",
|
|
152
|
-
"sessionId": "session-uuid",
|
|
153
|
-
"type": "video",
|
|
154
|
-
"initiator": { "uid": "alice", "name": "Alice" },
|
|
155
|
-
"receiver": { "uid": "bob", "name": "Bob" },
|
|
156
|
-
"receiverType": "user"
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Your handler:
|
|
162
|
-
|
|
163
|
-
```js
|
|
164
|
-
app.post("/webhooks/call", async (req, res) => {
|
|
165
|
-
// 1. Verify webhook signature (X-CometChat-Signature header)
|
|
166
|
-
const sig = req.headers["x-cometchat-signature"];
|
|
167
|
-
const expected = crypto.createHmac("sha256", process.env.COMETCHAT_WEBHOOK_SECRET)
|
|
168
|
-
.update(req.rawBody).digest("hex");
|
|
169
|
-
if (sig !== expected) return res.status(401).end();
|
|
170
|
-
|
|
171
|
-
// 2. Only fire VoIP push on call_initiated (not on call-ended)
|
|
172
|
-
if (req.body.trigger !== "call_initiated") return res.status(200).end();
|
|
173
|
-
|
|
174
|
-
// 3. Forward to platform-specific push
|
|
175
|
-
const { sessionId, type, initiator, receiver } = req.body.data;
|
|
176
|
-
await sendVoipPush({
|
|
177
|
-
recipientUid: receiver.uid,
|
|
178
|
-
sessionId,
|
|
179
|
-
callerName: initiator.name,
|
|
180
|
-
callerUid: initiator.uid,
|
|
181
|
-
callType: type,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
res.status(200).end();
|
|
185
|
-
});
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## Token registration (the round-trip)
|
|
191
|
-
|
|
192
|
-
When your iOS app launches, register PushKit and POST the token to your server:
|
|
193
|
-
|
|
194
|
-
```swift
|
|
195
|
-
// AppDelegate or dedicated VoIP manager
|
|
196
|
-
import PushKit
|
|
197
|
-
|
|
198
|
-
class VoipPushHandler: NSObject, PKPushRegistryDelegate {
|
|
199
|
-
let registry = PKPushRegistry(queue: .main)
|
|
200
|
-
|
|
201
|
-
override init() {
|
|
202
|
-
super.init()
|
|
203
|
-
registry.delegate = self
|
|
204
|
-
registry.desiredPushTypes = [.voIP]
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
|
|
208
|
-
guard type == .voIP else { return }
|
|
209
|
-
let token = credentials.token.map { String(format: "%02x", $0) }.joined()
|
|
210
|
-
Task { try? await api.registerVoipToken(uid: currentUserUid, token: token) }
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
|
|
214
|
-
Task { try? await api.removeVoipToken(uid: currentUserUid) }
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
|
|
218
|
-
// Report to CallKit IMMEDIATELY — Apple gives you ~5s
|
|
219
|
-
let dict = payload.dictionaryPayload
|
|
220
|
-
let update = CXCallUpdate()
|
|
221
|
-
update.remoteHandle = CXHandle(type: .generic, value: dict["callerUid"] as? String ?? "Unknown")
|
|
222
|
-
update.localizedCallerName = dict["callerName"] as? String ?? "Unknown"
|
|
223
|
-
update.hasVideo = (dict["callType"] as? String) == "video"
|
|
224
|
-
|
|
225
|
-
let uuid = UUID()
|
|
226
|
-
callProvider.reportNewIncomingCall(with: uuid, update: update) { error in
|
|
227
|
-
if let error = error { print("CallKit reportNewIncomingCall failed:", error) }
|
|
228
|
-
completion()
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Anti-patterns
|
|
237
|
-
|
|
238
|
-
1. **Using regular APNs token, not VoIP.** Push arrives but CallKit doesn't trigger — the app got woken up, not put into "incoming call" state.
|
|
239
|
-
2. **Forgetting `apns-push-type: voip`.** Apple drops the push, no error to your server.
|
|
240
|
-
3. **Not calling `reportNewIncomingCall` from `didReceiveIncomingPushWith`.** Three strikes → entitlement revoked.
|
|
241
|
-
4. **Sending too much in the VoIP payload.** Apple throttles or rejects >4KB. Send minimum, fetch the rest after CallKit fires.
|
|
242
|
-
5. **Webhook handler doing slow work synchronously.** Push to a queue (Redis, SQS, BullMQ); return 200 immediately. Slow webhook = CometChat retries = duplicate calls.
|
|
243
|
-
6. **Same token for chat push and VoIP push.** Different tokens — you must register both via `UNUserNotificationCenter` (regular) AND `PKPushRegistry` (VoIP).
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
## Verification checklist
|
|
248
|
-
|
|
249
|
-
- [ ] `.p8` key stored in secret manager
|
|
250
|
-
- [ ] `apns-topic = <bundle-id>.voip`
|
|
251
|
-
- [ ] `apns-push-type: voip` + `apns-priority: 10`
|
|
252
|
-
- [ ] `reportNewIncomingCall` fires from PushKit delegate inside ~5s
|
|
253
|
-
- [ ] 410 responses purge dead tokens from DB
|
|
254
|
-
- [ ] Webhook signature verified before processing
|
|
255
|
-
- [ ] Webhook returns 200 within 1s (push enqueued, not awaited)
|
|
256
|
-
- [ ] Real-device smoke: backgrounded recipient → caller dials → recipient phone rings on lock screen
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Pointers
|
|
261
|
-
|
|
262
|
-
- `cometchat-ios-calls/SKILL.md` — the seven hard rules (init order, IncomingCall mounting, hangup teardown)
|
|
263
|
-
- `cometchat-ios-push/SKILL.md` — chat push (sister, different APNs topic)
|
|
264
|
-
- `cometchat-android-v5-calls/references/server-fcm-voip.md` — Android sibling (FCM HTTP v1)
|
|
265
|
-
- `cometchat-react-calls/references/server-web-push-vapid.md` — Web sibling
|
|
266
|
-
- Apple PushKit: https://developer.apple.com/documentation/pushkit
|
|
267
|
-
- APNs HTTP/2 reference: https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
# Share invite on iOS
|
|
2
|
-
|
|
3
|
-
Same SDK API. iOS-specific: `UIActivityViewController` is the native share sheet (handles iMessage, Mail, AirDrop, third-party apps). Universal Links must be configured for the call link to deep into the app.
|
|
4
|
-
|
|
5
|
-
**Canonical docs:** https://www.cometchat.com/docs/calls/ios/share-invite
|
|
6
|
-
**Read first:** `cometchat-react-calls/references/share-invite.md` — deep-link rule + share dialog UX.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Hard rule: Universal Links + apple-app-site-association
|
|
11
|
-
|
|
12
|
-
For `https://yourapp.com/call/SESSION_ID` to open your app:
|
|
13
|
-
|
|
14
|
-
1. Add `Associated Domains` capability with `applinks:yourapp.com`
|
|
15
|
-
2. Host `apple-app-site-association` JSON at `https://yourapp.com/.well-known/apple-app-site-association`:
|
|
16
|
-
|
|
17
|
-
```json
|
|
18
|
-
{
|
|
19
|
-
"applinks": {
|
|
20
|
-
"apps": [],
|
|
21
|
-
"details": [{
|
|
22
|
-
"appID": "TEAMID.com.yourapp.bundle",
|
|
23
|
-
"paths": ["/call/*"]
|
|
24
|
-
}]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
3. In `SceneDelegate` / `AppDelegate`, handle `NSUserActivity` with `activityType == NSUserActivityTypeBrowsingWeb`:
|
|
30
|
-
|
|
31
|
-
```swift
|
|
32
|
-
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
|
33
|
-
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
|
|
34
|
-
let url = userActivity.webpageURL,
|
|
35
|
-
url.pathComponents.count >= 3,
|
|
36
|
-
url.pathComponents[1] == "call" else { return }
|
|
37
|
-
let sessionId = url.pathComponents[2]
|
|
38
|
-
router.routeToCall(sessionId: sessionId)
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Without these, share-invite URLs open in Safari instead of your app.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## No SDK share-invite button — build your own
|
|
47
|
-
|
|
48
|
-
> The iOS Calls SDK v5 has **no** share-invite affordance. There is no `setHideShareInviteButton` on `CallSettingsBuilder` and no `onShareInviteButtonClicked` callback on `CallsEventsDelegate`. Share-invite is an app-level feature: add your own button to your call UI and present a `UIActivityViewController` over the session's deep link (below).
|
|
49
|
-
|
|
50
|
-
```swift
|
|
51
|
-
// Your own button in the call control panel:
|
|
52
|
-
let inviteButton = UIButton(type: .system)
|
|
53
|
-
inviteButton.addAction(UIAction { [weak self] _ in
|
|
54
|
-
self?.shareCallInvite() // already on main
|
|
55
|
-
}, for: .touchUpInside)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## UIActivityViewController
|
|
61
|
-
|
|
62
|
-
```swift
|
|
63
|
-
extension CallViewController {
|
|
64
|
-
func shareCallInvite() {
|
|
65
|
-
let url = URL(string: "https://yourapp.com/call/\(sessionId)")!
|
|
66
|
-
let title = "Join my call"
|
|
67
|
-
let text = "I'm on a call — tap to join."
|
|
68
|
-
|
|
69
|
-
let items: [Any] = [text, url]
|
|
70
|
-
let activityVC = UIActivityViewController(
|
|
71
|
-
activityItems: items,
|
|
72
|
-
applicationActivities: nil
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
// Optional: exclude activities you don't want
|
|
76
|
-
activityVC.excludedActivityTypes = [.assignToContact, .saveToCameraRoll]
|
|
77
|
-
|
|
78
|
-
// iPad: must set source for popover
|
|
79
|
-
if let popover = activityVC.popoverPresentationController {
|
|
80
|
-
popover.sourceView = self.view
|
|
81
|
-
popover.sourceRect = CGRect(
|
|
82
|
-
x: self.view.bounds.midX,
|
|
83
|
-
y: self.view.bounds.midY,
|
|
84
|
-
width: 0,
|
|
85
|
-
height: 0
|
|
86
|
-
)
|
|
87
|
-
popover.permittedArrowDirections = []
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
present(activityVC, animated: true)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
iOS auto-renders link preview if your URL has Open Graph tags + universal-link routing — the share sheet shows app icon + name + "Join my call" instead of a raw URL.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## SwiftUI ShareLink (iOS 16+)
|
|
100
|
-
|
|
101
|
-
If you build the share button yourself in SwiftUI:
|
|
102
|
-
|
|
103
|
-
```swift
|
|
104
|
-
import SwiftUI
|
|
105
|
-
|
|
106
|
-
struct CallShareButton: View {
|
|
107
|
-
let sessionId: String
|
|
108
|
-
|
|
109
|
-
var body: some View {
|
|
110
|
-
let url = URL(string: "https://yourapp.com/call/\(sessionId)")!
|
|
111
|
-
ShareLink(item: url, subject: Text("Join my call"), message: Text("I'm on a call — tap to join.")) {
|
|
112
|
-
Label("Share invite", systemImage: "square.and.arrow.up")
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Anti-patterns
|
|
121
|
-
|
|
122
|
-
Web sister rules apply, plus iOS-specific:
|
|
123
|
-
|
|
124
|
-
1. **iPad without `popoverPresentationController.sourceView`.** Crashes on iPad — popover requires an anchor.
|
|
125
|
-
2. **`UIPasteboard.general.string = url.absoluteString` instead of UIActivityVC.** Skips iOS's curated share sheet — bad UX.
|
|
126
|
-
3. **Universal Links not configured.** Recipients tap link → opens Safari, not your app.
|
|
127
|
-
4. **`activityItems: [url]` without title text.** Recipients see just a URL, no context.
|
|
128
|
-
5. **Presenting from background queue.** Crash. Always main.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## Verification checklist
|
|
133
|
-
|
|
134
|
-
- [ ] Associated Domains entitlement added
|
|
135
|
-
- [ ] `apple-app-site-association` JSON hosted + reachable
|
|
136
|
-
- [ ] `NSUserActivity` continuation in SceneDelegate routes to call
|
|
137
|
-
- [ ] `UIActivityViewController` (UIKit) or `ShareLink` (SwiftUI 16+) used
|
|
138
|
-
- [ ] iPad popover anchored
|
|
139
|
-
- [ ] Real-device smoke: share via Messages → tap from another iPhone → opens your app at call
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Pointers
|
|
144
|
-
|
|
145
|
-
- `cometchat-react-calls/references/share-invite.md` — sister
|
|
146
|
-
- `cometchat-ios-calls` SKILL.md — seven hard rules
|
|
147
|
-
- `references/universal-links.md`
|
|
148
|
-
- Canonical docs: https://www.cometchat.com/docs/calls/ios/share-invite
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
# SwiftUI + UIKit hosting for iOS calls
|
|
2
|
-
|
|
3
|
-
CometChat's iOS Calls UI Kit ships UIKit `UIViewController`s. SwiftUI apps host them via `UIViewControllerRepresentable`. Mixed projects (SwiftUI app shell with UIKit feature screens) work natively.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Pure UIKit project — direct usage
|
|
8
|
-
|
|
9
|
-
```swift
|
|
10
|
-
import UIKit
|
|
11
|
-
import CometChatUIKitSwift
|
|
12
|
-
|
|
13
|
-
class ProfileViewController: UIViewController {
|
|
14
|
-
override func viewDidLoad() {
|
|
15
|
-
super.viewDidLoad()
|
|
16
|
-
|
|
17
|
-
let callButton = CometChatCallButtons(width: 100, height: 44).set(user: user) // class is plural; user via .set(user:), no (user:) init
|
|
18
|
-
callButton.translatesAutoresizingMaskIntoConstraints = false
|
|
19
|
-
view.addSubview(callButton)
|
|
20
|
-
NSLayoutConstraint.activate([
|
|
21
|
-
callButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
|
22
|
-
callButton.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor),
|
|
23
|
-
])
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
For ongoing call:
|
|
29
|
-
|
|
30
|
-
```swift
|
|
31
|
-
let ongoingCallVC = CometChatOngoingCall()
|
|
32
|
-
ongoingCallVC.set(sessionID: sessionId)
|
|
33
|
-
present(ongoingCallVC, animated: true)
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Pure SwiftUI project — UIViewControllerRepresentable
|
|
39
|
-
|
|
40
|
-
Wrap each UIKit VC in a SwiftUI view:
|
|
41
|
-
|
|
42
|
-
```swift
|
|
43
|
-
import SwiftUI
|
|
44
|
-
import CometChatUIKitSwift
|
|
45
|
-
|
|
46
|
-
struct CallButtonView: UIViewRepresentable {
|
|
47
|
-
let user: User
|
|
48
|
-
|
|
49
|
-
func makeUIView(context: Context) -> CometChatCallButtons {
|
|
50
|
-
CometChatCallButtons(width: 100, height: 44).set(user: user)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
func updateUIView(_ uiView: CometChatCallButtons, context: Context) {
|
|
54
|
-
// Re-bind on user change if your view supports that
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
struct OngoingCallView: UIViewControllerRepresentable {
|
|
59
|
-
let sessionID: String
|
|
60
|
-
@Binding var isPresented: Bool
|
|
61
|
-
|
|
62
|
-
func makeUIViewController(context: Context) -> CometChatOngoingCall {
|
|
63
|
-
let vc = CometChatOngoingCall()
|
|
64
|
-
vc.set(sessionID: sessionID)
|
|
65
|
-
return vc
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
func updateUIViewController(_ vc: CometChatOngoingCall, context: Context) {}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
struct CallLogsView: UIViewControllerRepresentable {
|
|
72
|
-
func makeUIViewController(context: Context) -> CometChatCallLogs {
|
|
73
|
-
CometChatCallLogs()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
func updateUIViewController(_ vc: CometChatCallLogs, context: Context) {}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Use them like any SwiftUI view:
|
|
81
|
-
|
|
82
|
-
```swift
|
|
83
|
-
struct ProfileView: View {
|
|
84
|
-
let user: User
|
|
85
|
-
@State private var ongoingSessionID: String?
|
|
86
|
-
|
|
87
|
-
var body: some View {
|
|
88
|
-
VStack {
|
|
89
|
-
Text(user.name)
|
|
90
|
-
CallButtonView(user: user)
|
|
91
|
-
.frame(width: 100, height: 44)
|
|
92
|
-
}
|
|
93
|
-
.fullScreenCover(isPresented: Binding(
|
|
94
|
-
get: { ongoingSessionID != nil },
|
|
95
|
-
set: { if !$0 { ongoingSessionID = nil } }
|
|
96
|
-
)) {
|
|
97
|
-
if let id = ongoingSessionID {
|
|
98
|
-
OngoingCallView(sessionID: id, isPresented: Binding(
|
|
99
|
-
get: { true }, set: { _ in ongoingSessionID = nil }
|
|
100
|
-
))
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Mixed-stack — SwiftUI app, UIKit feature screen
|
|
110
|
-
|
|
111
|
-
Common in apps that started UIKit and adopted SwiftUI for new features. Calls can stay UIKit; chat can be SwiftUI; both interop.
|
|
112
|
-
|
|
113
|
-
```swift
|
|
114
|
-
// SwiftUI screen pushing a UIKit call screen via UIHostingController bridge
|
|
115
|
-
import SwiftUI
|
|
116
|
-
|
|
117
|
-
struct ChatView: View {
|
|
118
|
-
let user: User
|
|
119
|
-
|
|
120
|
-
var body: some View {
|
|
121
|
-
NavigationLink(destination: UIKitCallScreenWrapper(user: user)) {
|
|
122
|
-
Text("Start call")
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
struct UIKitCallScreenWrapper: UIViewControllerRepresentable {
|
|
128
|
-
let user: User
|
|
129
|
-
|
|
130
|
-
func makeUIViewController(context: Context) -> UINavigationController {
|
|
131
|
-
let vc = OngoingCallViewController(user: user) // your custom UIKit VC
|
|
132
|
-
return UINavigationController(rootViewController: vc)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
func updateUIViewController(_ vc: UINavigationController, context: Context) {}
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Where the IncomingCall UI goes (additive mode)
|
|
142
|
-
|
|
143
|
-
In standalone mode, **CallKit owns the incoming-call UI** — no in-app rendering needed.
|
|
144
|
-
|
|
145
|
-
In additive mode (chat already integrated and user is foregrounded when a call comes in), the kit's `CometChatIncomingCall` view can render. Mount it at the root:
|
|
146
|
-
|
|
147
|
-
### SwiftUI app — root mount
|
|
148
|
-
|
|
149
|
-
```swift
|
|
150
|
-
@main
|
|
151
|
-
struct YourApp: App {
|
|
152
|
-
@StateObject private var callState = CallState.shared
|
|
153
|
-
|
|
154
|
-
var body: some Scene {
|
|
155
|
-
WindowGroup {
|
|
156
|
-
ZStack {
|
|
157
|
-
ContentView()
|
|
158
|
-
if let call = callState.foregroundIncomingCall {
|
|
159
|
-
IncomingCallView(call: call, callState: callState)
|
|
160
|
-
.transition(.move(edge: .top))
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
struct IncomingCallView: UIViewControllerRepresentable {
|
|
168
|
-
let call: Call
|
|
169
|
-
let callState: CallState
|
|
170
|
-
|
|
171
|
-
func makeUIViewController(context: Context) -> CometChatIncomingCall {
|
|
172
|
-
let vc = CometChatIncomingCall()
|
|
173
|
-
vc.set(call: call)
|
|
174
|
-
vc.setOnAccept { [weak callState] _ in callState?.accept(call) }
|
|
175
|
-
vc.setOnDecline { [weak callState] _ in callState?.decline(call) }
|
|
176
|
-
return vc
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
func updateUIViewController(_ vc: CometChatIncomingCall, context: Context) {}
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### UIKit app — present from root window
|
|
184
|
-
|
|
185
|
-
```swift
|
|
186
|
-
class CallObserver: NSObject {
|
|
187
|
-
func showIncomingCallUI(call: Call) {
|
|
188
|
-
let vc = CometChatIncomingCall()
|
|
189
|
-
vc.set(call: call)
|
|
190
|
-
UIApplication.shared.windows.first?.rootViewController?.present(vc, animated: true)
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
In standalone, neither — CallKit handles it.
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## When to use SwiftUI navigation vs UIKit modal
|
|
200
|
-
|
|
201
|
-
For ongoing calls specifically, **modal full-screen** is the right pattern on both stacks:
|
|
202
|
-
|
|
203
|
-
- SwiftUI: `.fullScreenCover(isPresented:)` (NOT `.sheet`, which is dismissable by swipe)
|
|
204
|
-
- UIKit: `present(_:animated:)` with `vc.modalPresentationStyle = .fullScreen`
|
|
205
|
-
|
|
206
|
-
Reason: in-call UI shouldn't be navigable-back-to (the user shouldn't accidentally swipe-down and lose the call view). Full-screen modal forces explicit "End" button to dismiss.
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## CometChatUIKit init for SwiftUI
|
|
211
|
-
|
|
212
|
-
Init in `App.init()`:
|
|
213
|
-
|
|
214
|
-
```swift
|
|
215
|
-
@main
|
|
216
|
-
struct YourApp: App {
|
|
217
|
-
init() {
|
|
218
|
-
let settings = UIKitSettings()
|
|
219
|
-
.set(appID: Secrets.cometchatAppID)
|
|
220
|
-
.set(region: Secrets.cometchatRegion)
|
|
221
|
-
.set(authKey: Secrets.cometchatAuthKey)
|
|
222
|
-
.subscribePresenceForAllUsers()
|
|
223
|
-
.build()
|
|
224
|
-
|
|
225
|
-
CometChatUIKit.init(uiKitSettings: settings) { result in
|
|
226
|
-
switch result {
|
|
227
|
-
case .success: print("Init OK")
|
|
228
|
-
case .onError(let error): print("Init failed: \(error)")
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
var body: some Scene { /* ... */ }
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
Reference `cometchat-ios-core` for the full init pattern with login.
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## Things that don't work cleanly in SwiftUI
|
|
242
|
-
|
|
243
|
-
- **Custom theming via Storyboard inspection** — UIKit-only. SwiftUI projects override theme via `CometChatTheme` API in code (see `cometchat-ios-theming`).
|
|
244
|
-
- **NavigationLink to a `CometChat*` VC without representable wrapper** — must wrap.
|
|
245
|
-
- **Sharing UIKit and SwiftUI navigation stacks** — possible but messy. Pick one for any single feature.
|
|
246
|
-
- **Presenting `CometChatIncomingCall` from a SwiftUI sheet** — sheets dismiss on swipe; calls shouldn't. Use `fullScreenCover` or a manually-rendered ZStack overlay.
|