@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.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 (264) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +266 -267
  5. package/package.json +2 -2
  6. package/pipeline/scripts/_notices.mjs +1 -1
  7. package/pipeline/skills/.skill-manifest.json +68 -68
  8. package/pipeline/skills/shared/README.md +70 -70
  9. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  10. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  11. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  12. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  13. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  14. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  15. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  16. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  17. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  18. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  19. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  20. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  21. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  22. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  23. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  24. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  25. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  26. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  27. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  28. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  29. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  30. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  31. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  32. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  34. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  35. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  36. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  37. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  38. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  39. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  40. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  41. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  42. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  43. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  44. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  45. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  46. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  47. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  48. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  49. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  50. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  51. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  52. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  53. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  54. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  55. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  56. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  57. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  58. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  59. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  60. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  61. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  62. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  63. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  64. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  65. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  66. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  67. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  68. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  69. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  70. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  71. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  72. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  73. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  74. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  75. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  76. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  77. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  78. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  79. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  80. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  81. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  82. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  83. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  84. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  85. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  86. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  87. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  88. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  89. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  90. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  91. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  92. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  93. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  94. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  95. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  96. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  97. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  98. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  99. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  100. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  101. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  102. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  103. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  104. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  105. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  106. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  107. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  108. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  109. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  111. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  112. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  113. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  114. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  115. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  116. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  117. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  118. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  119. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  120. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  121. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  122. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  123. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  124. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  125. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  126. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  127. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  128. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  129. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  130. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  131. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  132. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  133. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  134. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  135. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  136. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  137. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  138. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  139. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  140. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  141. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  142. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  143. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  144. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  145. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  146. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  147. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  148. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  149. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  150. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  151. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  152. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  153. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  154. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  155. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  156. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  157. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  158. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  159. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  160. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  161. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  162. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  163. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  164. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  165. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  166. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  167. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  168. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  169. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  170. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  171. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  172. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  173. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  174. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  175. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  176. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  177. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  178. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  179. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  180. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  181. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  182. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  183. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  184. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  185. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  186. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  187. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  188. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  189. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  190. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  191. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  192. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  193. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  194. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  195. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  196. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  197. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  198. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  199. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  200. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  201. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  202. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  203. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  204. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  205. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  206. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  207. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  208. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  209. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  210. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  211. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  212. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  213. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  214. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  215. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  216. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  217. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  218. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  219. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  220. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  221. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  222. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  223. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  224. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  225. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  226. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  227. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  228. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  229. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  230. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  231. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  232. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  233. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  234. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  235. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  236. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  237. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  238. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  239. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  240. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  241. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  242. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  243. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  244. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  245. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  246. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  247. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  248. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  249. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  250. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  251. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  252. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  253. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  254. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  255. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  256. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  257. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  258. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  259. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  260. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  261. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  262. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  263. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  264. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,9 +1,9 @@
1
- # Network.framework
1
+ # Network Framework
2
2
 
3
- Low-level networking with the Network framework. Use when you need TCP/UDP
4
- connections, WebSockets, Bonjour service discovery, local servers, or network
5
- path monitoring beyond what URLSession provides. All examples target
6
- Swift 6.3 / iOS 26+.
3
+ Reach for Network.framework when URLSession is the wrong layer: raw TCP or
4
+ UDP, a WebSocket at the protocol level, Bonjour discovery, a local server, or
5
+ detailed path monitoring. Ordinary HTTP APIs stay on URLSession. Examples
6
+ assume Swift 6.3 and iOS 26.
7
7
 
8
8
  ## Contents
9
9
 
@@ -14,575 +14,350 @@ Swift 6.3 / iOS 26+.
14
14
  - [NWParameters Configuration](#nwparameters-configuration)
15
15
  - [TLS Configuration](#tls-configuration)
16
16
  - [WebSocket Support](#websocket-support)
17
- - [NetworkConnection (iOS 26+)](#networkconnection-ios-26)
17
+ - [The iOS 26 NetworkConnection API](#the-ios-26-networkconnection-api)
18
18
 
19
19
  ## NWConnection
20
20
 
21
- A bidirectional data connection between a local and remote endpoint. Supports
22
- TCP, UDP, TLS, DTLS, QUIC, and WebSocket protocols.
23
-
24
- **Documentation:**
25
- [sosumi.ai/documentation/network/nwconnection](https://sosumi.ai/documentation/network/nwconnection)
26
-
27
- ### TCP Connection
21
+ `NWConnection` is one bidirectional connection. It speaks TCP, UDP, TLS,
22
+ DTLS, QUIC and WebSocket depending on its parameters.
23
+ API reference: [NWConnection docs](https://developer.apple.com/documentation/network/nwconnection).
28
24
 
29
25
  ```swift
26
+ import Foundation
30
27
  import Network
28
+ import OSLog
31
29
 
32
- let connection = NWConnection(
33
- host: "api.example.com",
34
- port: 443,
35
- using: .tls
36
- )
30
+ extension Logger { static let net = Logger(subsystem: "app.networking", category: "net") }
37
31
 
38
- connection.stateUpdateHandler = { state in
32
+ let link = NWConnection(host: "telemetry.example.net", port: 443, using: .tls)
33
+ link.stateUpdateHandler = { state in
39
34
  switch state {
40
- case .ready:
41
- print("Connected")
42
- case .waiting(let error):
43
- print("Waiting: \(error.localizedDescription)")
44
- case .failed(let error):
45
- print("Failed: \(error.localizedDescription)")
46
- case .cancelled:
47
- print("Cancelled")
48
- default:
49
- break
35
+ case .ready: Logger.net.info("connected")
36
+ case .waiting(let error): Logger.net.notice("waiting for a path: \(error.localizedDescription)")
37
+ case .failed(let error): Logger.net.error("failed: \(error.localizedDescription)"); link.cancel()
38
+ case .cancelled: Logger.net.info("closed")
39
+ default: break
50
40
  }
51
41
  }
52
-
53
- connection.start(queue: .main)
54
- ```
55
-
56
- ### Sending Data
57
-
58
- ```swift
59
- func send(_ data: Data, on connection: NWConnection) {
60
- connection.send(
61
- content: data,
62
- contentContext: .defaultMessage,
63
- isComplete: true,
64
- completion: .contentProcessed { error in
65
- if let error {
66
- print("Send error: \(error)")
67
- }
68
- }
69
- )
70
- }
71
- ```
72
-
73
- ### Receiving Data
74
-
75
- ```swift
76
- func receive(on connection: NWConnection) {
77
- connection.receive(
78
- minimumIncompleteLength: 1,
79
- maximumLength: 65536
80
- ) { content, contentContext, isComplete, error in
81
- if let data = content {
82
- handleData(data)
83
- }
84
- if isComplete {
85
- connection.cancel()
86
- } else if let error {
87
- print("Receive error: \(error)")
88
- } else {
89
- // Continue receiving
90
- receive(on: connection)
42
+ link.start(queue: .main)
43
+
44
+ link.send(content: Data("HELLO\n".utf8), contentContext: .defaultMessage, isComplete: true,
45
+ completion: .contentProcessed { error in
46
+ if let error { Logger.net.error("send failed: \(error.localizedDescription)") }
47
+ })
48
+
49
+ func readLoop(on connection: NWConnection) {
50
+ connection.receive(minimumIncompleteLength: 1, maximumLength: 65_536) { data, _, isComplete, error in
51
+ if let data, !data.isEmpty { consume(data) }
52
+ if let error {
53
+ Logger.net.error("receive failed: \(error.localizedDescription)")
54
+ return
91
55
  }
56
+ if isComplete { connection.cancel(); return }
57
+ readLoop(on: connection)
92
58
  }
93
59
  }
94
60
  ```
95
61
 
96
- ### UDP Connection
62
+ UDP uses the same type:
97
63
 
98
64
  ```swift
99
- let udpConnection = NWConnection(
100
- host: "239.0.0.1",
101
- port: 5000,
102
- using: .udp
103
- )
104
-
105
- udpConnection.stateUpdateHandler = { state in
65
+ let beacon = NWConnection(host: "239.255.10.20", port: 6200, using: .udp)
66
+ beacon.stateUpdateHandler = { state in
106
67
  if case .ready = state {
107
- let message = "Hello".data(using: .utf8)!
108
- udpConnection.send(
109
- content: message,
110
- completion: .contentProcessed { _ in }
111
- )
68
+ beacon.send(content: Data("ping".utf8), completion: .contentProcessed { _ in })
112
69
  }
113
70
  }
114
-
115
- udpConnection.start(queue: .main)
71
+ beacon.start(queue: .global())
116
72
  ```
117
73
 
118
- ### Connection Lifecycle
119
-
120
- States flow in order: `setup` → `preparing` → `ready` → `cancelled`/`failed`.
121
- A connection may enter `waiting(NWError)` if the network path is unavailable
122
- and retry when connectivity returns.
123
-
124
- Always cancel connections when done:
125
-
126
- ```swift
127
- connection.cancel() // Releases resources, transitions to .cancelled
128
- ```
74
+ - States run `setup`, `preparing`, `ready`, and end in `cancelled` or
75
+ `failed`.
76
+ - `waiting(NWError)` means no usable path right now. The connection tries
77
+ again by itself when the network comes back.
78
+ - Call `cancel()` when you are done. It frees the resources and moves the
79
+ connection to `cancelled`.
129
80
 
130
81
  ## NWListener
131
82
 
132
- An object that listens for incoming network connections. Use to create local
133
- TCP/UDP servers.
134
-
135
- **Documentation:**
136
- [sosumi.ai/documentation/network/nwlistener](https://sosumi.ai/documentation/network/nwlistener)
137
-
138
- ### TCP Server
83
+ `NWListener` accepts incoming connections, which is how you run a small TCP
84
+ or UDP server on the device.
85
+ API reference: [NWListener docs](https://developer.apple.com/documentation/network/nwlistener).
139
86
 
140
87
  ```swift
141
- import Network
142
-
143
- func startServer(port: UInt16) throws -> NWListener {
144
- let listener = try NWListener(using: .tcp, on: NWEndpoint.Port(rawValue: port)!)
145
-
146
- listener.stateUpdateHandler = { state in
88
+ func startServer() throws -> NWListener {
89
+ let port: NWEndpoint.Port = 8080
90
+ let server = try NWListener(using: .tcp, on: port)
91
+ server.stateUpdateHandler = { state in
147
92
  switch state {
148
- case .ready:
149
- print("Listening on port \(listener.port?.rawValue ?? 0)")
150
- case .failed(let error):
151
- print("Listener failed: \(error)")
152
- listener.cancel()
153
- default:
154
- break
93
+ case .ready: Logger.net.info("listening on \(server.port?.rawValue ?? 0)")
94
+ case .failed(let error): Logger.net.error("\(error.localizedDescription)"); server.cancel()
95
+ default: break
155
96
  }
156
97
  }
157
-
158
- listener.newConnectionHandler = { connection in
159
- print("New connection from \(connection.endpoint)")
160
- connection.stateUpdateHandler = { state in
161
- if case .ready = state {
162
- receive(on: connection)
163
- }
98
+ server.newConnectionHandler = { incoming in
99
+ incoming.stateUpdateHandler = { state in
100
+ if case .ready = state { readLoop(on: incoming) }
164
101
  }
165
- connection.start(queue: .main)
102
+ incoming.start(queue: .global())
166
103
  }
167
-
168
- listener.start(queue: .main)
169
- return listener
170
- }
171
- ```
172
-
173
- ### Advertising via Bonjour
174
-
175
- ```swift
176
- let listener = try NWListener(using: .tcp)
177
- listener.service = NWListener.Service(
178
- name: "MyApp",
179
- type: "_myapp._tcp"
180
- )
181
- listener.serviceRegistrationUpdateHandler = { change in
182
- switch change {
183
- case .add(let endpoint):
184
- print("Service registered: \(endpoint)")
185
- default:
186
- break
104
+ server.service = NWListener.Service(name: "Workbench", type: "_workbench._tcp")
105
+ server.serviceRegistrationUpdateHandler = { change in
106
+ if case .add(let endpoint) = change { Logger.net.info("advertised \(String(describing: endpoint))") }
187
107
  }
108
+ server.start(queue: .global())
109
+ return server
188
110
  }
189
- listener.start(queue: .main)
190
111
  ```
191
112
 
192
- ## NWBrowser
193
-
194
- Discovers Bonjour/mDNS services on the local network.
113
+ `NWEndpoint.Port` is expressible by an integer literal, so a fixed port
114
+ needs no optional. For a port from user input, use
115
+ `NWEndpoint.Port(rawValue:)` and handle `nil`. Setting `service` advertises
116
+ the listener over Bonjour.
195
117
 
196
- **Documentation:**
197
- [sosumi.ai/documentation/network/nwbrowser](https://sosumi.ai/documentation/network/nwbrowser)
118
+ ## NWBrowser
198
119
 
199
- ### Service Discovery
120
+ `NWBrowser` discovers peers that advertise over Bonjour (multicast DNS) on the LAN.
121
+ API reference: [NWBrowser docs](https://developer.apple.com/documentation/network/nwbrowser).
200
122
 
201
123
  ```swift
202
- import Network
203
-
204
- let browser = NWBrowser(
205
- for: .bonjour(type: "_myapp._tcp", domain: nil),
206
- using: .tcp
207
- )
208
-
209
- browser.stateUpdateHandler = { state in
210
- if case .failed(let error) = state {
211
- print("Browser failed: \(error)")
212
- }
213
- }
214
-
215
- browser.browseResultsChangedHandler = { results, changes in
216
- for result in results {
217
- switch result.endpoint {
218
- case .service(let name, let type, let domain, _):
219
- print("Found: \(name).\(type)\(domain)")
220
- default:
221
- break
222
- }
223
- }
224
-
124
+ let scanner = NWBrowser(for: .bonjour(type: "_workbench._tcp", domain: nil), using: .tcp)
125
+ scanner.browseResultsChangedHandler = { results, changes in
225
126
  for change in changes {
226
127
  switch change {
227
- case .added(let result):
228
- print("Added: \(result.endpoint)")
229
- case .removed(let result):
230
- print("Removed: \(result.endpoint)")
231
- default:
232
- break
128
+ case .added(let found):
129
+ if case .service(let name, _, _, _) = found.endpoint { Logger.net.info("found \(name)") }
130
+ case .removed(let gone):
131
+ Logger.net.info("lost \(String(describing: gone.endpoint))")
132
+ default: break
233
133
  }
234
134
  }
235
135
  }
136
+ scanner.start(queue: .main)
236
137
 
237
- browser.start(queue: .main)
138
+ func connect(to found: NWBrowser.Result) -> NWConnection {
139
+ NWConnection(to: found.endpoint, using: .tcp)
140
+ }
238
141
  ```
239
142
 
240
- ### Connecting to a Discovered Service
241
-
242
- ```swift
243
- // result is an NWBrowser.Result from browseResultsChangedHandler
244
- let connection = NWConnection(to: result.endpoint, using: .tcp)
245
- connection.start(queue: .main)
246
- ```
143
+ The handler receives the full current `results` set and the `changes`
144
+ (`.added`, `.removed`) since the last call.
247
145
 
248
146
  ## NWPathMonitor
249
147
 
250
- Monitors network path changes. Replaces the deprecated `SCNetworkReachability`
251
- API. Use to detect connectivity changes, expensive paths (cellular), and
252
- constrained paths (Low Data Mode).
253
-
254
- **Documentation:**
255
- [sosumi.ai/documentation/network/nwpathmonitor](https://sosumi.ai/documentation/network/nwpathmonitor)
256
-
257
- ### Basic Reachability with AsyncSequence
148
+ `NWPathMonitor` replaces the deprecated `SCNetworkReachability`. It reports
149
+ whether a path exists and whether it is expensive or constrained.
150
+ API reference: [NWPathMonitor docs](https://developer.apple.com/documentation/network/nwpathmonitor).
258
151
 
259
152
  ```swift
260
- import Network
261
-
262
153
  @MainActor @Observable
263
- class ConnectivityModel {
264
- var isConnected = true
265
- var isExpensive = false
266
- var isConstrained = false
267
-
268
- func startMonitoring() async {
269
- let monitor = NWPathMonitor()
270
-
271
- for await path in monitor {
272
- isConnected = path.status == .satisfied
273
- isExpensive = path.isExpensive // Cellular
274
- isConstrained = path.isConstrained // Low Data Mode
154
+ final class LinkQuality {
155
+ private(set) var online = true
156
+ private(set) var metered = false
157
+ private(set) var lowData = false
158
+
159
+ func watch() async {
160
+ for await path in NWPathMonitor() {
161
+ online = path.status == .satisfied
162
+ metered = path.isExpensive
163
+ lowData = path.isConstrained
275
164
  }
276
165
  }
166
+
167
+ var imagePolicy: ImagePolicy {
168
+ if lowData { return ImagePolicy(quality: .low, prefetch: false, preloadVideo: false) }
169
+ if metered { return ImagePolicy(quality: .standard, prefetch: true, preloadVideo: false) }
170
+ return ImagePolicy(quality: .high, prefetch: true, preloadVideo: true)
171
+ }
277
172
  }
278
173
  ```
279
174
 
280
- ### Monitor Specific Interface
175
+ Start `watch()` from a `.task` so the loop ends with the view. To watch one
176
+ interface type, or on an SDK where the monitor is not yet an async sequence,
177
+ use the handler API:
281
178
 
282
179
  ```swift
283
- // Monitor only Wi-Fi
284
- let wifiMonitor = NWPathMonitor(requiredInterfaceType: .wifi)
285
- wifiMonitor.pathUpdateHandler = { path in
286
- print("Wi-Fi: \(path.status)")
180
+ let wifiOnly = NWPathMonitor(requiredInterfaceType: .wifi)
181
+ wifiOnly.pathUpdateHandler = { path in
182
+ Logger.net.info("wifi path: \(String(describing: path.status))")
287
183
  }
288
- wifiMonitor.start(queue: .global())
184
+ wifiOnly.start(queue: .global())
289
185
  ```
290
186
 
291
- ### Key NWPath Properties
292
-
293
- | Property | Description |
187
+ | `NWPath` member | Meaning |
294
188
  |---|---|
295
- | `status` | `.satisfied`, `.unsatisfied`, or `.requiresConnection` |
296
- | `isExpensive` | `true` on cellular or personal hotspot |
297
- | `isConstrained` | `true` when Low Data Mode is enabled |
298
- | `availableInterfaces` | Array of available `NWInterface` objects |
299
- | `supportsDNS` | Whether DNS resolution is available |
300
- | `supportsIPv4` / `supportsIPv6` | Protocol family support |
189
+ | `status` | `.satisfied`, `.unsatisfied` or `.requiresConnection` |
190
+ | `isExpensive` | Cellular or a personal hotspot |
191
+ | `isConstrained` | Low Data Mode is on |
192
+ | `availableInterfaces` | The `NWInterface` values the path can use |
193
+ | `supportsDNS` | DNS resolution is available |
194
+ | `supportsIPv4`, `supportsIPv6` | Address families the path supports |
301
195
 
302
- ### Adapting Behavior
303
-
304
- ```swift
305
- let monitor = NWPathMonitor()
306
-
307
- for await path in monitor {
308
- if path.isConstrained {
309
- // Low Data Mode: reduce image quality, skip prefetch
310
- imageQuality = .low
311
- } else if path.isExpensive {
312
- // Cellular: use standard quality, skip video preload
313
- imageQuality = .standard
314
- } else {
315
- // Wi-Fi: full quality, prefetch aggressively
316
- imageQuality = .high
317
- }
318
- }
319
- ```
196
+ Adapt to the path: on a constrained path fetch low-quality images and skip
197
+ prefetching; on an expensive path keep standard quality and skip video
198
+ preloading; otherwise use high quality and prefetch freely.
320
199
 
321
200
  ## NWParameters Configuration
322
201
 
323
- `NWParameters` defines the protocols and options for connections and listeners.
202
+ `NWParameters` describes the protocol stack and path rules for a connection
203
+ or listener. Build options objects directly and pass them in, which avoids
204
+ casting them back out of the stack:
324
205
 
325
206
  ```swift
326
- import Network
327
-
328
- // TCP with custom options
329
- let tcpParams = NWParameters.tcp
330
- tcpParams.requiredInterfaceType = .wifi
331
- tcpParams.prohibitExpensivePaths = true
332
- tcpParams.prohibitConstrainedPaths = true
333
-
334
- let tcpOptions = tcpParams.defaultProtocolStack
335
- .transportProtocol as! NWProtocolTCP.Options
336
- tcpOptions.connectionTimeout = 10
337
- tcpOptions.enableKeepalive = true
338
- tcpOptions.keepaliveInterval = 30
339
-
340
- let connection = NWConnection(
341
- host: "api.example.com",
342
- port: 8080,
343
- using: tcpParams
344
- )
207
+ let tcp = NWProtocolTCP.Options()
208
+ tcp.connectionTimeout = 10
209
+ tcp.enableKeepalive = true
210
+ tcp.keepaliveInterval = 30
211
+
212
+ let lanOnly = NWParameters(tls: nil, tcp: tcp)
213
+ lanOnly.requiredInterfaceType = .wifi
214
+ lanOnly.prohibitExpensivePaths = true
215
+ lanOnly.prohibitConstrainedPaths = true
216
+
217
+ let udp = NWProtocolUDP.Options()
218
+ udp.preferNoChecksum = true
219
+ let datagrams = NWParameters(dtls: nil, udp: udp)
345
220
  ```
346
221
 
347
- ### UDP Parameters
348
-
349
- ```swift
350
- let udpParams = NWParameters.udp
351
- let udpOptions = udpParams.defaultProtocolStack
352
- .transportProtocol as! NWProtocolUDP.Options
353
- udpOptions.preferNoChecksum = true
354
-
355
- let connection = NWConnection(
356
- host: "239.0.0.1",
357
- port: 5000,
358
- using: udpParams
359
- )
360
- ```
222
+ If you must adjust a stack you did not build, use a conditional cast:
223
+ `if let tcp = params.defaultProtocolStack.transportProtocol as? NWProtocolTCP.Options`.
361
224
 
362
225
  ## TLS Configuration
363
226
 
364
- Configure TLS for secure connections using `NWProtocolTLS.Options`.
365
- Network.framework operates below the URL Loading System, so ATS does not
366
- automatically enforce URLSession-style policy here. When you use
367
- Network.framework for a secure protocol, configure TLS parameters and trust
368
- handling for that protocol stack; keep deep certificate-trust and SPKI pinning
369
- implementation in `swift-security`.
227
+ TLS is configured with `NWProtocolTLS.Options`. ATS belongs to the URL
228
+ Loading System and does not police this layer, so the TLS version, cipher
229
+ choices and trust evaluation are yours to set. Deep trust work and SPKI
230
+ pinning belong in `swift-security`.
370
231
 
371
232
  ```swift
372
- import Network
373
-
374
- let tlsParams = NWParameters(tls: NWProtocolTLS.Options())
375
-
376
- // Access TLS options for customization
377
- let tlsOptions = tlsParams.defaultProtocolStack
378
- .applicationProtocols.first as! NWProtocolTLS.Options
379
-
380
- sec_protocol_options_set_min_tls_protocol_version(
381
- tlsOptions.securityProtocolOptions,
382
- .TLSv13
383
- )
384
-
385
- let connection = NWConnection(
386
- host: "secure.example.com",
387
- port: 443,
388
- using: tlsParams
389
- )
390
- ```
391
-
392
- ### Inspecting TLS Metadata
393
-
394
- ```swift
395
- connection.stateUpdateHandler = { state in
396
- if case .ready = state {
397
- if let metadata = connection.metadata(
398
- definition: NWProtocolTLS.definition
399
- ) as? NWProtocolTLS.Metadata {
400
- let secMetadata = metadata.securityProtocolMetadata
401
- let negotiatedProtocol = sec_protocol_metadata_get_negotiated_tls_protocol_version(secMetadata)
402
- print("TLS version: \(negotiatedProtocol)")
403
- }
404
- }
233
+ let tls = NWProtocolTLS.Options()
234
+ sec_protocol_options_set_min_tls_protocol_version(tls.securityProtocolOptions, .TLSv13)
235
+ let secure = NWParameters(tls: tls)
236
+
237
+ let session = NWConnection(host: "vault.example.net", port: 8443, using: secure)
238
+ session.stateUpdateHandler = { state in
239
+ guard case .ready = state else { return }
240
+ let raw = session.metadata(definition: NWProtocolTLS.definition)
241
+ guard let meta = raw as? NWProtocolTLS.Metadata else { return }
242
+ let version = sec_protocol_metadata_get_negotiated_tls_protocol_version(meta.securityProtocolMetadata)
243
+ Logger.net.info("negotiated TLS \(version.rawValue)")
405
244
  }
245
+ session.start(queue: .global())
406
246
  ```
407
247
 
408
248
  ## WebSocket Support
409
249
 
410
- Network.framework supports WebSocket via `NWProtocolWebSocket`.
411
-
412
- ### WebSocket Client
250
+ Network.framework exposes WebSocket through `NWProtocolWebSocket`, layered on
251
+ top of TLS and TCP.
413
252
 
414
253
  ```swift
415
- import Network
416
-
417
- func createWebSocketConnection(url: String) -> NWConnection {
418
- let wsOptions = NWProtocolWebSocket.Options()
419
- wsOptions.autoReplyPing = true
420
-
421
- let params = NWParameters.tls
422
- params.defaultProtocolStack.applicationProtocols.insert(
423
- wsOptions, at: 0
424
- )
425
-
426
- let connection = NWConnection(
427
- host: NWEndpoint.Host(url),
428
- port: 443,
429
- using: params
430
- )
431
-
432
- return connection
254
+ let ws = NWProtocolWebSocket.Options()
255
+ ws.autoReplyPing = true
256
+ let params = NWParameters.tls
257
+ params.defaultProtocolStack.applicationProtocols.insert(ws, at: 0)
258
+ let socket = NWConnection(host: "stream.example.net", port: 443, using: params)
259
+
260
+ func sendText(_ message: String, over connection: NWConnection) {
261
+ let meta = NWProtocolWebSocket.Metadata(opcode: .text)
262
+ let context = NWConnection.ContentContext(identifier: "text", metadata: [meta])
263
+ connection.send(content: Data(message.utf8), contentContext: context, isComplete: true,
264
+ completion: .contentProcessed { _ in })
433
265
  }
434
- ```
435
266
 
436
- ### Sending WebSocket Messages
437
-
438
- ```swift
439
- func sendWebSocketMessage(_ text: String, on connection: NWConnection) {
440
- let metadata = NWProtocolWebSocket.Metadata(opcode: .text)
441
- let context = NWConnection.ContentContext(
442
- identifier: "textMessage",
443
- metadata: [metadata]
444
- )
445
-
446
- let data = text.data(using: .utf8)
447
- connection.send(
448
- content: data,
449
- contentContext: context,
450
- isComplete: true,
451
- completion: .contentProcessed { error in
452
- if let error {
453
- print("WebSocket send error: \(error)")
454
- }
455
- }
456
- )
457
- }
458
- ```
459
-
460
- ### Receiving WebSocket Messages
461
-
462
- ```swift
463
- func receiveWebSocketMessage(on connection: NWConnection) {
464
- connection.receiveMessage { data, context, isComplete, error in
465
- if let data,
466
- let metadata = context?.protocolMetadata(
467
- definition: NWProtocolWebSocket.definition
468
- ) as? NWProtocolWebSocket.Metadata {
469
- switch metadata.opcode {
470
- case .text:
471
- let text = String(data: data, encoding: .utf8) ?? ""
472
- print("Received text: \(text)")
473
- case .binary:
474
- print("Received binary: \(data.count) bytes")
475
- case .close:
476
- print("Connection closed")
477
- return
478
- default:
479
- break
480
- }
267
+ func listen(on connection: NWConnection) {
268
+ connection.receiveMessage { data, context, _, error in
269
+ guard error == nil else { return }
270
+ let meta = context?.protocolMetadata(definition: NWProtocolWebSocket.definition)
271
+ as? NWProtocolWebSocket.Metadata
272
+ switch meta?.opcode {
273
+ case .text?, .binary?:
274
+ if let data { consume(data) }
275
+ case .close?:
276
+ connection.cancel()
277
+ return
278
+ default:
279
+ break
481
280
  }
482
- // Continue receiving
483
- receiveWebSocketMessage(on: connection)
281
+ listen(on: connection)
484
282
  }
485
283
  }
486
284
  ```
487
285
 
488
- ## NetworkConnection (iOS 26+)
489
-
490
- `NetworkConnection` is a new Swift-native API introduced in iOS 26 that
491
- provides a modern, type-safe alternative to `NWConnection`. It uses generics
492
- over protocol stacks, supports structured concurrency patterns, and integrates
493
- with async/await via closure-based state handlers.
286
+ With `autoReplyPing` the framework answers pings for you. For app-level
287
+ WebSockets, `URLSessionWebSocketTask` (see
288
+ [background-websocket.md](background-websocket.md#urlsessionwebsockettask))
289
+ is usually simpler.
494
290
 
495
- **Documentation:**
496
- [sosumi.ai/documentation/network/networkconnection](https://sosumi.ai/documentation/network/networkconnection)
291
+ ## The iOS 26 NetworkConnection API
497
292
 
498
- ### Key Differences from NWConnection
293
+ `NetworkConnection` is the Swift-first connection type added in iOS 26. It is
294
+ generic over its protocol stack, uses async/await, and reports state through
295
+ closures. API reference: [NetworkConnection docs](https://developer.apple.com/documentation/network/networkconnection).
499
296
 
500
297
  | | `NWConnection` | `NetworkConnection` |
501
298
  |---|---|---|
502
- | **Availability** | iOS 12+ | iOS 26+ |
503
- | **Type safety** | Untyped protocol stack | Generic `ApplicationProtocol` parameter |
504
- | **Streams** | Single connection | Built-in QUIC stream multiplexing |
505
- | **State updates** | `stateUpdateHandler` callback | `onStateUpdate`, `onPathUpdate` closures |
506
- | **Wi-Fi Aware** | Not supported | `wifiAware` property |
507
- | **API style** | Callback-based | Closure-based with `Sendable` support |
508
-
509
- ### Basic Usage Shape
299
+ | Availability | iOS 12+ | iOS 26+ |
300
+ | Stack typing | Untyped parameters | Generic `ApplicationProtocol` |
301
+ | Streams | One connection | Many QUIC streams share one connection |
302
+ | State | `stateUpdateHandler` | `onStateUpdate` and `onPathUpdate` closures |
303
+ | Wi-Fi Aware | Not available | `wifiAware` property |
304
+ | Style | Callbacks on a queue | Async calls, `Sendable`-aware closures |
510
305
 
511
306
  ```swift
512
- import Network
513
-
514
- let endpoint = NWEndpoint.hostPort(host: "api.example.com", port: 443)
515
- ```
516
-
517
- Use the initializer variant that matches your protocol stack. The documented
518
- forms are:
307
+ let endpoint = NWEndpoint.hostPort(host: "relay.example.net", port: 9443)
519
308
 
520
- ```swift
521
- // Protocol-stack builder form.
522
- NetworkConnection(to: endpoint) {
523
- // ProtocolStackBuilder<ApplicationProtocol>
309
+ let relay = NetworkConnection(to: endpoint) {
310
+ TLS()
524
311
  }
525
312
 
526
- // Parameters-builder form.
527
- NetworkConnection(to: endpoint, using: builder)
528
- ```
529
-
530
- After constructing a concrete connection for your app's protocol stack, install
531
- state handlers and start it:
532
-
533
- ```swift
534
- func startConnection<ApplicationProtocol>(
535
- _ connection: NetworkConnection<ApplicationProtocol>
536
- ) where ApplicationProtocol: NetworkProtocolOptions {
537
- connection.onStateUpdate { state in
313
+ func logStates(of connection: NetworkConnection<TLS>) {
314
+ connection.onStateUpdate { _, state in
538
315
  switch state {
539
- case .ready:
540
- print("Connected")
541
- case .failed(let error):
542
- print("Failed: \(error)")
543
- case .cancelled:
544
- print("Cancelled")
545
- default:
546
- break
316
+ case .ready: Logger.net.info("ready")
317
+ case .failed(let error): Logger.net.error("failed: \(error.localizedDescription)")
318
+ case .cancelled: Logger.net.info("cancelled")
319
+ default: break
547
320
  }
548
321
  }
549
-
550
- connection.start()
551
322
  }
323
+
324
+ logStates(of: relay)
325
+ try await relay.send(Data("status".utf8))
552
326
  ```
553
327
 
554
- `NetworkConnection` is for lower-level protocol stacks and QUIC-style transport
555
- work. Keep ordinary HTTP APIs on `URLSession` unless you need capabilities that
556
- the URL Loading System does not provide.
328
+ The stack can also be built separately and passed with
329
+ `NetworkConnection(to:using:)`. The connection establishes itself when it is
330
+ first used, so the first `send` or `receive` drives it to `ready`.
331
+
332
+ Keep HTTP on URLSession; `NetworkConnection` is for custom protocol stacks
333
+ and QUIC transport.
557
334
 
558
335
  ### QUIC Multiplexed Streams
559
336
 
560
- `NetworkConnection<QUIC>` supports QUIC stream multiplexing natively.
561
- Opening and accepting streams are asynchronous and throwing operations.
337
+ A `NetworkConnection<QUIC>` carries many independent QUIC streams over one
338
+ connection. Opening and accepting streams are both `async throws`. Here `quic` is such a
339
+ connection:
562
340
 
563
341
  ```swift
564
- func openBidirectionalStream(
565
- on connection: NetworkConnection<QUIC>
566
- ) async throws -> QUIC.Stream<QUICStream> {
567
- try await connection.openStream(directionality: .bidirectional)
568
- }
342
+ let outbound = try await quic.openStream(directionality: .bidirectional)
343
+ try await outbound.send(Data("subscribe prices".utf8))
569
344
 
570
- func handleInboundStreams(
571
- on connection: NetworkConnection<QUIC>
572
- ) async throws {
573
- try await connection.inboundStreams { stream in
574
- // Process each incoming QUIC stream.
575
- }
345
+ try await quic.inboundStreams { stream in
346
+ let chunk = try await stream.receive(exactly: 64).content
347
+ route(chunk)
576
348
  }
577
349
  ```
578
350
 
351
+ `openStream` returns a `QUIC.Stream`; `inboundStreams` calls the closure for
352
+ every stream the peer opens. Treat both as fallible suspension points, never
353
+ as synchronous callbacks.
354
+
579
355
  ### Migration Guidance
580
356
 
581
- For new iOS 26+ low-level networking work, evaluate `NetworkConnection` before
582
- adding new `NWConnection` code:
583
- - It provides stronger type safety through its generic `ApplicationProtocol`.
584
- - Stream multiplexing is a first-class concept for QUIC.
585
- - The API is designed for modern Swift with `Sendable` conformance.
357
+ - New low-level code that can require iOS 26: evaluate `NetworkConnection`
358
+ first for typed stacks, first-class QUIC streams and `Sendable`-aware
359
+ design.
360
+ - Apps that still support earlier releases keep `NWConnection`. It is not
361
+ deprecated, and the two can live in the same app.
586
362
 
587
- For projects supporting iOS versions before 26, continue using `NWConnection`.
588
- Both APIs coexist and `NWConnection` is not deprecated.
363
+ The snippets log through `extension Logger { static let net = Logger(subsystem: "app.networking", category: "net") }`.