@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,275 +1,229 @@
1
1
  ---
2
2
  name: swiftui-webkit
3
- description: "Embeds and controls web content in SwiftUI with WebKit for SwiftUI, including WebView, WebPage, navigation policies, JavaScript execution, observable page state, link interception, local HTML or data loading, and custom URL schemes. Use when building iOS 26+ article/detail views, help centers, in-app documentation, or other embedded web experiences backed by HTML, CSS, and JavaScript."
3
+ description: "Web content in SwiftUI with WebKit for SwiftUI: WebView, WebPage, observable page state, navigation policies, link interception, JavaScript calls, local HTML or data, custom URL schemes. Use when an iOS 26+ screen shows articles, detail pages, help centers, in-app docs or other embedded HTML, CSS and JavaScript, or when replacing a WKWebView wrapper. Not for OAuth or deep-link routing."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # SwiftUI WebKit
8
+ # WebKit for SwiftUI
9
9
 
10
- Embed and manage web content in SwiftUI using the native WebKit-for-SwiftUI APIs introduced for iOS 26, iPadOS 26, macOS 26, and visionOS 26. Use this skill when the app needs an integrated web surface, app-owned HTML content, JavaScript-backed page interaction, or custom navigation policy control.
10
+ Starting with the 26 releases (iOS, iPadOS, macOS, visionOS), WebKit ships a SwiftUI
11
+ surface of its own: `WebView` draws web content and `WebPage` is the
12
+ observable model behind it. Everything below needs `import WebKit` and those
13
+ OS versions.
11
14
 
12
- ## Contents
15
+ ## Picking the container
13
16
 
14
- - [Choose the Right Web Container](#choose-the-right-web-container)
15
- - [Displaying Web Content](#displaying-web-content)
16
- - [Loading and Observing with WebPage](#loading-and-observing-with-webpage)
17
- - [Navigation Policies](#navigation-policies)
18
- - [JavaScript Integration](#javascript-integration)
19
- - [Local Content and Custom URL Schemes](#local-content-and-custom-url-schemes)
20
- - [WebView Customization](#webview-customization)
21
- - [Common Mistakes](#common-mistakes)
22
- - [Review Checklist](#review-checklist)
23
- - [References](#references)
24
-
25
- ## Choose the Right Web Container
26
-
27
- Use the narrowest tool that matches the job.
28
-
29
- | Need | Default choice |
17
+ | Situation | Use |
30
18
  |---|---|
31
- | Embedded app-owned web content in SwiftUI | `WebView` + `WebPage` |
32
- | Simple external site presentation with Safari behavior | `SFSafariViewController` |
33
- | OAuth or third-party sign-in | `ASWebAuthenticationSession` |
34
- | Back-deploy below iOS 26 or use missing legacy-only WebKit features | `WKWebView` fallback |
19
+ | Web content that belongs to the app, shown inside a SwiftUI screen | `WebView` with a `WebPage` |
20
+ | Sending the user to an outside site with Safari behaviour | `SFSafariViewController` |
21
+ | OAuth or any third-party sign-in | `ASWebAuthenticationSession` |
22
+ | Deployment target below iOS 26, or a capability only the old API has | a `WKWebView` fallback |
35
23
 
36
- Prefer `WebView` and `WebPage` for modern SwiftUI apps targeting iOS 26+. Apple's WWDC25 guidance explicitly recommends migrating SwiftUI apps away from UIKit/AppKit WebKit wrappers when possible.
24
+ Apple's WWDC25 WebKit guidance points SwiftUI apps away from UIKit and AppKit
25
+ web view wrappers wherever the new API covers the need. Sign-in never runs in
26
+ an embedded web view.
37
27
 
38
- Do not use embedded web views for OAuth. That stays an `ASWebAuthenticationSession` flow.
28
+ ## Showing a page
39
29
 
40
- ## Displaying Web Content
41
-
42
- Use the simple `WebView(url:)` form when the app only needs to render a URL and SwiftUI state drives navigation.
30
+ The shortest path renders a URL and lets SwiftUI state decide which one:
43
31
 
44
32
  ```swift
45
33
  import SwiftUI
46
34
  import WebKit
47
35
 
48
- struct ArticleView: View {
49
- let url: URL
36
+ struct ReleaseNotesView: View {
37
+ let address: URL
50
38
 
51
39
  var body: some View {
52
- WebView(url: url)
40
+ WebView(url: address)
53
41
  }
54
42
  }
55
43
  ```
56
44
 
57
- Create a `WebPage` when the app needs to load requests directly, observe state, call JavaScript, or customize navigation behavior.
45
+ As soon as you need to issue requests yourself, watch state, run
46
+ JavaScript or steer navigation, own a `WebPage` and pass it to
47
+ `WebView(page)`. Deciding this up front is cheaper than retrofitting it.
58
48
 
59
49
  ```swift
60
50
  @Observable
61
51
  @MainActor
62
- final class ArticleModel {
52
+ final class GuideModel {
63
53
  let page = WebPage()
64
54
 
65
- func load(_ url: URL) async throws {
66
- for try await _ in page.load(URLRequest(url: url)) {
67
- }
55
+ func open(_ address: URL) async throws {
56
+ let events = page.load(URLRequest(url: address))
57
+ for try await _ in events { }
68
58
  }
69
59
  }
70
60
 
71
- struct ArticleDetailView: View {
72
- @State private var model = ArticleModel()
73
- let url: URL
61
+ struct GuideScreen: View {
62
+ @State private var model = GuideModel()
63
+ let start: URL
74
64
 
75
65
  var body: some View {
76
66
  WebView(model.page)
77
- .task {
78
- try? await model.load(url)
79
- }
67
+ .task { try? await model.open(start) }
80
68
  }
81
69
  }
82
70
  ```
83
71
 
84
- See [references/loading-and-observation.md](references/loading-and-observation.md) for full examples.
85
-
86
- ## Loading and Observing with WebPage
72
+ ## Loading and observing
87
73
 
88
- `WebPage` is an `@MainActor` observable type. Use it when you need page state in SwiftUI.
74
+ `WebPage` is an observable class isolated to the main actor. Its load
75
+ methods:
89
76
 
90
- Common loading entry points:
91
- - `load(URLRequest)`
92
- - `load(URL)`
93
- - `load(html:baseURL:)`
94
- - `load(_:mimeType:characterEncoding:baseURL:)`
77
+ - `load(_ request: URLRequest)` and `load(_ url: URL?)`
78
+ - `load(html:baseURL:)` for a string of markup
79
+ - `load(_:mimeType:characterEncoding:baseURL:)` for raw `Data`; the encoding
80
+ is a `String.Encoding` such as `.utf8`
95
81
 
96
- Common observable properties:
97
- - `title`
98
- - `url`
99
- - `isLoading`
100
- - `estimatedProgress`
101
- - `currentNavigationEvent`
102
- - `backForwardList`
82
+ Each returns an async sequence of navigation events that throws when the
83
+ navigation fails. Observable properties include `title` (a non-optional
84
+ `String`), `url`, `isLoading`, `estimatedProgress`, `backForwardList`,
85
+ `hasOnlySecureContent` and, from the SwiftUI overlay, `themeColor`.
103
86
 
104
87
  ```swift
105
- struct ReaderView: View {
88
+ struct ArticleReader: View {
106
89
  @State private var page = WebPage()
90
+ let story: URL
107
91
 
108
92
  var body: some View {
109
93
  WebView(page)
110
- .navigationTitle(page.title ?? "Loading")
111
- .overlay {
94
+ .navigationTitle(page.title.isEmpty ? "Article" : page.title)
95
+ .overlay(alignment: .top) {
112
96
  if page.isLoading {
113
97
  ProgressView(value: page.estimatedProgress)
114
98
  }
115
99
  }
116
100
  .task {
117
101
  do {
118
- for try await _ in page.load(URLRequest(url: URL(string: "https://example.com")!)) {
119
- }
102
+ let events = page.load(story)
103
+ for try await _ in events { }
120
104
  } catch {
121
- // Handle load failure.
105
+ // show an inline error state
122
106
  }
123
107
  }
124
108
  }
125
109
  }
126
110
  ```
127
111
 
128
- When you need to react to every navigation, observe the navigation sequence rather than only checking a single property.
129
-
130
- ```swift
131
- Task {
132
- for await event in page.navigations {
133
- // Handle finish, redirect, or failure events.
134
- }
135
- }
136
- ```
137
-
138
- See [references/loading-and-observation.md](references/loading-and-observation.md) for stronger patterns and the load-sequence examples.
112
+ To react to every navigation rather than sampling one property, iterate
113
+ `page.navigations` with `for try await`. The released SDK has no
114
+ `currentNavigationEvent` property; the event sequences are the way to follow
115
+ progress. Details are in [page loading notes](references/loading-and-observation.md).
139
116
 
140
- ## Navigation Policies
117
+ ## Navigation policy
141
118
 
142
- Use `WebPage.NavigationDeciding` to allow, cancel, or customize navigations based on the request or response.
119
+ A type conforming to `WebPage.NavigationDeciding` can permit, cancel or adjust
120
+ navigations by request or by response. Typical jobs:
143
121
 
144
- Typical uses:
145
- - keep app-owned domains inside the embedded web view
146
- - cancel external domains and hand them off with `openURL`
147
- - intercept special callback URLs
148
- - tune `NavigationPreferences`
122
+ - keep the app's own domains inside the web view,
123
+ - cancel links to other domains and hand them to `openURL`,
124
+ - catch callback URLs,
125
+ - adjust `WebPage.NavigationPreferences` for a request.
149
126
 
150
127
  ```swift
151
128
  @MainActor
152
- final class ArticleNavigationDecider: WebPage.NavigationDeciding {
153
- var urlToOpenExternally: URL?
154
-
155
- func decidePolicy(
156
- for action: WebPage.NavigationAction,
157
- preferences: inout WebPage.NavigationPreferences
158
- ) async -> WKNavigationActionPolicy {
159
- guard let url = action.request.url else { return .allow }
160
-
161
- if url.host == "example.com" {
162
- return .allow
163
- }
164
-
165
- urlToOpenExternally = url
129
+ final class DomainGate: WebPage.NavigationDeciding {
130
+ var leaving: URL?
131
+
132
+ func decidePolicy(for step: WebPage.NavigationAction,
133
+ preferences prefs: inout WebPage.NavigationPreferences)
134
+ async -> WKNavigationActionPolicy {
135
+ guard let target = step.request.url, let host = target.host() else { return .allow }
136
+ if host.hasSuffix("docs.example.org") { return .allow }
137
+ leaving = target // opened outside the app by the view
166
138
  return .cancel
167
139
  }
168
140
  }
169
141
  ```
170
142
 
171
- Keep app-level deep-link routing in the navigation skill. This skill owns navigation that happens inside embedded web content.
172
-
173
- See [references/navigation-and-javascript.md](references/navigation-and-javascript.md) for complete patterns.
174
-
175
- ## JavaScript Integration
143
+ This skill covers navigation inside web content. Routing the app itself from
144
+ a deep link belongs to the `swiftui-navigation` skill.
176
145
 
177
- Use `callJavaScript(_:arguments:in:contentWorld:)` to evaluate JavaScript functions against the page.
146
+ ## JavaScript
178
147
 
179
- ```swift
180
- let script = """
181
- const headings = [...document.querySelectorAll('h1, h2')];
182
- return headings.map(node => ({
183
- id: node.id,
184
- text: node.textContent?.trim()
185
- }));
186
- """
187
-
188
- let result = try await page.callJavaScript(script)
189
- let headings = result as? [[String: Any]] ?? []
190
- ```
191
-
192
- You can pass values through the `arguments` dictionary and cast the returned `Any` into the Swift type you actually need.
148
+ `callJavaScript(_:arguments:in:contentWorld:)` runs the string as the body of
149
+ an async JavaScript function, so the script uses `return`. The result comes
150
+ back as `Any?`; cast it to the Swift shape you expect straight away, and pass
151
+ values through `arguments` rather than building them into the script text.
193
152
 
194
153
  ```swift
195
- let result = try await page.callJavaScript(
196
- "return document.getElementById(sectionID)?.getBoundingClientRect().top ?? null;",
197
- arguments: ["sectionID": selectedSectionID]
154
+ let raw = try await page.callJavaScript(
155
+ "return [...document.querySelectorAll(selector)].map(n => ({ id: n.id, text: n.textContent }))",
156
+ arguments: ["selector": "h2"]
198
157
  )
158
+ let headings = raw as? [[String: Any]] ?? []
199
159
  ```
200
160
 
201
- Important boundary: the native SwiftUI WebKit API clearly supports Swift-to-JavaScript calls, but it does not expose an obvious direct replacement for `WKScriptMessageHandler`. If you need coarse JS-to-native signaling, a custom navigation or callback-URL pattern can work, but document it as a workaround pattern, not a guaranteed one-to-one replacement.
161
+ `callJavaScript` is not a message channel from the page to the app. For
162
+ simple one-off signals, the page can navigate to a custom callback URL that
163
+ the navigation decider intercepts; that is a workaround, not a full
164
+ replacement for `WKScriptMessageHandler`. `WebPage.Configuration` does expose
165
+ a `userContentController` (a `WKUserContentController`) for apps that need
166
+ structured script messages. See
167
+ [policy and script notes](references/navigation-and-javascript.md).
202
168
 
203
- See [references/navigation-and-javascript.md](references/navigation-and-javascript.md).
169
+ ## Local content and custom schemes
204
170
 
205
- ## Local Content and Custom URL Schemes
206
-
207
- Use `WebPage.Configuration` and `URLSchemeHandler` when the app needs bundled HTML, offline documents, or app-provided resources under a custom scheme.
171
+ For bundled HTML, offline documentation or resources the app generates,
172
+ register a `URLSchemeHandler` on a `WebPage.Configuration`:
208
173
 
209
174
  ```swift
210
- var configuration = WebPage.Configuration()
211
- configuration.urlSchemeHandlers[URLScheme("docs")!] = DocsSchemeHandler(bundle: .main)
212
-
213
- let page = WebPage(configuration: configuration)
214
- for try await _ in page.load(URL(string: "docs://article/welcome")!) {
175
+ var setup = WebPage.Configuration()
176
+ if let scheme = URLScheme("manual") {
177
+ setup.urlSchemeHandlers[scheme] = ManualFiles()
215
178
  }
216
-
179
+ let page = WebPage(configuration: setup)
180
+ // later: page.load(URL(string: "manual://getting-started"))
217
181
  ```
218
182
 
219
- Use this for:
220
- - bundled documentation or article content
221
- - offline HTML/CSS/JS assets
222
- - app-owned resource loading under a custom scheme
223
-
224
- Do not overuse custom schemes for normal remote content. Prefer standard HTTPS for server-hosted pages.
225
-
226
- See [references/local-content-and-custom-schemes.md](references/local-content-and-custom-schemes.md).
227
-
228
- ## WebView Customization
229
-
230
- Use WebView modifiers to match the intended browsing experience.
231
-
232
- Useful modifiers and related APIs:
233
- - `webViewBackForwardNavigationGestures(_:)`
234
- - `findNavigator(isPresented:)`
235
- - `webViewScrollPosition(_:)`
236
- - `webViewOnScrollGeometryChange(...)`
237
-
238
- Apply them only when the user experience needs them.
239
-
240
- - Enable back/forward gestures when people are likely to visit multiple pages.
241
- - Add Find in Page when the content is document-like.
242
- - Sync scroll position only when the app has a sidebar, table of contents, or other explicit navigation affordance.
243
-
244
- Apple's HIG also applies here: support back/forward navigation when appropriate, but do not turn an app web view into a general-purpose browser.
245
-
246
- ## Common Mistakes
247
-
248
- - Using `WKWebView` wrappers by default in an iOS 26+ SwiftUI app instead of starting with `WebView` and `WebPage`
249
- - Using embedded web views for OAuth instead of `ASWebAuthenticationSession`
250
- - Reaching for `WebPage` only after building a plain `WebView(url:)` path that now needs state, JS, or navigation control
251
- - Treating `callJavaScript` as a direct replacement for `WKScriptMessageHandler`
252
- - Keeping all links inside the app when external domains should open outside the embedded surface
253
- - Building a browser-style app shell around WebView instead of a focused embedded experience
254
- - Using custom URL schemes for content that should just load over HTTPS
255
- - Forgetting that `WebPage` is main-actor-isolated
256
-
257
- ## Review Checklist
258
-
259
- - [ ] `WebView` and `WebPage` are the default path for iOS 26+ SwiftUI web content
260
- - [ ] `ASWebAuthenticationSession` is used for auth flows instead of embedded web views
261
- - [ ] `WebPage` is used whenever the app needs state observation, JS calls, or policy control
262
- - [ ] Navigation policies only intercept the URLs the app actually owns or needs to reroute
263
- - [ ] External domains open externally when appropriate
264
- - [ ] JavaScript return values are cast defensively to concrete Swift types
265
- - [ ] Custom URL schemes are used only for real app-owned resources
266
- - [ ] Back/forward gestures or controls are enabled when multi-page browsing is expected
267
- - [ ] The web experience adds focused native value instead of behaving like a thin browser shell
268
- - [ ] Fallback to `WKWebView` is justified by deployment target or missing API needs
183
+ Ordinary remote content should come over HTTPS, not through a custom scheme.
184
+ Handler implementation and cancellation are covered in
185
+ [scheme handler notes](references/local-content-and-custom-schemes.md).
186
+
187
+ ## View modifiers
188
+
189
+ - `webViewBackForwardNavigationGestures(_:)`: turn on swipe back and forward
190
+ when people will visit several pages.
191
+ - `findNavigator(isPresented:)`: Find in Page for long, document-like content.
192
+ - `webViewScrollPosition(_:)` and `webViewOnScrollGeometryChange(for:of:action:)`:
193
+ sync scrolling only when there is a sidebar, a table of contents or another
194
+ explicit navigation control.
195
+
196
+ The HIG asks for back and forward support where it helps, but an app's web
197
+ view should not grow into a general-purpose browser.
198
+
199
+ ## Common mistakes
200
+
201
+ - Reaching for a `WKWebView` wrapper in a SwiftUI app that targets iOS 26+.
202
+ - Running OAuth inside an embedded web view.
203
+ - Starting with `WebView(url:)` and bolting on `WebPage` later once state,
204
+ JavaScript or navigation control turns out to be needed.
205
+ - Treating `callJavaScript` as if it were `WKScriptMessageHandler`.
206
+ - Keeping every link in the app when other domains should open outside it.
207
+ - Building a browser shell (address bar, tabs) around the web view.
208
+ - Using a custom scheme for content that should load over HTTPS.
209
+ - Touching a `WebPage` off the main actor; the type is `@MainActor`.
210
+
211
+ ## Review checklist
212
+
213
+ - [ ] iOS 26+ screens start from `WebView` plus `WebPage`
214
+ - [ ] Sign-in goes through `ASWebAuthenticationSession`
215
+ - [ ] A `WebPage` exists wherever state, JavaScript or policy control is needed
216
+ - [ ] The navigation decider only intercepts URLs the app owns or reroutes
217
+ - [ ] Other domains open outside the app where that is the better experience
218
+ - [ ] JavaScript results are cast defensively
219
+ - [ ] Custom schemes serve only genuine app-owned resources
220
+ - [ ] Multi-page browsing has back and forward gestures or controls
221
+ - [ ] The screen offers something native and specific, not a wrapped website
222
+ - [ ] Each remaining `WKWebView` has a reason: an older deployment target or a missing API
269
223
 
270
224
  ## References
271
225
 
272
- - Loading and observation: [references/loading-and-observation.md](references/loading-and-observation.md)
273
- - Navigation and JavaScript: [references/navigation-and-javascript.md](references/navigation-and-javascript.md)
274
- - Local content and custom schemes: [references/local-content-and-custom-schemes.md](references/local-content-and-custom-schemes.md)
275
- - Migration and fallbacks: [references/migration-and-fallbacks.md](references/migration-and-fallbacks.md)
226
+ - [page loading notes](references/loading-and-observation.md): URL-only views, controlled loading, progress and title, navigation events, ephemeral pages, user agents
227
+ - [policy and script notes](references/navigation-and-javascript.md): deciders, external links, calling JavaScript, arguments, page-to-app signals
228
+ - [scheme handler notes](references/local-content-and-custom-schemes.md): scheme handlers, responses, bundled files, cancellation
229
+ - [migration notes](references/migration-and-fallbacks.md): moving off `WKWebView` wrappers, Safari and sign-in boundaries, testing
@@ -1,151 +1,140 @@
1
- # Loading and Observation
1
+ # Loading and observing pages
2
2
 
3
- ## Contents
4
- - Simple `WebView(url:)`
5
- - Controlled `WebPage` loading
6
- - Observing progress and title
7
- - Observing navigation events
8
- - Ephemeral pages and custom user agents
3
+ Part of the `swiftui-webkit` skill ([../SKILL.md](../SKILL.md)). All code
4
+ needs iOS 26, iPadOS 26, macOS 26 or visionOS 26 and `import WebKit`.
9
5
 
10
- ## Simple `WebView(url:)`
6
+ ## The URL-only view
11
7
 
12
- Use `WebView(url:)` when the app only needs to display a URL and does not need explicit page control.
8
+ When all you need is to show a page and let people move back and forth,
9
+ `WebView(url:)` plus the gesture modifier is the least code:
13
10
 
14
11
  ```swift
15
- import SwiftUI
16
- import WebKit
17
-
18
- struct MarketingPageView: View {
19
- let url: URL
12
+ struct PolicyPage: View {
13
+ let link: URL
20
14
 
21
15
  var body: some View {
22
- WebView(url: url)
16
+ WebView(url: link)
23
17
  .webViewBackForwardNavigationGestures(.enabled)
24
18
  }
25
19
  }
26
20
  ```
27
21
 
28
- This is the lowest-friction path for embedded content.
29
-
30
- ## Controlled `WebPage` loading
22
+ ## Loading through a WebPage
31
23
 
32
- Create a `WebPage` when the app needs to drive loading itself.
24
+ A model that owns the page can keep the last failure for the UI:
33
25
 
34
26
  ```swift
35
27
  @Observable
36
28
  @MainActor
37
- final class ArticleModel {
29
+ final class HelpCenterModel {
38
30
  let page = WebPage()
39
- var lastError: String?
31
+ var failure: Error?
40
32
 
41
- func load(_ url: URL) async {
33
+ func show(_ address: URL) async {
34
+ failure = nil
42
35
  do {
43
- for try await _ in page.load(URLRequest(url: url)) {
44
- }
36
+ for try await _ in page.load(URLRequest(url: address)) { }
45
37
  } catch {
46
- lastError = error.localizedDescription
38
+ failure = error
47
39
  }
48
40
  }
49
41
  }
50
42
  ```
51
43
 
52
- ```swift
53
- struct ArticleDetailView: View {
54
- @State private var model = ArticleModel()
55
- let url: URL
44
+ The other load entry points return the same kind of event sequence:
56
45
 
57
- var body: some View {
58
- WebView(model.page)
59
- .task {
60
- await model.load(url)
61
- }
62
- }
63
- }
46
+ ```swift
47
+ _ = page.load(address)
48
+ _ = page.load(html: "<h1>Offline</h1><p>Try again later.</p>") // baseURL defaults to about:blank
49
+ _ = page.load(markupData,
50
+ mimeType: "text/html",
51
+ characterEncoding: .utf8,
52
+ baseURL: bundleFolder)
64
53
  ```
65
54
 
66
- You can also load:
67
- - `for try await _ in page.load(url) { }`
68
- - `for try await _ in page.load(html: htmlString, baseURL: baseURL) { }`
69
- - `for try await _ in page.load(data, mimeType: "text/html", characterEncoding: "utf-8", baseURL: baseURL) { }`
55
+ Iterate the returned sequence (or ignore it) depending on whether the caller
56
+ cares when the load ends. `characterEncoding` takes a `String.Encoding`, not a
57
+ string like `"utf-8"`.
70
58
 
71
- ## Observing progress and title
59
+ ## Progress, title and other state
72
60
 
73
- `WebPage` is observable, so SwiftUI can bind directly to its state.
61
+ Besides `title`, `url`, `isLoading`, `estimatedProgress` and
62
+ `backForwardList`, a page reports `themeColor` (the page's theme colour, if
63
+ any) and `hasOnlySecureContent`.
74
64
 
75
65
  ```swift
76
- struct ReaderView: View {
77
- @State private var page = WebPage()
66
+ struct DocsPane: View {
67
+ @State private var model = HelpCenterModel()
68
+ let home: URL
78
69
 
79
70
  var body: some View {
80
- WebView(page)
81
- .navigationTitle(page.title ?? "Loading")
71
+ WebView(model.page)
72
+ .navigationTitle(model.page.title)
73
+ .toolbarBackground(model.page.themeColor ?? .clear, for: .navigationBar)
82
74
  .overlay(alignment: .top) {
83
- if page.isLoading {
84
- ProgressView(value: page.estimatedProgress)
85
- .padding()
86
- }
87
- }
88
- .task {
89
- do {
90
- for try await _ in page.load(URLRequest(url: URL(string: "https://example.com/docs")!)) {
91
- }
92
- } catch {
93
- // Handle load failure.
75
+ if model.page.isLoading {
76
+ ProgressView(value: model.page.estimatedProgress)
77
+ .padding(.horizontal)
94
78
  }
95
79
  }
80
+ .task { await model.show(home) }
96
81
  }
97
82
  }
98
83
  ```
99
84
 
100
- Useful properties:
101
- - `title`
102
- - `url`
103
- - `isLoading`
104
- - `estimatedProgress`
105
- - `themeColor`
106
- - `hasOnlySecureContent`
107
- - `backForwardList`
108
-
109
- ## Observing navigation events
85
+ ## Following navigation events
110
86
 
111
- Use `currentNavigationEvent` for a lightweight current-state view. Use `navigations` to observe the full sequence of navigation events.
87
+ `load` returns the events of that one navigation; `page.navigations` delivers
88
+ the events of every navigation the page makes, including link taps. Both are
89
+ throwing sequences. The event cases are `.startedProvisionalNavigation`,
90
+ `.receivedServerRedirect`, `.committed` and `.finished`. Failures are not
91
+ events: they arrive as thrown errors, typically a `WebPage.NavigationError`
92
+ such as `.failedProvisionalNavigation(_:)`, `.webContentProcessTerminated`
93
+ or `.pageClosed`.
112
94
 
113
95
  ```swift
114
96
  @MainActor
115
- func observeNavigations(for page: WebPage) {
116
- Task {
117
- for await event in page.navigations {
97
+ func watch(_ page: WebPage) async {
98
+ do {
99
+ for try await event in page.navigations {
118
100
  switch event {
119
101
  case .finished:
120
- print("Navigation finished")
121
- case .failed(let error), .failedProvisionalNavigation(let error):
122
- print("Navigation failed: \(error)")
102
+ await collectHeadings(from: page) // follow-up work goes here
123
103
  default:
124
104
  break
125
105
  }
126
106
  }
107
+ } catch WebPage.NavigationError.failedProvisionalNavigation(let reason) {
108
+ report(reason)
109
+ } catch {
110
+ report(error)
127
111
  }
128
112
  }
129
113
  ```
130
114
 
131
- This is the right place to trigger follow-up work like parsing headings after a finished navigation.
115
+ The finished event is the right moment for work that needs the loaded
116
+ document, such as reading its headings. For lightweight UI, the observable
117
+ properties (`isLoading`, `estimatedProgress`) are usually enough; there is no
118
+ separate "current event" property.
132
119
 
133
- ## Ephemeral pages and custom user agents
120
+ ## Throwaway pages and custom user agents
134
121
 
135
- Use `WebPage.Configuration` when you need a nonpersistent page, custom user agent, or tighter loading rules.
122
+ For a quick metadata fetch or an isolated session, configure a page that
123
+ keeps nothing around:
136
124
 
137
125
  ```swift
138
126
  @MainActor
139
- func makeMetadataPage() -> WebPage {
140
- var configuration = WebPage.Configuration()
141
- configuration.loadsSubresources = false
142
- configuration.defaultNavigationPreferences.allowsContentJavaScript = false
143
- configuration.websiteDataStore = .nonPersistent()
144
-
145
- let page = WebPage(configuration: configuration)
146
- page.customUserAgent = "MetadataBot/1.0"
127
+ func makeScratchPage() -> WebPage {
128
+ var setup = WebPage.Configuration()
129
+ setup.loadsSubresources = false
130
+ setup.defaultNavigationPreferences.allowsContentJavaScript = false
131
+ setup.websiteDataStore = .nonPersistent()
132
+
133
+ let page = WebPage(configuration: setup)
134
+ page.customUserAgent = "ExampleReader/2.1"
147
135
  return page
148
136
  }
149
137
  ```
150
138
 
151
- Use nonpersistent pages when you want an isolated web session or metadata fetch path without shared cookies or long-lived website data.
139
+ A non-persistent data store means no shared cookies and no long-lived website
140
+ data, so each such page is its own sealed session.