@cometchat/skills 4.0.0 → 4.2.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.
Files changed (258) hide show
  1. package/README.md +42 -2
  2. package/bin/install.js +448 -57
  3. package/package.json +1 -1
  4. package/skills/cometchat/SKILL.md +337 -80
  5. package/skills/cometchat-a11y/SKILL.md +476 -0
  6. package/skills/cometchat-android-v5/SKILL.md +1 -1
  7. package/skills/cometchat-android-v5-calls/SKILL.md +413 -0
  8. package/skills/cometchat-android-v5-calls/references/README.md +53 -0
  9. package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +195 -0
  10. package/skills/cometchat-android-v5-calls/references/audio-controls.md +91 -0
  11. package/skills/cometchat-android-v5-calls/references/background-handling.md +168 -0
  12. package/skills/cometchat-android-v5-calls/references/call-layouts.md +123 -0
  13. package/skills/cometchat-android-v5-calls/references/call-logs.md +113 -0
  14. package/skills/cometchat-android-v5-calls/references/call-session.md +274 -0
  15. package/skills/cometchat-android-v5-calls/references/custom-ui.md +150 -0
  16. package/skills/cometchat-android-v5-calls/references/event-listeners.md +123 -0
  17. package/skills/cometchat-android-v5-calls/references/group-calls.md +205 -0
  18. package/skills/cometchat-android-v5-calls/references/idle-timeout.md +111 -0
  19. package/skills/cometchat-android-v5-calls/references/in-call-chat.md +134 -0
  20. package/skills/cometchat-android-v5-calls/references/join-session.md +120 -0
  21. package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +206 -0
  22. package/skills/cometchat-android-v5-calls/references/participant-management.md +110 -0
  23. package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +106 -0
  24. package/skills/cometchat-android-v5-calls/references/raise-hand.md +242 -0
  25. package/skills/cometchat-android-v5-calls/references/recording.md +101 -0
  26. package/skills/cometchat-android-v5-calls/references/ringing-integration.md +152 -0
  27. package/skills/cometchat-android-v5-calls/references/screen-sharing.md +82 -0
  28. package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +215 -0
  29. package/skills/cometchat-android-v5-calls/references/session-settings.md +121 -0
  30. package/skills/cometchat-android-v5-calls/references/setup.md +137 -0
  31. package/skills/cometchat-android-v5-calls/references/share-invite.md +151 -0
  32. package/skills/cometchat-android-v5-calls/references/video-controls.md +87 -0
  33. package/skills/cometchat-android-v5-calls/references/voip-calling.md +526 -0
  34. package/skills/cometchat-android-v5-components/SKILL.md +1 -1
  35. package/skills/cometchat-android-v5-core/SKILL.md +1 -1
  36. package/skills/cometchat-android-v5-customization/SKILL.md +1 -1
  37. package/skills/cometchat-android-v5-extensions/SKILL.md +1 -1
  38. package/skills/cometchat-android-v5-features/SKILL.md +1 -1
  39. package/skills/cometchat-android-v5-placement/SKILL.md +1 -1
  40. package/skills/cometchat-android-v5-production/SKILL.md +1 -1
  41. package/skills/cometchat-android-v5-push/SKILL.md +1 -1
  42. package/skills/cometchat-android-v5-testing/SKILL.md +1 -1
  43. package/skills/cometchat-android-v5-theming/SKILL.md +1 -1
  44. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +1 -1
  45. package/skills/cometchat-android-v6/SKILL.md +1 -1
  46. package/skills/cometchat-android-v6-builder-settings/SKILL.md +1 -1
  47. package/skills/cometchat-android-v6-calls/SKILL.md +375 -0
  48. package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +97 -0
  49. package/skills/cometchat-android-v6-calls/references/call-layouts.md +91 -0
  50. package/skills/cometchat-android-v6-calls/references/call-session.md +163 -0
  51. package/skills/cometchat-android-v6-calls/references/device-management.md +171 -0
  52. package/skills/cometchat-android-v6-calls/references/group-calls.md +191 -0
  53. package/skills/cometchat-android-v6-calls/references/idle-timeout.md +107 -0
  54. package/skills/cometchat-android-v6-calls/references/in-call-chat.md +136 -0
  55. package/skills/cometchat-android-v6-calls/references/raise-hand.md +186 -0
  56. package/skills/cometchat-android-v6-calls/references/ringing-integration.md +176 -0
  57. package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +127 -0
  58. package/skills/cometchat-android-v6-calls/references/share-invite.md +105 -0
  59. package/skills/cometchat-android-v6-compose-components/SKILL.md +2 -2
  60. package/skills/cometchat-android-v6-compose-customization/SKILL.md +1 -1
  61. package/skills/cometchat-android-v6-compose-placement/SKILL.md +1 -1
  62. package/skills/cometchat-android-v6-compose-theming/SKILL.md +1 -1
  63. package/skills/cometchat-android-v6-core/SKILL.md +1 -1
  64. package/skills/cometchat-android-v6-events/SKILL.md +1 -1
  65. package/skills/cometchat-android-v6-extensions/SKILL.md +1 -1
  66. package/skills/cometchat-android-v6-features/SKILL.md +1 -1
  67. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +1 -1
  68. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +1 -1
  69. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +1 -1
  70. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +1 -1
  71. package/skills/cometchat-android-v6-migration/SKILL.md +398 -0
  72. package/skills/cometchat-android-v6-production/SKILL.md +1 -1
  73. package/skills/cometchat-android-v6-push/SKILL.md +1 -1
  74. package/skills/cometchat-android-v6-testing/SKILL.md +1 -1
  75. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +1 -1
  76. package/skills/cometchat-angular-calls/SKILL.md +511 -0
  77. package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +95 -0
  78. package/skills/cometchat-angular-calls/references/call-layouts.md +106 -0
  79. package/skills/cometchat-angular-calls/references/call-session.md +167 -0
  80. package/skills/cometchat-angular-calls/references/custom-ui.md +231 -0
  81. package/skills/cometchat-angular-calls/references/device-management.md +135 -0
  82. package/skills/cometchat-angular-calls/references/group-calls.md +412 -0
  83. package/skills/cometchat-angular-calls/references/idle-timeout.md +145 -0
  84. package/skills/cometchat-angular-calls/references/in-call-chat.md +148 -0
  85. package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +205 -0
  86. package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +53 -0
  87. package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +183 -0
  88. package/skills/cometchat-angular-calls/references/picture-in-picture.md +285 -0
  89. package/skills/cometchat-angular-calls/references/raise-hand.md +167 -0
  90. package/skills/cometchat-angular-calls/references/recording-screen-share.md +267 -0
  91. package/skills/cometchat-angular-calls/references/ringing-integration.md +131 -0
  92. package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +100 -0
  93. package/skills/cometchat-angular-calls/references/share-invite.md +116 -0
  94. package/skills/cometchat-angular-components/SKILL.md +1 -1
  95. package/skills/cometchat-angular-core/SKILL.md +1 -1
  96. package/skills/cometchat-angular-customization/SKILL.md +1 -1
  97. package/skills/cometchat-angular-features/SKILL.md +1 -1
  98. package/skills/cometchat-angular-patterns/SKILL.md +1 -1
  99. package/skills/cometchat-angular-placement/SKILL.md +1 -1
  100. package/skills/cometchat-angular-production/SKILL.md +1 -1
  101. package/skills/cometchat-angular-push/SKILL.md +403 -0
  102. package/skills/cometchat-angular-testing/SKILL.md +333 -0
  103. package/skills/cometchat-angular-theming/SKILL.md +1 -1
  104. package/skills/cometchat-angular-troubleshooting/SKILL.md +1 -1
  105. package/skills/cometchat-astro-patterns/SKILL.md +1 -1
  106. package/skills/cometchat-calls/SKILL.md +358 -0
  107. package/skills/cometchat-calls/references/use-case-broadcast.md +194 -0
  108. package/skills/cometchat-calls/references/use-case-marketplace.md +158 -0
  109. package/skills/cometchat-calls/references/use-case-support.md +190 -0
  110. package/skills/cometchat-calls/references/use-case-team.md +169 -0
  111. package/skills/cometchat-calls/references/use-case-telehealth.md +154 -0
  112. package/skills/cometchat-components/SKILL.md +1 -1
  113. package/skills/cometchat-core/SKILL.md +1 -1
  114. package/skills/cometchat-customization/SKILL.md +2 -2
  115. package/skills/cometchat-features/SKILL.md +2 -2
  116. package/skills/cometchat-flutter-v5/SKILL.md +1 -1
  117. package/skills/cometchat-flutter-v5-calls/SKILL.md +325 -94
  118. package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +169 -0
  119. package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +98 -0
  120. package/skills/cometchat-flutter-v5-calls/references/call-session.md +330 -0
  121. package/skills/cometchat-flutter-v5-calls/references/device-management.md +120 -0
  122. package/skills/cometchat-flutter-v5-calls/references/group-calls.md +187 -0
  123. package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +97 -0
  124. package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +132 -0
  125. package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +160 -0
  126. package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +244 -0
  127. package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +193 -0
  128. package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +101 -0
  129. package/skills/cometchat-flutter-v5-calls/references/share-invite.md +142 -0
  130. package/skills/cometchat-flutter-v5-conversations/SKILL.md +1 -1
  131. package/skills/cometchat-flutter-v5-core/SKILL.md +1 -1
  132. package/skills/cometchat-flutter-v5-customization/SKILL.md +1 -1
  133. package/skills/cometchat-flutter-v5-events/SKILL.md +1 -1
  134. package/skills/cometchat-flutter-v5-messages/SKILL.md +1 -1
  135. package/skills/cometchat-flutter-v5-production/SKILL.md +1 -1
  136. package/skills/cometchat-flutter-v5-push/SKILL.md +1 -1
  137. package/skills/cometchat-flutter-v5-testing/SKILL.md +390 -0
  138. package/skills/cometchat-flutter-v5-theming/SKILL.md +1 -1
  139. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +1 -1
  140. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +1 -1
  141. package/skills/cometchat-flutter-v6/SKILL.md +1 -1
  142. package/skills/cometchat-flutter-v6-calls/SKILL.md +308 -243
  143. package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +134 -0
  144. package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +102 -0
  145. package/skills/cometchat-flutter-v6-calls/references/call-session.md +229 -0
  146. package/skills/cometchat-flutter-v6-calls/references/device-management.md +99 -0
  147. package/skills/cometchat-flutter-v6-calls/references/group-calls.md +190 -0
  148. package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +80 -0
  149. package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +122 -0
  150. package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +268 -0
  151. package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +171 -0
  152. package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +93 -0
  153. package/skills/cometchat-flutter-v6-calls/references/share-invite.md +102 -0
  154. package/skills/cometchat-flutter-v6-components/SKILL.md +1 -1
  155. package/skills/cometchat-flutter-v6-conversations/SKILL.md +1 -1
  156. package/skills/cometchat-flutter-v6-core/SKILL.md +1 -1
  157. package/skills/cometchat-flutter-v6-customization/SKILL.md +1 -1
  158. package/skills/cometchat-flutter-v6-events/SKILL.md +1 -1
  159. package/skills/cometchat-flutter-v6-features/SKILL.md +1 -1
  160. package/skills/cometchat-flutter-v6-messages/SKILL.md +1 -1
  161. package/skills/cometchat-flutter-v6-migration/SKILL.md +1 -1
  162. package/skills/cometchat-flutter-v6-placement/SKILL.md +1 -1
  163. package/skills/cometchat-flutter-v6-production/SKILL.md +1 -1
  164. package/skills/cometchat-flutter-v6-push/SKILL.md +452 -0
  165. package/skills/cometchat-flutter-v6-testing/SKILL.md +319 -0
  166. package/skills/cometchat-flutter-v6-theming/SKILL.md +1 -1
  167. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +1 -1
  168. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +1 -1
  169. package/skills/cometchat-i18n/SKILL.md +358 -0
  170. package/skills/cometchat-ios/SKILL.md +5 -5
  171. package/skills/cometchat-ios-calls/SKILL.md +409 -0
  172. package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +172 -0
  173. package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +189 -0
  174. package/skills/cometchat-ios-calls/references/call-layouts.md +136 -0
  175. package/skills/cometchat-ios-calls/references/call-session.md +221 -0
  176. package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +353 -0
  177. package/skills/cometchat-ios-calls/references/custom-ui.md +322 -0
  178. package/skills/cometchat-ios-calls/references/device-management.md +171 -0
  179. package/skills/cometchat-ios-calls/references/group-calls.md +396 -0
  180. package/skills/cometchat-ios-calls/references/idle-timeout.md +185 -0
  181. package/skills/cometchat-ios-calls/references/in-call-chat.md +183 -0
  182. package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +138 -0
  183. package/skills/cometchat-ios-calls/references/picture-in-picture.md +246 -0
  184. package/skills/cometchat-ios-calls/references/raise-hand.md +239 -0
  185. package/skills/cometchat-ios-calls/references/recording-screen-share.md +339 -0
  186. package/skills/cometchat-ios-calls/references/ringing-integration.md +142 -0
  187. package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +267 -0
  188. package/skills/cometchat-ios-calls/references/share-invite.md +152 -0
  189. package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +246 -0
  190. package/skills/cometchat-ios-calls/references/voip-cert-setup.md +166 -0
  191. package/skills/cometchat-ios-components/SKILL.md +1 -1
  192. package/skills/cometchat-ios-core/SKILL.md +1 -1
  193. package/skills/cometchat-ios-customization/SKILL.md +1 -1
  194. package/skills/cometchat-ios-features/SKILL.md +1 -1
  195. package/skills/cometchat-ios-placement/SKILL.md +1 -1
  196. package/skills/cometchat-ios-production/SKILL.md +1 -1
  197. package/skills/cometchat-ios-push/SKILL.md +1 -1
  198. package/skills/cometchat-ios-testing/SKILL.md +371 -0
  199. package/skills/cometchat-ios-theming/SKILL.md +1 -1
  200. package/skills/cometchat-ios-troubleshooting/SKILL.md +1 -1
  201. package/skills/cometchat-native-bare-patterns/SKILL.md +45 -3
  202. package/skills/cometchat-native-calls/SKILL.md +599 -0
  203. package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +203 -0
  204. package/skills/cometchat-native-calls/references/call-layouts.md +124 -0
  205. package/skills/cometchat-native-calls/references/call-session.md +182 -0
  206. package/skills/cometchat-native-calls/references/custom-ui.md +250 -0
  207. package/skills/cometchat-native-calls/references/device-management.md +135 -0
  208. package/skills/cometchat-native-calls/references/expo-vs-bare.md +179 -0
  209. package/skills/cometchat-native-calls/references/group-calls.md +291 -0
  210. package/skills/cometchat-native-calls/references/idle-timeout.md +128 -0
  211. package/skills/cometchat-native-calls/references/in-call-chat.md +143 -0
  212. package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +72 -0
  213. package/skills/cometchat-native-calls/references/picture-in-picture.md +276 -0
  214. package/skills/cometchat-native-calls/references/raise-hand.md +203 -0
  215. package/skills/cometchat-native-calls/references/recording-screen-share.md +290 -0
  216. package/skills/cometchat-native-calls/references/ringing-integration.md +118 -0
  217. package/skills/cometchat-native-calls/references/server-push-bridge.md +135 -0
  218. package/skills/cometchat-native-calls/references/server-push-payloads.md +193 -0
  219. package/skills/cometchat-native-calls/references/share-invite.md +144 -0
  220. package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +317 -0
  221. package/skills/cometchat-native-components/SKILL.md +1 -1
  222. package/skills/cometchat-native-core/SKILL.md +1 -1
  223. package/skills/cometchat-native-customization/SKILL.md +1 -1
  224. package/skills/cometchat-native-expo-patterns/SKILL.md +18 -1
  225. package/skills/cometchat-native-features/SKILL.md +1 -1
  226. package/skills/cometchat-native-placement/SKILL.md +1 -1
  227. package/skills/cometchat-native-production/SKILL.md +1 -1
  228. package/skills/cometchat-native-push/SKILL.md +1 -1
  229. package/skills/cometchat-native-testing/SKILL.md +1 -1
  230. package/skills/cometchat-native-theming/SKILL.md +1 -1
  231. package/skills/cometchat-native-troubleshooting/SKILL.md +1 -1
  232. package/skills/cometchat-nextjs-patterns/SKILL.md +1 -1
  233. package/skills/cometchat-placement/SKILL.md +29 -1
  234. package/skills/cometchat-production/SKILL.md +1 -1
  235. package/skills/cometchat-react-calls/SKILL.md +539 -0
  236. package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +145 -0
  237. package/skills/cometchat-react-calls/references/call-layouts.md +161 -0
  238. package/skills/cometchat-react-calls/references/call-session.md +235 -0
  239. package/skills/cometchat-react-calls/references/custom-ui.md +201 -0
  240. package/skills/cometchat-react-calls/references/device-management.md +206 -0
  241. package/skills/cometchat-react-calls/references/group-calls.md +262 -0
  242. package/skills/cometchat-react-calls/references/idle-timeout.md +175 -0
  243. package/skills/cometchat-react-calls/references/in-call-chat.md +212 -0
  244. package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +172 -0
  245. package/skills/cometchat-react-calls/references/picture-in-picture.md +245 -0
  246. package/skills/cometchat-react-calls/references/raise-hand.md +238 -0
  247. package/skills/cometchat-react-calls/references/recording-screen-share.md +143 -0
  248. package/skills/cometchat-react-calls/references/ringing-integration.md +255 -0
  249. package/skills/cometchat-react-calls/references/server-web-push-vapid.md +241 -0
  250. package/skills/cometchat-react-calls/references/share-invite.md +176 -0
  251. package/skills/cometchat-react-calls/references/testing-calls-on-web.md +198 -0
  252. package/skills/cometchat-react-calls/references/voip-and-web-push.md +165 -0
  253. package/skills/cometchat-react-patterns/SKILL.md +56 -8
  254. package/skills/cometchat-react-push/SKILL.md +448 -0
  255. package/skills/cometchat-react-router-patterns/SKILL.md +1 -1
  256. package/skills/cometchat-react-testing/SKILL.md +404 -0
  257. package/skills/cometchat-theming/SKILL.md +3 -3
  258. package/skills/cometchat-troubleshooting/SKILL.md +2 -2
@@ -0,0 +1,409 @@
1
+ ---
2
+ name: cometchat-ios-calls
3
+ description: CometChat Calls SDK v5 integration for native iOS (Swift; SwiftUI + UIKit hosting). Covers SDK install (SPM + CocoaPods), CometChatCalls init, dual-SDK ringing (Chat SDK initiateCall + Calls SDK joinSession), CallKit + PushKit VoIP push, AVAudioSession routing, mixed-stack hosting (UIViewControllerRepresentable for SwiftUI), Info.plist permissions + Background Modes, and additive-vs-standalone modes.
4
+ license: "MIT"
5
+ compatibility: "Xcode 15+, Swift 5.9+, iOS 13+ deployment target; CometChatCallsSDK 5.x; CometChatSDK 4.x; CometChatUIKitSwift 5.x (additive mode)"
6
+ allowed-tools: "shell, file-read, file-search, file-list, ask-user"
7
+ metadata:
8
+ author: "CometChat"
9
+ version: "4.0.0"
10
+ tags: "cometchat ios calls voice video webrtc swift swiftui uikit callkit pushkit avaudiosession spm cocoapods voip background-modes"
11
+ ---
12
+
13
+ ## Purpose
14
+
15
+ Production-grade voice + video calling for native iOS. Loaded by `cometchat-calls` when `framework === "ios"`. Operates in two modes:
16
+
17
+ - **Standalone** — calls is the product. `CometChatSDK` (signaling) + `CometChatCallsSDK` (WebRTC) + your own SwiftUI views or UIKit view controllers. **CallKit + PushKit are mandatory.**
18
+ - **Additive** — calls layered onto an existing CometChat iOS UI Kit integration. The kit's `CometChatMessageHeader` already exposes call buttons; this skill wires them and mounts the global call listener.
19
+
20
+ **Read these other skills first:**
21
+ - `cometchat-calls` — dispatcher (modes, hard rules, anti-patterns)
22
+ - `cometchat-ios-core` — Chat SDK init, login, `Secrets.swift` / `.xcconfig` credential conventions, SwiftUI vs UIKit entry-point detection
23
+
24
+ **Ground truth:**
25
+ - SDK source — `~/Downloads/calls-sdk/calls-sdk-ios-5/sdk/`
26
+ - Sample app — `~/Downloads/calls-sdk/calls-sdk-ios-5/sample-apps/cometchat-calls-sample-app-ios/`
27
+ - `Package.swift` — `https://github.com/cometchat/calls-sdk-ios.git` (SPM)
28
+ - Public docs — https://www.cometchat.com/docs/calls/ios/overview
29
+
30
+ ---
31
+
32
+ ## ⚠️ Known upstream issue — iOS v5 binary is broken (May 2026)
33
+
34
+ **SPM and CocoaPods both fail to resolve the iOS Calls SDK v5** because the WebRTC binary it depends on is missing from Cloudsmith:
35
+
36
+ ```
37
+ https://dl.cloudsmith.io/public/cometchat/cometchat/raw/versions/124.0.4/CometChatWebRTC-124.0.4.xcframework.zip
38
+ → 404 Not Found
39
+ ```
40
+
41
+ This affects every v5 tag (`5.0.0`, `5.0.0-beta.1` … `5.0.0-beta.3`). The `Package.swift` and `.podspec` both reference the same broken URL.
42
+
43
+ **Until upstream republishes the binary:**
44
+ - Customers on iOS should stay on **v4.2.x** of the Calls SDK (it has its own WebRTC dependency that's still hosted)
45
+ - If you must use v5 for parity with other platforms, contact CometChat support for a working binary or a private SPM fork
46
+ - This skill's v5 setup section assumes the binary is available — that assumption is currently invalid for iOS only
47
+
48
+ Tracking this so the next audit pass can verify when it's fixed. The vendor sample-apps at `~/Downloads/calls-sdk/calls-sdk-ios-5/sample-apps/` reference the same broken binary — they don't ship a workaround.
49
+
50
+ ---
51
+
52
+ ## 1. The seven hard rules — iOS specialization
53
+
54
+ ### 1.0 Calls SDK login is its own step (v5+)
55
+
56
+ The v5 Calls SDK has its own auth state, separate from the Chat SDK. After `CometChat.login` succeeds, you MUST also call `CometChatCalls.login` — without it, the FIRST calls API call throws **"auth token cannot be null"**.
57
+
58
+ ```swift
59
+ import CometChatSDK
60
+ import CometChatCallsSDK
61
+
62
+ CometChat.login(UID: uid, authKey: AUTH_KEY) { user in
63
+ // Chat SDK ready — now login Calls SDK
64
+ CometChatCalls.login(UID: uid, authKey: AUTH_KEY) { callUser in
65
+ // both ready — incoming-call listener can be registered, calls can fire
66
+ } onError: { error in
67
+ // surface to user — common cause: typo in app id / auth key
68
+ }
69
+ } onError: { error in
70
+ // chat login failed; calls login never fires
71
+ }
72
+ ```
73
+
74
+ For production with server-minted tokens:
75
+
76
+ ```swift
77
+ CometChatCalls.login(authToken: tokenFromBackend) { callUser in
78
+ // …
79
+ } onError: { error in /* … */ }
80
+ ```
81
+
82
+ **Surprises:**
83
+ - The Chat SDK persists login via Keychain across app launches. The **Calls SDK does NOT** persist as reliably — always check `CometChatCalls.getLoggedInUser()` on app start and re-login if nil.
84
+ - Calls SDK errors hit the `onError` closure (not `do/try/catch`). The error type is `CometChatException` from the Calls module — has `errorDescription` and `errorCode`.
85
+
86
+ ### 1.1 Dual-SDK contract
87
+
88
+ Chat SDK (`CometChatSDK`) initiates ringing; Calls SDK (`CometChatCallsSDK`) runs the WebRTC session. There is no two-`Call`-classes problem on iOS — Swift's module separation prevents it. But the API split still exists:
89
+
90
+ ```swift
91
+ // ✓ RIGHT — initiate ringing (Chat SDK)
92
+ import CometChatSDK
93
+
94
+ let outgoing = Call(receiverUid: receiverUid, receiverType: .user, callType: .video)
95
+ CometChat.initiateCall(call: outgoing, onSuccess: { initiated in
96
+ // initiated.sessionID is what the Calls SDK will join
97
+ }, onError: { error in
98
+ // surface to UI
99
+ })
100
+ ```
101
+
102
+ ```swift
103
+ // ✓ RIGHT — join WebRTC session (Calls SDK) after acceptance.
104
+ // Matches upstream sample at calls-sdk-ios-5/sample-apps/cometchat-calls-
105
+ // sample-app-ringing-ios/CometChatCallsRinging/CallView.swift.
106
+ // - SessionSettingsBuilder (NOT CallSettingsBuilder — that's chat-side)
107
+ // - Single-call joinSession(sessionID:callSetting:container:) — token is
108
+ // generated internally; no separate generateToken needed
109
+ // - Register listeners on the resulting CallSession in onSuccess
110
+ import CometChatCallsSDK
111
+
112
+ let settings = SessionSettingsBuilder()
113
+ .setTitle("CometChat Call")
114
+ .startVideoPaused(false)
115
+ .startAudioMuted(false)
116
+ .build()
117
+
118
+ CometChatCalls.joinSession(
119
+ sessionID: sessionID,
120
+ callSetting: settings,
121
+ container: callContainerView // UIView with measurable bounds
122
+ ) { success in
123
+ let session = CometChatCallsSDK.CallSession.shared
124
+ session.addSessionStatusListener(callListener)
125
+ session.addButtonClickListener(callListener)
126
+ } onError: { error in
127
+ print("joinSession failed: \(error?.errorDescription ?? "unknown")")
128
+ }
129
+ ```
130
+
131
+ ### 1.2 CallKit + PushKit are mandatory
132
+
133
+ iOS will not deliver standard push notifications to a backgrounded/terminated app for an incoming call — the app would have to be foregrounded for it to ring. CallKit + PushKit is the only correct path:
134
+
135
+ - **PushKit** delivers VoIP push tokens (separate from APNs tokens) and high-priority VoIP payloads even when the app is terminated
136
+ - **CallKit** presents the system incoming-call UI (lock-screen, even when device is locked) and reports call state to the OS
137
+ - Your `PKPushRegistry` listener calls `CXProvider.reportNewIncomingCall(...)` immediately on receiving the VoIP payload — Apple terminates apps that delay this
138
+
139
+ This pattern is non-negotiable for App Store review on apps that ring users. Standalone mode wires it; additive mode prompts but doesn't force it.
140
+
141
+ ### 1.3 Background modes — three required entries
142
+
143
+ In the target's "Signing & Capabilities" → Background Modes:
144
+
145
+ - **`Audio, AirPlay, and Picture in Picture`** — required for ongoing-call audio when backgrounded
146
+ - **`Voice over IP`** — required for PushKit VoIP payload delivery
147
+ - **`Remote notifications`** — required for chat push (keeps existing entitlements working)
148
+
149
+ In `Info.plist`:
150
+
151
+ ```xml
152
+ <key>UIBackgroundModes</key>
153
+ <array>
154
+ <string>audio</string>
155
+ <string>voip</string>
156
+ <string>remote-notification</string>
157
+ </array>
158
+ ```
159
+
160
+ Apple will reject the app if `voip` is declared but PushKit is not actually used.
161
+
162
+ ### 1.4 Server-minted auth tokens
163
+
164
+ Same rule as the chat dispatcher / `cometchat-ios-production`. Production calls path uses `CometChat.login(authToken:)`, not `CometChat.login(uid:authKey:)`.
165
+
166
+ ### 1.5 Hangup cleanup — `AVAudioSession` routing
167
+
168
+ Releasing the camera + mic on iOS is straightforward; the gotcha is `AVAudioSession`:
169
+
170
+ ```swift
171
+ import CometChatCallsSDK // for the CallSession namespace
172
+
173
+ func endCall() {
174
+ // v5: leaveSession lives on the CallSession singleton, NOT on CometChatCalls.
175
+ // CometChatCalls.endSession() exists as a deprecated alias but the v5 API is
176
+ // singleton-based — use the form below to stay forward-compatible.
177
+ CometChatCallsSDK.CallSession.shared.leaveSession()
178
+ callContainer.subviews.forEach { $0.removeFromSuperview() }
179
+
180
+ // CRITICAL: deactivate the audio session, otherwise the speaker stays
181
+ // routed to "earpiece + voice processing" mode and other audio (music,
182
+ // phone calls outside the app) sounds wrong until the user resets it.
183
+ do {
184
+ try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
185
+ } catch {
186
+ // log but don't block — best-effort cleanup
187
+ }
188
+
189
+ // CallKit must be told the call ended, even if WE ended it
190
+ cxProvider.reportCall(with: callUUID, endedAt: Date(), reason: .remoteEnded)
191
+ }
192
+ ```
193
+
194
+ **Module-qualified `CometChatCallsSDK.CallSession.shared`** is the canonical reference (matches the iOS sample app). `CallSession` exists in both `CometChatSDK` and `CometChatCallsSDK` modules — Swift will resolve the unqualified name based on import order, but qualifying with the module prefix makes intent explicit and avoids drift if Swift's resolution changes. Same singleton hosts the in-call control APIs:
195
+
196
+ ```swift
197
+ CometChatCallsSDK.CallSession.shared.muteAudio()
198
+ CometChatCallsSDK.CallSession.shared.unmuteAudio()
199
+ CometChatCallsSDK.CallSession.shared.pauseVideo()
200
+ CometChatCallsSDK.CallSession.shared.resumeVideo()
201
+ CometChatCallsSDK.CallSession.shared.startScreenShare()
202
+ CometChatCallsSDK.CallSession.shared.stopScreenShare()
203
+ ```
204
+
205
+ Skipping the `setActive(false, options: .notifyOthersOnDeactivation)` is the canonical "music doesn't resume after the call" bug.
206
+
207
+ ### 1.6 Permissions with rationale — Info.plist usage strings
208
+
209
+ Two required entries; iOS rejects builds that record without them:
210
+
211
+ ```xml
212
+ <key>NSMicrophoneUsageDescription</key>
213
+ <string>So you can talk during voice and video calls.</string>
214
+ <key>NSCameraUsageDescription</key>
215
+ <string>So you can be seen during video calls.</string>
216
+ ```
217
+
218
+ Plus, on iOS 15+, request permission via `AVCaptureDevice.requestAccess(for:)` and `AVAudioApplication.requestRecordPermission` (deprecating `AVAudioSession.requestRecordPermission` in iOS 17+). The skill writes the modern path.
219
+
220
+ ### 1.7 IncomingCall UI — CallKit owns it
221
+
222
+ In standalone mode, you do NOT render an in-app incoming-call screen. CallKit's system UI handles it (rule 1.2). Your job is:
223
+
224
+ 1. Keep `PKPushRegistry` alive — register in `application(_:didFinishLaunchingWithOptions:)` (UIKit) or `App.init()` (SwiftUI's `@main`)
225
+ 2. On VoIP payload → call `CXProvider.reportNewIncomingCall`
226
+ 3. Implement `CXProviderDelegate` `provider(_:perform:)` for `CXAnswerCallAction` — this is where you finally call `CometChatCalls.joinSession`
227
+
228
+ In additive mode, the UI Kit's incoming-call view can be used for in-foreground rings; CallKit handles backgrounded/terminated rings.
229
+
230
+ ---
231
+
232
+ ## 2. Setup
233
+
234
+ ### Swift Package Manager (preferred)
235
+
236
+ Add via Xcode → File → Add Package Dependencies:
237
+
238
+ ```
239
+ https://github.com/cometchat/calls-sdk-ios.git
240
+ ```
241
+
242
+ Pin to `5.0.0..<6.0.0`. SPM resolves `CometChatSDK` automatically.
243
+
244
+ ### CocoaPods
245
+
246
+ ```ruby
247
+ platform :ios, '13.0'
248
+ target 'YourApp' do
249
+ use_frameworks!
250
+ pod 'CometChatSDK', '~> 4.0' # signaling
251
+ pod 'CometChatCallsSDK', '~> 5.0' # WebRTC session
252
+ # additive mode also has CometChatUIKitSwift '~> 5.1' already
253
+ end
254
+
255
+ post_install do |installer|
256
+ installer.pods_project.build_configurations.each do |config|
257
+ config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO' # Xcode 15+
258
+ end
259
+ end
260
+ ```
261
+
262
+ ### Init
263
+
264
+ In SwiftUI app entry (`@main struct App.init()`) or UIKit `application(_:didFinishLaunchingWithOptions:)`:
265
+
266
+ ```swift
267
+ import CometChatSDK
268
+ import CometChatCallsSDK
269
+
270
+ let appSettings = AppSettings.AppSettingsBuilder()
271
+ .subscribePresenceForAllUsers()
272
+ .setRegion(region: Secrets.cometchatRegion)
273
+ .build()
274
+
275
+ CometChat.init(appId: Secrets.cometchatAppID, appSettings: appSettings) { isInitialized, error in
276
+ guard error == nil else { return }
277
+
278
+ let callAppSettings = CallAppSettingsBuilder()
279
+ .setAppId(Secrets.cometchatAppID)
280
+ .setRegion(Secrets.cometchatRegion)
281
+ .build()
282
+
283
+ CometChatCalls.init(callAppSettings: callAppSettings) { _ in
284
+ // ready — register PushKit (rule 1.2) and CXProvider (rule 1.7) here
285
+ }
286
+ }
287
+ ```
288
+
289
+ Credentials via `Secrets.swift` (gitignored) or `.xcconfig` Build Settings — see `cometchat-ios-core`.
290
+
291
+ ---
292
+
293
+ ## 3. Components catalog
294
+
295
+ ### Calls SDK primitives (used in standalone or wherever you build custom UI)
296
+
297
+ | Type | Purpose |
298
+ |---|---|
299
+ | `CometChatCalls` | Top-level facade — init, joinSession, endSession, generateToken |
300
+ | `CallSettingsBuilder` | Per-session config (type, layout, hide buttons, audio mode) |
301
+ | `CallSession` | Active session object — held during a call |
302
+ | `CallType` | `.voice` / `.video` |
303
+ | `LayoutMode` | `.tile` / `.sidebar` / `.spotlight` |
304
+ | `CallLogRequest.CallLogRequestBuilder` | Paginated call history |
305
+ | `CometChatCallsEventsListener` (protocol) | Lifecycle + media + participant + button events |
306
+
307
+ ### UI Kit views (additive mode — `CometChatUIKitSwift`)
308
+
309
+ | View / VC | Purpose |
310
+ |---|---|
311
+ | `CometChatCallButton` | Voice + video button row (standalone or in `CometChatMessageHeader`) |
312
+ | `CometChatIncomingCall` (UIViewController) | Foreground in-app ring UI |
313
+ | `CometChatOutgoingCall` (UIViewController) | Dialing UI |
314
+ | `CometChatOngoingCall` (UIViewController) | Active call UI hosting WebRTC |
315
+ | `CometChatCallLogs` (UIViewController) | Paginated history |
316
+
317
+ SwiftUI hosting via `UIViewControllerRepresentable`:
318
+
319
+ ```swift
320
+ struct CallLogsView: UIViewControllerRepresentable {
321
+ func makeUIViewController(context: Context) -> CometChatCallLogs { CometChatCallLogs() }
322
+ func updateUIViewController(_ vc: CometChatCallLogs, context: Context) {}
323
+ }
324
+ ```
325
+
326
+ ---
327
+
328
+ ## 4. Standalone integration
329
+
330
+ When `product === "voice-video"` and there is no existing UI Kit.
331
+
332
+ **Split by calling mode:**
333
+
334
+ ### 4a. Standalone — Session mode (meeting-room UX, no ringing)
335
+
336
+ Calls SDK ONLY. NO Chat SDK, NO CallKit, NO PushKit. Matches `~/Downloads/calls-sdk/calls-sdk-ios-5/sample-apps/cometchat-calls-sample-app-ios/`. Scaffold:
337
+
338
+ 1. **App entry** — `CometChatCalls.init({appId, region, authKey})` ONLY. No `CometChat.init`, no `CometChat.login`, no PushKit, no CallKit.
339
+ 2. **`JoinSessionView.swift`** — UID picker + "Start meeting" / "Join meeting" + state.
340
+ 3. **`CallView.swift` + `CallContainerView: UIViewRepresentable`** — Single-call `CometChatCalls.joinSession(sessionID:callSetting:container:)`. Coordinator implements `SessionStatusListener` + `ButtonClickListener`. See `references/call-session.md`.
341
+ 4. **`Info.plist` patch** — Camera + microphone permissions ONLY. No `audio` or `voip` Background Modes needed.
342
+ 5. **Universal Link routing** — meeting URL → CallView.
343
+
344
+ **Why no CallKit / no PushKit:** session mode is link-driven, not push-driven. No incoming ring to surface.
345
+
346
+ ### 4b. Standalone — Ringing mode (CallKit + PushKit + Chat SDK signaling)
347
+
348
+ Dual-SDK + CallKit + PushKit. Scaffold:
349
+
350
+ 1. **App entry** — Chat SDK + Calls SDK init, PushKit + CallKit registration (rule 1.2, 1.7).
351
+ 2. **`CallKitProviderDelegate.swift`** — `CXProviderDelegate` implementation. Routes `CXAnswerCallAction` → `CometChatCalls.joinSession(sessionID:callSetting:container:)`. Routes `CXEndCallAction` → `CallSession.shared.leaveSession()` + `AVAudioSession` cleanup (rule 1.5).
352
+ 3. **`PushRegistryDelegate.swift`** — `PKPushRegistryDelegate` listening on `.voIP`. On payload → `CXProvider.reportNewIncomingCall` immediately.
353
+ 4. **`ProfileView.swift` (SwiftUI) or `ProfileViewController.swift` (UIKit)** — Hosts call buttons next to user info. Tap → `CometChat.initiateCall`.
354
+ 5. **`OngoingCallView.swift`** — Custom view hosting the SDK's call surface via `UIViewRepresentable` bridging. Implements rule 1.5 teardown.
355
+ 6. **`CallLogsView.swift`** — `/calls` equivalent — `CallLogRequest.CallLogRequestBuilder`.
356
+ 7. **`Info.plist` patch** — Background Modes (rule 1.3), permissions (rule 1.6).
357
+ 8. **VoIP Services certificate setup** — manual step (Apple Developer portal + App Store Connect). The skill documents the steps; cannot automate.
358
+
359
+ ## 5. Additive integration
360
+
361
+ When `cometchat-ios` is already integrated. The skill:
362
+
363
+ 1. Adds `CometChatCallsSDK` to SPM or Podfile.
364
+ 2. Adds `CometChatCalls.init(...)` to the existing `CometChat.init` success callback.
365
+ 3. Adds Background Modes + permissions to `Info.plist`.
366
+ 4. Wires `CometChatMessageHeader` call buttons (already rendered by the kit — just enable them).
367
+ 5. Adds CallKit + PushKit (asks user — same opt-in as Android).
368
+ 6. Adds `CallLogsView` as an additional tab/route.
369
+
370
+ ## 6. Anti-patterns
371
+
372
+ 1. **Skipping CallKit + PushKit** in standalone mode. The app cannot ring backgrounded/terminated devices any other way. App Store reviewers test this.
373
+ 2. **Calling `CXProvider.reportNewIncomingCall` after async work.** Apple terminates the app process if the report happens more than ~5 seconds after PushKit delivery. Report immediately, then do the actual `joinSession` from inside `CXAnswerCallAction`.
374
+ 3. **Forgetting `setActive(false, options: .notifyOthersOnDeactivation)`** on hangup. Music/phone-call audio sounds wrong until the next foreground. The "looks fine in dev, fails review" bug.
375
+ 4. **Declaring `voip` in `UIBackgroundModes` without using PushKit.** Apple rejects.
376
+ 5. **Mixing CallKit and an in-app incoming-call screen** in standalone mode. Causes double-rings and confused state. CallKit owns standalone rings; in-app UI is additive-mode only.
377
+ 6. **Using SwiftUI `.alert` for incoming calls.** It only fires when the app is foregrounded. Use CallKit (rule 1.7).
378
+ 7. **Pinning `CometChatCallsSDK` to a `4.x`** because that's what the chat SDK is on. They version independently — Calls SDK 5.x is the current calls major.
379
+
380
+ ## 7. Verification checklist
381
+
382
+ **Static:**
383
+
384
+ - [ ] `CometChatCallsSDK` in SPM Package.resolved or Podfile.lock
385
+ - [ ] `CometChat.init` followed by `CometChatCalls.init` in app entry
386
+ - [ ] PushKit registry listening on `.voIP`
387
+ - [ ] `CXProvider` configured with `CXProviderConfiguration` (app name + ringtone if any)
388
+ - [ ] `CXProviderDelegate` implements answer + end actions
389
+ - [ ] `Info.plist` has `NSMicrophoneUsageDescription` + `NSCameraUsageDescription`
390
+ - [ ] `Info.plist` `UIBackgroundModes` has `audio` + `voip` + `remote-notification`
391
+ - [ ] Hangup path includes `endSession` + `setActive(false, options: .notifyOthersOnDeactivation)` + `cxProvider.reportCall(...endedAt:reason:)`
392
+ - [ ] **Standalone only:** No in-app incoming-call screen — CallKit owns it
393
+
394
+ **Runtime (real device):**
395
+
396
+ - [ ] Outgoing call connects, two-way audio + video
397
+ - [ ] Incoming call rings on lock screen (device locked + app terminated)
398
+ - [ ] Tap "Answer" on lock screen → app opens directly into ongoing call
399
+ - [ ] Hangup ends call, camera light off, music resumes if it was playing
400
+ - [ ] Background the app during a call → audio continues
401
+ - [ ] Lock device during a call → ongoing-call UI on lock screen, audio continues
402
+
403
+ ## 8. Pointers
404
+
405
+ - `cometchat-ios-core` — Chat SDK init, login, `Secrets.swift` conventions
406
+ - `cometchat-ios-components` — full UI Kit catalog (additive mode)
407
+ - `cometchat-ios-push` — APNs setup; some overlap with PushKit but distinct (PushKit is VoIP-only)
408
+ - `cometchat-ios-production` — server-minted tokens, security checklist
409
+ - `cometchat-ios-troubleshooting` — common failure modes (PushKit delivery, CallKit reporting timing, ENABLE_USER_SCRIPT_SANDBOXING)
@@ -0,0 +1,172 @@
1
+ # Adding calls to an existing chat integration (iOS)
2
+
3
+ You have `CometChatUIKitSwift` working. This guide adds `CometChatCallsSDK` plus PushKit + CallKit + the seven hard rules.
4
+
5
+ **Read first:** `cometchat-ios-calls/SKILL.md` — seven hard rules (init order, IncomingCall mount, hangup teardown, VoIP push, etc.).
6
+
7
+ ---
8
+
9
+ ## Step 1 — Install Calls SDK
10
+
11
+ **SwiftPM:**
12
+ - File → Add Packages → `https://github.com/cometchat/calls-sdk-ios` → version `5.0.0+`
13
+ - Add `CometChatCallsSDK` to your app target
14
+
15
+ **CocoaPods:**
16
+ ```ruby
17
+ pod 'CometChatCallsSDK', '~> 5.0'
18
+ ```
19
+ ```bash
20
+ pod install --repo-update
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Step 2 — Add capabilities + Info.plist entries
26
+
27
+ **Xcode → target → Signing & Capabilities:**
28
+ - Push Notifications
29
+ - Background Modes → check Audio, AirPlay, and Picture in Picture + Voice over IP + Remote notifications
30
+
31
+ **Info.plist:**
32
+ ```xml
33
+ <key>UIBackgroundModes</key>
34
+ <array>
35
+ <string>audio</string>
36
+ <string>voip</string>
37
+ <string>remote-notification</string>
38
+ </array>
39
+ <key>NSCameraUsageDescription</key>
40
+ <string>Camera access is required for video calls.</string>
41
+ <key>NSMicrophoneUsageDescription</key>
42
+ <string>Microphone access is required for calls.</string>
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Step 3 — Init order: chat → calls
48
+
49
+ Wherever you currently call `CometChatUIKit.init(uikitSettings:)`, append the calls init:
50
+
51
+ ```swift
52
+ import CometChatSDK
53
+ import CometChatCallsSDK
54
+ import CometChatUIKitSwift
55
+
56
+ // Existing chat init
57
+ CometChatUIKit.init(uikitSettings: chatSettings) { result in
58
+ switch result {
59
+ case .success:
60
+ // NEW: Calls init AFTER chat init succeeded
61
+ let callsSettings = CallAppSettings(appId: APP_ID, region: REGION)
62
+ Task {
63
+ try await CometChatCalls.init(with: callsSettings)
64
+ }
65
+ case .onError(let error):
66
+ print(error)
67
+ }
68
+ }
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Step 4 — Login
74
+
75
+ After your existing login flow:
76
+
77
+ ```swift
78
+ let user = try await CometChat.loginAsync(uid: uid, authKey: authKey)
79
+ let authToken = user.authToken
80
+ try await CometChatCalls.login(authToken: authToken)
81
+ ```
82
+
83
+ If you use server-minted auth tokens (recommended), pass that token to both SDKs.
84
+
85
+ ---
86
+
87
+ ## Step 5 — Mount IncomingCall at root
88
+
89
+ In SwiftUI:
90
+
91
+ ```swift
92
+ @main
93
+ struct YourApp: App {
94
+ var body: some Scene {
95
+ WindowGroup {
96
+ RootView()
97
+ .overlay(alignment: .top) {
98
+ CometChatIncomingCall()
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ In UIKit:
106
+ - Make a `RootViewController` that holds your existing app + the `CometChatIncomingCallView`
107
+ - Or use `UIWindow.rootViewController` swap pattern when an incoming call arrives
108
+
109
+ ---
110
+
111
+ ## Step 6 — PushKit + CallKit registration
112
+
113
+ Implement `PKPushRegistryDelegate` (see `cometchat-ios-calls/references/server-apns-pushkit.md`):
114
+
115
+ ```swift
116
+ class VoipPushHandler: NSObject, PKPushRegistryDelegate {
117
+ let registry = PKPushRegistry(queue: .main)
118
+ let callProvider: CXProvider
119
+
120
+ func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
121
+ let token = credentials.token.map { String(format: "%02x", $0) }.joined()
122
+ Task { try await api.registerVoipToken(uid: currentUid, token: token) }
123
+ }
124
+
125
+ func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
126
+ // Report to CallKit IMMEDIATELY
127
+ let update = CXCallUpdate()
128
+ let dict = payload.dictionaryPayload
129
+ update.remoteHandle = CXHandle(type: .generic, value: dict["callerUid"] as? String ?? "Unknown")
130
+ update.localizedCallerName = dict["callerName"] as? String ?? "Unknown"
131
+ update.hasVideo = (dict["callType"] as? String) == "video"
132
+ callProvider.reportNewIncomingCall(with: UUID(), update: update) { _ in completion() }
133
+ }
134
+ }
135
+ ```
136
+
137
+ Init this handler from your `AppDelegate.didFinishLaunchingWithOptions`.
138
+
139
+ ---
140
+
141
+ ## Step 7 — Hangup teardown
142
+
143
+ ```swift
144
+ func endCall(sessionId: String) async {
145
+ CometChatCalls.leaveSession()
146
+ try? await CometChat.endCallAsync(sessionId: sessionId)
147
+ callProvider.reportCall(with: callUUID, endedAt: nil, reason: .remoteEnded)
148
+ }
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Verification checklist
154
+
155
+ - [ ] `CometChatCallsSDK` in SwiftPM/CocoaPods
156
+ - [ ] Background Modes capability + Info.plist UIBackgroundModes (audio + voip + remote-notification)
157
+ - [ ] NSCameraUsageDescription + NSMicrophoneUsageDescription
158
+ - [ ] Calls init runs AFTER chat init succeeds
159
+ - [ ] `CometChatCalls.login` runs after chat login
160
+ - [ ] `CometChatIncomingCall` mounted at root (SwiftUI overlay or UIKit window-root)
161
+ - [ ] PushKit registry initialized + reports to CallKit within 5s
162
+ - [ ] Hangup teardown ends both SDK + CallKit + chat-side call record
163
+ - [ ] Real-device smoke: backgrounded incoming call rings on lock screen
164
+ - [ ] Run `cometchat verify --calls` — should pass
165
+
166
+ ---
167
+
168
+ ## Pointers
169
+
170
+ - `cometchat-react-calls/references/add-calls-to-existing-chat.md` — canonical (no native modules)
171
+ - `cometchat-ios-calls/SKILL.md` — seven hard rules
172
+ - `cometchat-ios-calls/references/server-apns-pushkit.md` — server-side PushKit