@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,246 @@
1
+ # Picture-in-Picture on iOS
2
+
3
+ iOS supports PiP for video calls via `AVPictureInPictureController` (iOS 14+) or via CallKit's auto-PiP (iOS 14+ when CallKit reports a video call). For most production calling apps, **CallKit handles PiP for free** — if you've integrated CallKit (rule 1.7 in the SKILL.md), iOS auto-PiPs your call when the user backgrounds the app.
4
+
5
+ The `AVPictureInPictureController` path is only needed for non-CallKit foreground-only calls (rare — most production apps use CallKit).
6
+
7
+ ---
8
+
9
+ ## CallKit auto-PiP — the simplest path
10
+
11
+ If your app integrates CallKit (rule 1.7, mandatory for VoIP push standalone mode), iOS auto-handles PiP. When the user presses Home during an active call:
12
+
13
+ 1. iOS automatically captures the call's video stream
14
+ 2. The CallKit-managed call enters PiP mode
15
+ 3. The PiP window floats above all apps, even system UI
16
+ 4. Tapping the PiP window foregrounds your app
17
+
18
+ No code needed beyond CallKit setup. The skill defaults to this path for standalone-mode calls.
19
+
20
+ ### Required entitlements
21
+
22
+ ```xml
23
+ <!-- Info.plist — already required by CallKit -->
24
+ <key>UIBackgroundModes</key>
25
+ <array>
26
+ <string>audio</string>
27
+ <string>voip</string>
28
+ <string>remote-notification</string>
29
+ </array>
30
+ ```
31
+
32
+ `audio` background mode is what lets the call's audio continue while in PiP. Without it, video PiP works but audio cuts.
33
+
34
+ ---
35
+
36
+ ## SDK-managed PiP layout — `CallSession.shared.enablePictureInPictureLayout()`
37
+
38
+ > **Audit 2026-05-14, confirmed against `https://www.cometchat.com/docs/calls/ios/picture-in-picture.md`:** The iOS Calls SDK v5.x exposes two methods to toggle the SDK's INTERNAL compact layout — it does NOT expose video frames or a `CMSampleBuffer` pipeline to drive a host-app `AVPictureInPictureController`. An earlier draft of this doc cited `CometChatCalls.attachPictureInPictureLayer(layer)` / `detachPictureInPictureLayer()` — **those symbols do not exist on CometChatCallsSDK v5.x**.
39
+
40
+ ### What works today
41
+
42
+ | Goal | API |
43
+ |---|---|
44
+ | Switch the SDK's call surface to compact "PiP-style" layout | `CallSession.shared.enablePictureInPictureLayout()` |
45
+ | Switch back to full layout | `CallSession.shared.disablePictureInPictureLayout()` |
46
+
47
+ ```swift
48
+ import CometChatCallsSDK
49
+
50
+ // When the user taps "minimize" in the call UI
51
+ CallSession.shared.enablePictureInPictureLayout()
52
+
53
+ // When they tap to expand back, or before hangup
54
+ CallSession.shared.disablePictureInPictureLayout()
55
+ ```
56
+
57
+ This is **NOT iOS system-level PiP** (the floating window that survives backgrounding). It's an in-app compact layout. For true OS-level PiP (floating call window across all apps + lock screen), see the CallKit path above.
58
+
59
+ ### Custom system-level PiP via `AVPictureInPictureController` — NOT directly supported
60
+
61
+ Driving iOS system-level PiP via `AVPictureInPictureController` requires feeding video frames to an `AVSampleBufferDisplayLayer`. The Calls SDK does not expose its WebRTC video track for this — the peer-connection handle is internal. Three options:
62
+
63
+ 1. **Recommended: use CallKit** (rule 1.7 SKILL.md). CallKit-managed VoIP calls get auto-PiP for free — no `AVPictureInPictureController` plumbing needed.
64
+ 2. **Use the SDK's compact layout API** (above) for in-app minimization. Acceptable UX for foreground-only flows.
65
+ 3. **Roll your own WebRTC bridge.** Requires forking/patching the SDK to expose the underlying `RTCMediaStream` — not recommended.
66
+
67
+ ### Required capability (CallKit path)
68
+
69
+ In Xcode → Signing & Capabilities → Background Modes → ensure **Audio, AirPlay, and Picture in Picture** is checked. CallKit needs this; without it, CallKit's auto-PiP doesn't fire even with a CallKit-managed call.
70
+
71
+ ### Toggle button for SDK compact layout
72
+
73
+ ```swift
74
+ @IBAction func toggleCompactLayout(_ sender: UIButton) {
75
+ if isCompact {
76
+ CallSession.shared.disablePictureInPictureLayout()
77
+ } else {
78
+ CallSession.shared.enablePictureInPictureLayout()
79
+ }
80
+ isCompact.toggle()
81
+ }
82
+ ```
83
+
84
+ This switches the SDK's call surface between full and compact layouts. The compact view shows local + remote video tiles in a smaller container; useful when you want to free screen space for other UI but keep the call visible.
85
+
86
+ > **Note**: `AVPictureInPictureController` + KVO on `isPictureInPicturePossible` patterns (previously documented here) are not applicable because the SDK does not expose the video frames `AVPictureInPictureController` requires. Use the CallKit path for system-level PiP, or this compact-layout API for in-app PiP-style minimization.
87
+
88
+ ---
89
+
90
+ ## SwiftUI integration
91
+
92
+ Wrap the UIKit view controller as a `UIViewControllerRepresentable`:
93
+
94
+ ```swift
95
+ struct PiPCallView: UIViewControllerRepresentable {
96
+ let sessionID: String
97
+
98
+ func makeUIViewController(context: Context) -> CustomOngoingCallViewController {
99
+ let vc = CustomOngoingCallViewController(sessionID: sessionID)
100
+ return vc
101
+ }
102
+
103
+ func updateUIViewController(_ vc: CustomOngoingCallViewController, context: Context) {}
104
+ }
105
+ ```
106
+
107
+ Use in your SwiftUI app:
108
+
109
+ ```swift
110
+ struct CallScreen: View {
111
+ let sessionID: String
112
+
113
+ var body: some View {
114
+ PiPCallView(sessionID: sessionID)
115
+ .ignoresSafeArea()
116
+ }
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Auto-PiP on backgrounding (manual path)
123
+
124
+ iOS 14+ supports auto-PiP from inline AVKit playback. For active calls:
125
+
126
+ ```swift
127
+ pipController?.canStartPictureInPictureAutomaticallyFromInline = true
128
+ ```
129
+
130
+ Combined with the `audio` background mode, this gives you the same behavior as CallKit auto-PiP: press Home → call enters PiP → audio + video continue.
131
+
132
+ ---
133
+
134
+ ## Delegate methods
135
+
136
+ ```swift
137
+ extension CustomOngoingCallViewController: AVPictureInPictureControllerDelegate {
138
+ func pictureInPictureControllerWillStartPictureInPicture(_ pip: AVPictureInPictureController) {
139
+ // Hide your in-page video (it duplicates with PiP)
140
+ sampleBufferDisplayLayer?.isHidden = true
141
+ }
142
+
143
+ func pictureInPictureControllerDidStartPictureInPicture(_ pip: AVPictureInPictureController) {
144
+ // PiP is active
145
+ }
146
+
147
+ func pictureInPictureController(_ pip: AVPictureInPictureController,
148
+ failedToStartPictureInPictureWithError error: Error) {
149
+ print("PiP failed:", error)
150
+ }
151
+
152
+ func pictureInPictureControllerDidStopPictureInPicture(_ pip: AVPictureInPictureController) {
153
+ sampleBufferDisplayLayer?.isHidden = false
154
+ }
155
+
156
+ func pictureInPictureController(_ pip: AVPictureInPictureController,
157
+ restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completion: @escaping (Bool) -> Void) {
158
+ // User tapped the PiP window — restore the full call screen
159
+ if let nav = self.navigationController {
160
+ nav.popToRootViewController(animated: true)
161
+ }
162
+ completion(true)
163
+ }
164
+ }
165
+ ```
166
+
167
+ `restoreUserInterfaceForPictureInPictureStopWithCompletionHandler` is critical — without it, tapping the PiP window restores nothing.
168
+
169
+ ---
170
+
171
+ ## Lock screen + PiP
172
+
173
+ When the device is locked during a call:
174
+
175
+ - **CallKit-managed call:** PiP appears on the lock screen as part of the CallKit incoming-call card. Audio continues; video shows in the lock-screen UI.
176
+ - **Manual `AVPictureInPictureController`:** PiP cannot show on the lock screen. The video pauses; audio continues if `audio` background mode is set.
177
+
178
+ Standalone-mode VoIP apps must use CallKit for the lock-screen video story to work.
179
+
180
+ ---
181
+
182
+ ## Hangup cleanup
183
+
184
+ When the call ends:
185
+
186
+ ```swift
187
+ func endCall() {
188
+ // Switch SDK back to default layout BEFORE ending the session, otherwise
189
+ // a re-init of the SDK can inherit compact-layout state on the next call.
190
+ CallSession.shared.disablePictureInPictureLayout()
191
+
192
+ CallSession.shared.leaveSession() // ends the WebRTC session
193
+
194
+ do {
195
+ try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
196
+ } catch {}
197
+ }
198
+ ```
199
+
200
+ If you ALSO drove a host-app `AVPictureInPictureController` (against an external video source), call `pipController?.stopPictureInPicture()` before tearing down. The CometChat SDK has no awareness of that controller.
201
+
202
+ ---
203
+
204
+ ## Anti-patterns
205
+
206
+ 1. **Using `CometChatCalls.attachPictureInPictureLayer(layer)` / `detachPictureInPictureLayer()`** — these symbols **do not exist** on `CometChatCallsSDK` v5.x. Confirmed against the SDK docs 2026-05-14. Use `CallSession.shared.enable/disablePictureInPictureLayout()` instead.
207
+ 2. **Manual `AVPictureInPictureController` for VoIP apps without CallKit.** Lock-screen ringing breaks; the SDK does not expose its video pipeline so the PiP window won't render the call. Use CallKit.
208
+ 3. **No `audio` background mode.** Audio cuts when the app backgrounds, regardless of PiP path.
209
+ 4. **Mixing SDK compact-layout with host-driven `AVPictureInPictureController`.** Two competing PiP surfaces — the SDK's compact layout fights the user's manual PiP, both look broken. Pick one.
210
+
211
+ ---
212
+
213
+ ## Verification checklist
214
+
215
+ - [ ] CallKit integrated (rule 1.7 in SKILL.md) — gives you PiP for free
216
+ - [ ] `audio` in `UIBackgroundModes` (Info.plist)
217
+ - [ ] Background Modes capability includes "Audio, AirPlay, and Picture in Picture"
218
+
219
+ **SDK compact-layout path (in-app PiP, no system-level PiP):**
220
+ - [ ] `CallSession.shared.enablePictureInPictureLayout()` called to enter compact mode
221
+ - [ ] `CallSession.shared.disablePictureInPictureLayout()` called BEFORE `leaveSession()` on hangup
222
+ - [ ] UI button to toggle between full/compact layouts
223
+ - [ ] NOT used together with a host-app `AVPictureInPictureController` (see anti-pattern #4)
224
+
225
+ **Real-device smoke (CallKit path):**
226
+ - [ ] Press Home during call → PiP appears (auto via CallKit)
227
+ - [ ] Audio continues through PiP transition
228
+ - [ ] Tap PiP window → app foregrounds, full call screen restored
229
+ - [ ] Lock device → PiP visible on lock screen (CallKit only)
230
+ - [ ] Hangup ends call cleanly; no stuck PiP window
231
+
232
+ **Real-device smoke (SDK compact-layout path):**
233
+ - [ ] Tap "minimize" → SDK switches to compact layout in-app
234
+ - [ ] Tap "expand" → SDK switches back to full layout
235
+ - [ ] Hangup from compact layout cleanly ends call
236
+
237
+ ---
238
+
239
+ ## Pointers
240
+
241
+ - `references/callkit-and-pushkit.md` — CallKit gives PiP for free
242
+ - `references/avaudiosession-routing.md` — audio routing during PiP transitions
243
+ - `references/swiftui-uikit-hosting.md` — SwiftUI hosting of the UIKit PiP view controller
244
+ - `cometchat-native-calls/references/picture-in-picture.md` — sister reference (RN bridges to the same iOS APIs)
245
+ - `cometchat-react-calls/references/picture-in-picture.md` — Web PiP (different APIs but same UX shape)
246
+ - `cometchat-ios-calls` SKILL.md — base hard rules
@@ -0,0 +1,239 @@
1
+ # Raise hand on iOS
2
+
3
+ Native CometChatCallsSDK exposes the same conceptual API as the JS SDK — `raiseHand()` / `lowerHand()` plus delegate callbacks. The wow piece is wiring it into UIKit / SwiftUI cleanly + the system-level UX (CallKit doesn't show raised-hand state on the lock screen, so the in-app surface is the canonical place).
4
+
5
+ **Canonical docs:** https://www.cometchat.com/docs/calls/ios/raise-hand
6
+ **Read first:** `cometchat-react-calls/references/raise-hand.md` — UX shape + anti-patterns are identical; this reference is the iOS-specific Swift wiring.
7
+
8
+ ---
9
+
10
+ ## SDK API
11
+
12
+ ```swift
13
+ import CometChatCallsSDK
14
+
15
+ // Local user
16
+ CometChatCalls.raiseHand()
17
+ CometChatCalls.lowerHand()
18
+
19
+ // Listener — set via the call event listener attached at session start
20
+ class CallListener: NSObject, CometChatCallsEventsListener {
21
+ func onParticipantHandRaised(_ participant: Participant) {
22
+ // participant.uid, participant.name
23
+ }
24
+ func onParticipantHandLowered(_ participant: Participant) {
25
+ // ...
26
+ }
27
+ }
28
+
29
+ // Settings flag
30
+ let settings = CallSettingsBuilder()
31
+ .setSessionType(.video)
32
+ .hideRaiseHandButton(true)
33
+ .build()
34
+ ```
35
+
36
+ ---
37
+
38
+ ## SwiftUI integration — observable state holder
39
+
40
+ ```swift
41
+ import SwiftUI
42
+ import Combine
43
+ import CometChatCallsSDK
44
+
45
+ struct RaisedParticipant: Identifiable {
46
+ let id: String // uid
47
+ let name: String
48
+ let raisedAt: Date
49
+ }
50
+
51
+ final class RaiseHandState: ObservableObject {
52
+ @Published var localRaised: Bool = false
53
+ @Published var raised: [RaisedParticipant] = []
54
+
55
+ func toggle() {
56
+ if localRaised {
57
+ CometChatCalls.lowerHand()
58
+ } else {
59
+ CometChatCalls.raiseHand()
60
+ }
61
+ localRaised.toggle()
62
+ }
63
+
64
+ func handle(participantRaised p: Participant) {
65
+ DispatchQueue.main.async {
66
+ let entry = RaisedParticipant(id: p.uid, name: p.name, raisedAt: Date())
67
+ self.raised.removeAll { $0.id == p.uid }
68
+ self.raised.append(entry)
69
+ self.raised.sort { $0.raisedAt < $1.raisedAt }
70
+ }
71
+ }
72
+
73
+ func handle(participantLowered p: Participant) {
74
+ DispatchQueue.main.async {
75
+ self.raised.removeAll { $0.id == p.uid }
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ `DispatchQueue.main.async` wraps SDK callbacks — same rule as elsewhere in iOS calls integrations (cf. `references/group-calls.md`). Without it, `@Published` updates from a background queue cause UI thread warnings + skipped re-renders.
82
+
83
+ ---
84
+
85
+ ## Toggle button (SwiftUI)
86
+
87
+ ```swift
88
+ struct RaiseHandButton: View {
89
+ @ObservedObject var state: RaiseHandState
90
+
91
+ var body: some View {
92
+ Button(action: state.toggle) {
93
+ Label(state.localRaised ? "Lower" : "Raise hand",
94
+ systemImage: state.localRaised ? "hand.raised.fill" : "hand.raised")
95
+ }
96
+ .buttonStyle(.bordered)
97
+ .tint(state.localRaised ? .yellow : .white)
98
+ .accessibilityLabel(state.localRaised ? "Lower hand" : "Raise hand")
99
+ .accessibilityAddTraits(state.localRaised ? .isSelected : [])
100
+ .onChange(of: state.localRaised) { newValue in
101
+ UIAccessibility.post(notification: .announcement, argument:
102
+ newValue ? "Hand raised" : "Hand lowered")
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ `UIAccessibility.post(.announcement, ...)` is the iOS equivalent of web's `aria-live` and RN's `AccessibilityInfo.announceForAccessibility`. VoiceOver picks it up.
109
+
110
+ ---
111
+
112
+ ## Raised-hands sheet (SwiftUI)
113
+
114
+ ```swift
115
+ struct RaisedHandsSheet: View {
116
+ @ObservedObject var state: RaiseHandState
117
+
118
+ var body: some View {
119
+ VStack(alignment: .leading, spacing: 12) {
120
+ Text("Raised hands (\(state.raised.count))")
121
+ .font(.headline)
122
+ if state.raised.isEmpty {
123
+ Text("No hands raised").foregroundColor(.secondary)
124
+ } else {
125
+ ForEach(state.raised) { p in
126
+ HStack {
127
+ Text("✋").font(.title2)
128
+ Text(p.name).font(.body)
129
+ Spacer()
130
+ Text(secondsAgo(p.raisedAt))
131
+ .font(.caption)
132
+ .foregroundColor(.secondary)
133
+ }
134
+ .padding(.vertical, 4)
135
+ }
136
+ }
137
+ }
138
+ .padding()
139
+ .presentationDetents([.fraction(0.3), .medium])
140
+ }
141
+
142
+ func secondsAgo(_ t: Date) -> String {
143
+ "\(Int(Date().timeIntervalSince(t)))s ago"
144
+ }
145
+ }
146
+ ```
147
+
148
+ `.presentationDetents([.fraction(0.3), .medium])` is iOS 16+ — gives the user two snap heights, matching the BottomSheet pattern from RN.
149
+
150
+ ---
151
+
152
+ ## UIKit pattern
153
+
154
+ For UIKit projects (the kit's default surface):
155
+
156
+ ```swift
157
+ class CallViewController: UIViewController {
158
+ private let state = RaiseHandState()
159
+
160
+ override func viewDidLoad() {
161
+ super.viewDidLoad()
162
+ // ... attach state to call event listener at session start
163
+ }
164
+
165
+ @objc private func raiseHandTapped() {
166
+ state.toggle()
167
+ // Update the UIBarButtonItem appearance
168
+ raiseHandButton.image = UIImage(systemName: state.localRaised ? "hand.raised.fill" : "hand.raised")
169
+ raiseHandButton.tintColor = state.localRaised ? .systemYellow : .label
170
+ }
171
+
172
+ func presentRaisedHandsSheet() {
173
+ let host = UIHostingController(rootView: RaisedHandsSheet(state: state))
174
+ if #available(iOS 15.0, *) {
175
+ host.sheetPresentationController?.detents = [.medium(), .large()]
176
+ }
177
+ present(host, animated: true)
178
+ }
179
+ }
180
+ ```
181
+
182
+ `UIHostingController(rootView:)` lets you embed a SwiftUI sheet in a UIKit nav stack. `sheetPresentationController.detents` is the iOS 15+ pull-up sheet API.
183
+
184
+ ---
185
+
186
+ ## Toast announcement for the host
187
+
188
+ iOS has no native toast — use `UNUserNotificationCenter` for an in-call banner-style notification, OR a custom view:
189
+
190
+ ```swift
191
+ extension RaiseHandState {
192
+ func showRaisedNotification(for p: Participant) {
193
+ let banner = UIView()
194
+ banner.backgroundColor = .systemYellow.withAlphaComponent(0.95)
195
+ let label = UILabel()
196
+ label.text = "✋ \(p.name) raised their hand"
197
+ label.textColor = .black
198
+ label.font = .systemFont(ofSize: 14, weight: .medium)
199
+ // ...add to view, animate down from top, dismiss after 4s
200
+ }
201
+ }
202
+ ```
203
+
204
+ Or use a third-party lib like `NotificationBannerSwift`. Custom is fine; just don't use `UNUserNotificationCenter` (which is system-level and feels out of place for in-call signals).
205
+
206
+ ---
207
+
208
+ ## Anti-patterns
209
+
210
+ Web sister reference rules apply, plus iOS-specific:
211
+
212
+ 1. **`@Published` updates from non-main queue.** SwiftUI warns "publishing changes from background threads is not allowed." Always wrap SDK callbacks in `DispatchQueue.main.async`.
213
+ 2. **Forgetting `accessibilityAddTraits(.isSelected)` on the toggle button.** VoiceOver doesn't announce "selected" state without it.
214
+ 3. **Using `UNUserNotificationCenter`** for in-call raise-hand alerts. System-level; feels wrong. Use a custom banner.
215
+ 4. **`removeAll { $0.id == p.uid }` then `append` without sort.** When a participant raises again after lowering, position in queue should reset to "now"; current code already does the right thing, but easy to break by reordering operations.
216
+
217
+ ---
218
+
219
+ ## Verification checklist
220
+
221
+ - [ ] `RaiseHandState` is an `ObservableObject`
222
+ - [ ] All SDK callbacks wrap in `DispatchQueue.main.async`
223
+ - [ ] Toggle button has `accessibilityLabel` + `accessibilityAddTraits(.isSelected)` when raised
224
+ - [ ] `UIAccessibility.post(.announcement, ...)` on toggle
225
+ - [ ] Raised-hands list sorted by `raisedAt` ascending
226
+ - [ ] `hideRaiseHandButton: true` in CallSettings if custom UI
227
+ - [ ] Real-device smoke: 3 iPhones in same call, host sees both raised
228
+ - [ ] VoiceOver smoke: enable VoiceOver, raise hand, hear "Hand raised" announcement
229
+
230
+ ---
231
+
232
+ ## Pointers
233
+
234
+ - `cometchat-react-calls/references/raise-hand.md` — sister reference (UX shape)
235
+ - `cometchat-ios-calls` SKILL.md — the seven hard rules
236
+ - `references/group-calls.md` — group call iOS architecture
237
+ - `references/swiftui-uikit-hosting.md` — embedding SwiftUI sheets in UIKit
238
+ - `cometchat-a11y` — UIAccessibility patterns
239
+ - Canonical docs: https://www.cometchat.com/docs/calls/ios/raise-hand