@mmerterden/multi-agent-pipeline 20.6.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 (326) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +328 -329
  5. package/package.json +2 -2
  6. package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
  7. package/pipeline/scripts/_notices.mjs +12 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +1 -1
  9. package/pipeline/skills/.skill-manifest.json +106 -106
  10. package/pipeline/skills/shared/README.md +71 -71
  11. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
  12. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  13. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  14. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  15. package/pipeline/skills/shared/external/android-architecture/SKILL.md +2 -0
  16. package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
  17. package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
  18. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  19. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  20. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  21. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  22. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  23. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  24. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  25. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  26. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  27. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  28. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  29. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  30. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  31. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  32. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  33. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  34. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  35. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  37. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  38. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  39. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  40. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  41. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  42. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  43. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  44. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  45. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  46. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  47. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  48. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  49. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  50. package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
  51. package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
  52. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  53. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  54. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  55. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
  56. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  57. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  58. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  59. package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
  60. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
  61. package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
  62. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  63. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  64. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  65. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  66. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  67. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  68. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  69. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  70. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  71. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  72. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  73. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  74. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  75. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  76. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  77. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  78. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  79. package/pipeline/skills/shared/external/council/SKILL.md +1 -0
  80. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  81. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  82. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  83. package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
  84. package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
  85. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  86. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  87. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  88. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  89. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  90. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  91. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  92. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  93. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  94. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  95. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  96. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  97. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  98. package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
  99. package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
  100. package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
  101. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  102. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  103. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  104. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  105. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  106. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  107. package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
  108. package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
  109. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  110. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  111. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  112. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  113. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  114. package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
  115. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  116. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  117. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  118. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  119. package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
  120. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  121. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  122. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  123. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  124. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  125. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  126. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  127. package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
  128. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  129. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  130. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  131. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  132. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  133. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  134. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
  135. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
  136. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
  137. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
  138. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
  139. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
  140. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
  141. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
  142. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
  143. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
  144. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
  145. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
  146. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
  147. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
  148. package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
  149. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
  150. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  151. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  152. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  153. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  154. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  155. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  156. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  157. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  158. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  159. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  160. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  161. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  162. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  163. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
  164. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  165. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  166. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  167. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  168. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  169. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  170. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  171. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  172. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  173. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  174. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  175. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  176. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  177. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  178. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  179. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  180. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  181. package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
  182. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  183. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  184. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  185. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  186. package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
  187. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
  188. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  189. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  190. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  191. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
  192. package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
  193. package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
  194. package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
  195. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  196. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  197. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  198. package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
  199. package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
  200. package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
  201. package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
  202. package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
  203. package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
  204. package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
  205. package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
  206. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  207. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  208. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  209. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  210. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  211. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  212. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  213. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  214. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  215. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  216. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  217. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  218. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  219. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  220. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  221. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  222. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  223. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  224. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  225. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  226. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  227. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  228. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  229. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  230. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  231. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  232. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  233. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  234. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  235. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  236. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  237. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  238. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  239. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  240. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  241. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  242. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  243. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  244. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  245. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  246. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  247. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  248. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  249. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  250. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  251. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  252. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  253. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  254. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  255. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  256. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  257. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  258. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  259. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  260. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  261. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  262. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  263. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  264. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  265. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  266. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  267. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  268. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  269. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  270. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  271. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  272. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  273. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  274. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  275. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  276. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  277. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  278. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  279. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  280. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  281. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  282. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  283. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  284. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  285. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  286. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  287. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  288. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  289. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  290. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  291. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  292. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  293. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  294. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  295. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  296. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  297. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  298. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  299. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  300. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  301. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  302. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  303. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  304. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  305. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  306. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  307. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  308. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  309. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  310. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
  311. package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
  312. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  313. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  314. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
  315. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  316. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  317. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  318. package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
  319. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  320. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  321. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
  322. package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
  323. package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
  324. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  325. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  326. 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") }`.