@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.1

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 (284) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +285 -285
  5. package/package.json +3 -3
  6. package/pipeline/lib/redact.mjs +3 -2
  7. package/pipeline/scripts/_notices.mjs +1 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +13 -1
  9. package/pipeline/scripts/pre-commit-check.sh +4 -0
  10. package/pipeline/skills/.skill-manifest.json +69 -69
  11. package/pipeline/skills/shared/README.md +70 -70
  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/app-clips/SKILL.md +260 -160
  16. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  17. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  18. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  19. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  20. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  21. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  22. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  23. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +345 -277
  24. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  25. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +107 -121
  26. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +145 -165
  27. package/pipeline/skills/shared/external/app-store-review/SKILL.md +306 -326
  28. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  29. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  30. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  31. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +335 -360
  32. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  34. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  35. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  37. package/pipeline/skills/shared/external/authentication/SKILL.md +277 -381
  38. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  39. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +135 -178
  40. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  41. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  42. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  43. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  44. package/pipeline/skills/shared/external/background-processing/SKILL.md +274 -384
  45. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  46. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +173 -321
  47. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  48. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  49. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  50. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  51. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  52. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  53. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  54. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  55. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  56. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +228 -376
  57. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  58. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  59. package/pipeline/skills/shared/external/core-data/SKILL.md +302 -368
  60. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  61. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  62. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  63. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  64. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  65. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  66. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  67. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  68. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  69. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  70. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  71. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  72. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  73. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  74. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  75. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  76. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  77. package/pipeline/skills/shared/external/device-integrity/SKILL.md +236 -353
  78. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  79. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  80. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  81. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  82. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  83. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  84. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  85. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  86. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  87. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  88. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  89. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  90. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  91. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  92. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  93. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  94. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  95. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  96. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  97. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  98. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  99. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  100. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  101. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  102. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  103. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  104. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  105. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  106. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  107. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  108. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  109. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  111. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  112. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  113. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  114. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +3 -3
  115. package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +1 -1
  116. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +8 -7
  117. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +2 -2
  118. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +5 -2
  119. package/pipeline/skills/shared/external/localization-reuse-map/scripts/_shared.py +100 -0
  120. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +45 -26
  121. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +14 -16
  122. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +12 -5
  123. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +2 -1
  124. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +6 -5
  125. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +44 -18
  126. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +5 -2
  127. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +10 -11
  128. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +4 -33
  129. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +12 -59
  130. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +297 -267
  131. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  132. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  133. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  134. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  135. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  136. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  137. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  138. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  139. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  140. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  141. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  142. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  143. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  144. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  145. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  146. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  147. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  148. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  149. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  150. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  151. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  152. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  153. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  154. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  155. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  156. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  157. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  158. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  159. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  160. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  161. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  162. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  163. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  164. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  165. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  166. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  167. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  168. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  169. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  170. package/pipeline/skills/shared/external/skill-creator/template.md +7 -1
  171. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  172. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  173. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  174. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  175. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  176. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  177. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +302 -241
  178. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  179. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  180. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  181. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  182. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  183. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  184. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  185. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  186. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  187. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  188. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  189. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  191. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +304 -351
  193. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  194. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  195. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  196. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  197. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  198. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  199. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  200. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  201. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  202. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  203. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  204. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  205. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  206. package/pipeline/skills/shared/external/swift-security/SKILL.md +183 -162
  207. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  208. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  209. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +411 -476
  210. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  211. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  212. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  213. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  214. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  215. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  216. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +375 -491
  217. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  218. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  219. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  220. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +397 -457
  221. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  222. package/pipeline/skills/shared/external/swift-testing/SKILL.md +191 -175
  223. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  224. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +81 -84
  225. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  226. package/pipeline/skills/shared/external/swiftdata/SKILL.md +394 -256
  227. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  228. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  229. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  230. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  231. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  232. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  233. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  234. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  235. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  236. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  237. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  238. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  239. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  240. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  241. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  242. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  243. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  244. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  245. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  246. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  247. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  248. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  249. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  250. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  251. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +201 -168
  252. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  253. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +134 -133
  254. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  255. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +111 -138
  256. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  257. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  258. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  259. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  260. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  261. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  262. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  263. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  264. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  265. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  266. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  267. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  268. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  269. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  270. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  271. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  272. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  273. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  274. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  275. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  276. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  277. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  278. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  279. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  280. package/pipeline/skills/shared/external/weatherkit/SKILL.md +160 -315
  281. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  282. package/pipeline/skills/shared/external/widgetkit/SKILL.md +224 -288
  283. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +416 -719
  284. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,500 +1,456 @@
1
1
  ---
2
2
  name: coreml
3
- description: "Integrate Core ML models in iOS apps for on-device machine learning inference. Covers model loading (.mlmodel, .mlpackage, .mlmodelc), predictions with auto-generated classes and MLFeatureProvider, compute unit configuration (CPU, GPU, Neural Engine), MLTensor, VNCoreMLRequest, MLComputePlan, multi-model pipelines, and deployment strategies. Use when loading Core ML models, making predictions, configuring compute units, or profiling model performance."
3
+ description: "Swift-side Core ML: loading .mlmodel, .mlpackage and .mlmodelc, predictions via generated classes and MLFeatureProvider, compute units, async and stateful prediction with MLState, MLTensor, MLMultiArray, MLComputePlan, multi-model pipelines, deployment and profiling. Use when integrating, reviewing, deploying or profiling a Core ML model in an app. Not for Python conversion (apple-on-device-ai) or Vision requests (vision-framework)."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
- # Core ML Swift Integration
8
7
 
9
- Load, configure, and run Core ML models in iOS apps. This skill covers the
10
- Swift side: model loading, prediction, MLTensor, profiling, and deployment.
11
- Target iOS 26+ with Swift 6.3, backward-compatible to iOS 14 unless noted.
8
+ # Core ML
12
9
 
13
- > **Scope boundary:** Python-side model conversion, optimization (quantization,
14
- > palettization, pruning), and framework selection live in the `apple-on-device-ai`
15
- > skill. This skill owns Swift integration only.
10
+ This skill covers the app side of Core ML: getting a model into memory,
11
+ feeding it, reading its output, and shipping it. Baseline: iOS 26 and Swift
12
+ 6.3, with each API's lower floor stated where it matters (much of Core ML goes
13
+ back to iOS 14 or earlier).
16
14
 
17
- See [references/coreml-swift-integration.md](references/coreml-swift-integration.md) for complete code patterns including
18
- actor-based caching, batch inference, image preprocessing, and testing.
15
+ Out of scope here: converting or compressing models in Python (quantization,
16
+ palettization, pruning) and choosing between on-device AI frameworks; those
17
+ belong to `apple-on-device-ai`. Text recognition, barcodes and document
18
+ scanning with Vision belong to `vision-framework`.
19
19
 
20
- ## Contents
20
+ Longer code (an actor that owns models, SwiftUI wiring, custom feature
21
+ providers, stateful sessions, pixel buffers, tensors, Vision pipelines,
22
+ NaturalLanguage, compute plans, lifecycle, errors, tests) is in
23
+ `references/coreml-swift-integration.md`.
21
24
 
22
- - [Loading Models](#loading-models)
23
- - [Model Configuration](#model-configuration)
24
- - [Making Predictions](#making-predictions)
25
- - [MLTensor (iOS 18+)](#mltensor-ios-18)
26
- - [Working with MLMultiArray](#working-with-mlmultiarray)
27
- - [Image Preprocessing](#image-preprocessing)
28
- - [Multi-Model Pipelines](#multi-model-pipelines)
29
- - [Vision Integration](#vision-integration)
30
- - [Performance Profiling](#performance-profiling)
31
- - [Model Deployment](#model-deployment)
32
- - [Memory Management](#memory-management)
33
- - [Common Mistakes](#common-mistakes)
34
- - [Review Checklist](#review-checklist)
35
- - [References](#references)
25
+ ## Loading a model
36
26
 
37
- ## Loading Models
38
-
39
- ### Auto-Generated Classes
40
-
41
- When you add a `.mlmodel` or `.mlpackage` to an app target, Xcode generates a Swift
42
- class with typed input/output. Use this whenever possible.
27
+ **Generated class.** Drop a `.mlmodel` or `.mlpackage` into a target and Xcode
28
+ generates a Swift class with typed inputs and outputs. Use it whenever it
29
+ exists.
43
30
 
44
31
  ```swift
45
32
  import CoreML
46
33
 
47
- let config = MLModelConfiguration()
48
- config.computeUnits = .all
49
-
50
- let model = try MyImageClassifier(configuration: config)
34
+ func makeDenoiser() throws -> PhotoDenoiser {
35
+ let settings = MLModelConfiguration()
36
+ settings.computeUnits = .all
37
+ return try PhotoDenoiser(configuration: settings)
38
+ }
51
39
  ```
52
40
 
53
- ### Manual Loading
54
-
55
- Load from a URL when the model is downloaded at runtime or stored outside the
56
- bundle.
41
+ **From a URL.** For models that are downloaded or stored outside the bundle:
57
42
 
58
43
  ```swift
59
- let modelURL = Bundle.main.url(
60
- forResource: "MyModel", withExtension: "mlmodelc"
61
- )!
62
- let model = try MLModel(contentsOf: modelURL, configuration: config)
63
- ```
64
-
65
- ### Async Loading (iOS 15+)
66
-
67
- Load models without blocking the main thread. Prefer this for large models.
44
+ import CoreML
68
45
 
69
- ```swift
70
- let model = try await MLModel.load(
71
- contentsOf: modelURL,
72
- configuration: config
73
- )
46
+ func bundledModel(named name: String) throws -> MLModel {
47
+ guard let url = Bundle.main.url(forResource: name, withExtension: "mlmodelc") else {
48
+ throw CocoaError(.fileNoSuchFile)
49
+ }
50
+ return try MLModel(contentsOf: url, configuration: MLModelConfiguration())
51
+ }
74
52
  ```
75
53
 
76
- ### Compile at Runtime (iOS 16+)
77
-
78
- Compile a `.mlpackage` or `.mlmodel` to `.mlmodelc` on device. Useful for
79
- models downloaded from a server. Do this once per model version, not on every
80
- launch.
54
+ **Asynchronously.** `MLModel.load(contentsOf:configuration:)` (async, iOS 15+)
55
+ keeps large models from stalling the main thread and is the preferred loader.
81
56
 
82
- ```swift
83
- let compiledURL = try await MLModel.compileModel(at: packageURL)
84
- let model = try await MLModel.load(contentsOf: compiledURL, configuration: config)
85
- ```
57
+ **Compiling on device.** `MLModel.compileModel(at:)` (async form, iOS 16+)
58
+ turns a `.mlmodel` or `.mlpackage` into a `.mlmodelc` on the device, which is
59
+ how server-delivered models become loadable. Two rules travel together:
86
60
 
87
- Cache the compiled URL -- recompiling on every launch is a bug. Copy
88
- `compiledURL` to a persistent location (e.g., Application Support). When
89
- reviewing runtime-loaded models, call out both facts together: async
90
- `MLModel.compileModel(at:)` is iOS 16+, and compiled models must be cached so the
91
- app does not recompile on every launch.
61
+ 1. Compile once per model version, never on every launch; recompiling at each
62
+ start is a bug.
63
+ 2. The returned URL points into a temporary location. Move the `.mlmodelc`
64
+ somewhere durable such as Application Support and reuse it.
92
65
 
93
- ## Model Configuration
66
+ When reviewing runtime-loaded models, state both: the async compile API needs
67
+ iOS 16, and its output must be cached.
94
68
 
95
- `MLModelConfiguration` controls compute units, GPU access, and model parameters.
69
+ ## Configuration and compute units
96
70
 
97
- ### Compute Units Decision Table
71
+ `MLModelConfiguration` chooses hardware, GPU precision and model parameters.
98
72
 
99
- | Value | Uses | When to Choose |
73
+ | `computeUnits` | Hardware | When |
100
74
  |---|---|---|
101
- | `.all` | CPU + GPU + Neural Engine | Default. Let the system decide. |
102
- | `.cpuOnly` | CPU | Deterministic tests, CPU-only fallbacks, or constrained work after profiling shows accelerator policy, contention, thermal state, or energy budget is the limiting factor. |
103
- | `.cpuAndGPU` | CPU + GPU | Need GPU but model has ops unsupported by ANE. |
104
- | `.cpuAndNeuralEngine` (iOS 16+) | CPU + Neural Engine | Best energy efficiency for compatible models. |
75
+ | `.all` (default) | CPU, GPU, Neural Engine; the system decides | Almost always |
76
+ | `.cpuOnly` | CPU | Deterministic tests, CPU-only fallbacks, or when profiling shows accelerator policy, contention, thermal state or energy budget is the constraint |
77
+ | `.cpuAndGPU` | CPU and GPU | The model needs the GPU but has operations the Neural Engine cannot run |
78
+ | `.cpuAndNeuralEngine` (iOS 16+) | CPU and Neural Engine | Best energy efficiency for models the Neural Engine fully supports |
105
79
 
106
80
  ```swift
107
- let config = MLModelConfiguration()
108
- config.computeUnits = .cpuAndNeuralEngine
109
-
110
- // Optional fallback for constrained work after profiling and policy review
111
- config.computeUnits = .cpuOnly
112
- ```
113
-
114
- ### Configuration Properties
81
+ import CoreML
115
82
 
116
- ```swift
117
- let config = MLModelConfiguration()
118
- config.computeUnits = .all
119
- config.allowLowPrecisionAccumulationOnGPU = true // faster, slight precision loss
83
+ func efficientSettings(fallbackToCPU: Bool) -> MLModelConfiguration {
84
+ let settings = MLModelConfiguration()
85
+ settings.computeUnits = fallbackToCPU ? .cpuOnly : .cpuAndNeuralEngine
86
+ settings.allowLowPrecisionAccumulationOnGPU = true
87
+ return settings
88
+ }
120
89
  ```
121
90
 
122
- ## Making Predictions
91
+ `allowLowPrecisionAccumulationOnGPU` buys speed for a small loss of precision.
92
+ Choose `.cpuOnly` only after profiling says so.
123
93
 
124
- ### With Auto-Generated Classes
94
+ ## Predictions
125
95
 
126
- The generated class provides typed input/output structs.
96
+ **Generated class:**
127
97
 
128
98
  ```swift
129
- let model = try MyImageClassifier(configuration: config)
130
- let input = MyImageClassifierInput(image: pixelBuffer)
131
- let output = try model.prediction(input: input)
132
- print(output.classLabel) // "golden_retriever"
133
- print(output.classLabelProbs) // ["golden_retriever": 0.95, ...]
99
+ import CoreML
100
+
101
+ func tagScene(_ frame: CVPixelBuffer, with model: SceneTagger) throws -> (String, Double) {
102
+ let result = try model.prediction(input: SceneTaggerInput(image: frame))
103
+ return (result.classLabel, result.classLabelProbs[result.classLabel] ?? 0)
104
+ }
134
105
  ```
135
106
 
136
- ### With MLDictionaryFeatureProvider
107
+ `classLabel` is the winning label and `classLabelProbs` maps every label to
108
+ its probability.
137
109
 
138
- Use when inputs are dynamic or not known at compile time.
110
+ **Dictionary provider**, for inputs only known at run time:
139
111
 
140
112
  ```swift
141
- let inputFeatures = try MLDictionaryFeatureProvider(dictionary: [
142
- "image": MLFeatureValue(pixelBuffer: pixelBuffer),
143
- "confidence_threshold": MLFeatureValue(double: 0.5),
144
- ])
145
- let output = try model.prediction(from: inputFeatures)
146
- let label = output.featureValue(for: "classLabel")?.stringValue
147
- ```
113
+ import CoreML
148
114
 
149
- ### Prediction Inside Async Workflows
115
+ func tagWithThreshold(_ frame: CVPixelBuffer, cutoff: Double, model: MLModel) async throws -> String? {
116
+ let inputs = try MLDictionaryFeatureProvider(dictionary: [
117
+ "image": MLFeatureValue(pixelBuffer: frame),
118
+ "threshold": MLFeatureValue(double: cutoff)
119
+ ])
120
+ let outputs = try await model.prediction(from: inputs)
121
+ return outputs.featureValue(for: "label")?.stringValue
122
+ }
123
+ ```
150
124
 
151
- `MLModel.prediction(...)` is synchronous. In async pipelines, keep model loading
152
- async, then run prediction from an actor or non-main task without adding `await`
153
- to the prediction call.
125
+ ### Sync or async prediction
154
126
 
155
- ```swift
156
- let output = try model.prediction(from: inputFeatures)
157
- ```
127
+ - `prediction(from:)` and `prediction(from:options:)` exist in a synchronous
128
+ throwing form on every supported OS.
129
+ - From iOS 17 there is also `prediction(from:options:) async throws`, which
130
+ may be called concurrently on the same model. Inside an `async` function the
131
+ compiler resolves to that overload, so the call needs `try await`; leaving
132
+ out `await` there does not compile.
133
+ - In synchronous code (a serial queue, a synchronous actor method) the
134
+ synchronous form is used without `await`.
135
+ - Loading stays async either way (`MLModel.load`).
158
136
 
159
- ### Batch Prediction
137
+ ### Batches
160
138
 
161
- Process multiple inputs in one call for better throughput.
139
+ Processing several inputs per call raises throughput:
162
140
 
163
141
  ```swift
164
- let batchInputs = try MLArrayBatchProvider(array: inputs.map { input in
165
- try MLDictionaryFeatureProvider(dictionary: ["image": MLFeatureValue(pixelBuffer: input)])
166
- })
167
- let batchOutput = try model.predictions(fromBatch: batchInputs)
168
- for i in 0..<batchOutput.count {
169
- let result = batchOutput.features(at: i)
170
- print(result.featureValue(for: "classLabel")?.stringValue ?? "unknown")
142
+ import CoreML
143
+
144
+ func labels(for frames: [CVPixelBuffer], model: MLModel) throws -> [String] {
145
+ let rows = try frames.map { try MLDictionaryFeatureProvider(dictionary: ["image": MLFeatureValue(pixelBuffer: $0)]) }
146
+ let answers = try model.predictions(fromBatch: MLArrayBatchProvider(array: rows))
147
+ return (0..<answers.count).compactMap { answers.features(at: $0).featureValue(for: "label")?.stringValue }
171
148
  }
172
149
  ```
173
150
 
174
- Use `predictions(fromBatch:)` when batching without explicit
175
- `MLPredictionOptions`. Use `predictions(from:options:)` only when passing both an
176
- `MLBatchProvider` and `MLPredictionOptions`; `predictions(from:)` by itself is
177
- not the no-options batch API.
151
+ Two batch spellings are valid: `predictions(fromBatch:)` without options, and
152
+ `predictions(from:options:)` when you pass an `MLBatchProvider` together with
153
+ `MLPredictionOptions`. There is no options-free `predictions(from:)`; do not
154
+ write one.
178
155
 
179
- ### Stateful Prediction (iOS 18+)
156
+ ### Stateful models with MLState (iOS 18+)
180
157
 
181
- Use `MLState` for models that maintain state across predictions (sequence models,
182
- LLMs, audio accumulators). Create state once and pass it to each prediction call.
158
+ Sequence models (language models, streaming audio, time series) keep context
159
+ between calls. Create a state once per stream and pass it to every call.
183
160
 
184
161
  ```swift
185
- let state = model.makeState()
162
+ import CoreML
186
163
 
187
- // Each synchronous prediction carries forward the internal model state
188
- for frame in audioFrames {
189
- let input = try MLDictionaryFeatureProvider(dictionary: [
190
- "audio_features": MLFeatureValue(multiArray: frame)
191
- ])
192
- let output = try model.prediction(from: input, using: state)
193
- let classification = output.featureValue(for: "label")?.stringValue
164
+ func classifyStream(_ windows: [MLMultiArray], model: MLModel) throws -> [String] {
165
+ let memory = model.makeState()
166
+ return try windows.compactMap { window in
167
+ let input = try MLDictionaryFeatureProvider(dictionary: ["samples": MLFeatureValue(multiArray: window)])
168
+ return try model.prediction(from: input, using: memory).featureValue(for: "label")?.stringValue
169
+ }
194
170
  }
195
171
  ```
196
172
 
197
- `MLState` is `Sendable`, but `Sendable` does not make one state safe for
198
- concurrent inference. Predictions using the same state must be serialized; do
199
- not read or write state buffers while a prediction is in flight. Call
200
- `model.makeState()` for each independent concurrent stream. If you need
201
- `MLPredictionOptions`, iOS 18+ also provides the async
202
- `prediction(from:using:options:)` overload; the same one-in-flight-per-state rule
203
- still applies.
173
+ Rules for `MLState`:
174
+
175
+ - It is `Sendable`, which lets it move between concurrency domains. It does
176
+ not make concurrent predictions on one state safe: run them one at a time.
177
+ - Do not read or write the state's buffers while a prediction is running.
178
+ - Independent concurrent streams each get their own `model.makeState()`.
179
+ - The async `prediction(from:using:options:)` (iOS 18) is there when you need
180
+ options or are in async code; the same one-prediction-in-flight rule holds.
181
+ The synchronous `prediction(from:using:)` is for synchronous loops.
204
182
 
205
183
  ## MLTensor (iOS 18+)
206
184
 
207
- `MLTensor` is a Swift-native multidimensional array for pre/post-processing.
208
- Operations run lazily -- call `await tensor.shapedArray(of:)` to materialize results.
185
+ `MLTensor` is a Swift multidimensional array for pre- and post-processing.
186
+ Operations are lazy; results materialize only when you await
187
+ `shapedArray(of:)`.
209
188
 
210
189
  ```swift
211
190
  import CoreML
212
191
 
213
- // Creation
214
- let tensor = MLTensor([1.0, 2.0, 3.0, 4.0])
215
- let zeros = MLTensor(zeros: [3, 224, 224], scalarType: Float.self)
216
-
217
- // Reshaping
218
- let reshaped = tensor.reshaped(to: [2, 2])
219
-
220
- // Math operations
221
- let softmaxed = tensor.softmax(alongAxis: -1)
222
- let centered = tensor - tensor.mean()
192
+ func normalizedScores(_ logits: [Float]) async -> MLMultiArray {
193
+ let raw = MLTensor(logits).reshaped(to: [1, logits.count])
194
+ let centered = raw - raw.mean()
195
+ let probabilities = centered.softmax(alongAxis: -1)
196
+ let shaped = await probabilities.shapedArray(of: Float.self)
197
+ return MLMultiArray(shaped)
198
+ }
223
199
 
224
- // Interop with MLShapedArray / MLMultiArray
225
- let shaped = await tensor.shapedArray(of: Float.self)
226
- let multiArray = try MLMultiArray(shaped)
227
- let shapedAgain = MLShapedArray<Float>(multiArray)
200
+ func tensor(from array: MLMultiArray) -> MLTensor {
201
+ MLTensor(MLShapedArray<Float>(array))
202
+ }
228
203
  ```
229
204
 
230
- Do not invent `MLTensor` APIs for statistics or bridging. Avoid examples such as
231
- `MLTensor(multiArray)`, `tensor.std()`, `tensor.standardDeviation()`, direct
232
- lazy-buffer access, or synchronous extraction; perform unsupported DSP/statistics
233
- outside the tensor pipeline or with source-confirmed tensor operations.
205
+ Stay with documented operations. There is no `MLTensor(multiArray)`
206
+ initializer, no `std()` or `standardDeviation()`, no direct access to the lazy
207
+ storage, and no synchronous extraction. Go through `MLShapedArray` for
208
+ conversions, and build statistics from documented pieces (`mean()`,
209
+ `squareRoot()`, arithmetic) or do them outside the tensor pipeline.
210
+ `MLTensor(zeros:scalarType:)` and `MLTensor(ones:scalarType:)` create filled
211
+ tensors.
234
212
 
235
- ## Working with MLMultiArray
213
+ ## MLMultiArray
236
214
 
237
- `MLMultiArray` is the primary data exchange type for non-image model inputs and
238
- outputs. Use it when the auto-generated class expects array-type features.
215
+ `MLMultiArray` is the exchange type for non-image inputs and outputs; generated
216
+ classes use it for array features.
239
217
 
240
218
  ```swift
241
- // Create a 3D array: [batch, sequence, features]
242
- let array = try MLMultiArray(shape: [1, 128, 768], dataType: .float32)
219
+ import CoreML
243
220
 
244
- // Write values
245
- for i in 0..<128 {
246
- array[[0, i, 0] as [NSNumber]] = NSNumber(value: Float(i))
221
+ func embeddingInput(tokens: Int, width: Int) throws -> MLMultiArray {
222
+ let grid = try MLMultiArray(shape: [1, NSNumber(value: tokens), NSNumber(value: width)], dataType: .float32)
223
+ grid[[0, 0, 0] as [NSNumber]] = 0.25
224
+ return grid
247
225
  }
248
226
 
249
- // Read values
250
- let value = array[[0, 0, 0] as [NSNumber]].floatValue
227
+ func firstValue(of grid: MLMultiArray) -> Float {
228
+ grid[[0, 0, 0] as [NSNumber]].floatValue
229
+ }
251
230
 
252
- let data: [Float] = [1.0, 2.0, 3.0]
253
- let shaped = MLShapedArray(scalars: data, shape: [3])
254
- let fromShaped = try MLMultiArray(shaped)
231
+ func packed(_ values: [Float]) -> MLMultiArray {
232
+ MLMultiArray(MLShapedArray<Float>(scalars: values, shape: [1, values.count]))
233
+ }
255
234
  ```
256
235
 
257
- See [references/coreml-swift-integration.md](references/coreml-swift-integration.md) for advanced MLMultiArray patterns
258
- including NLP tokenization and audio feature extraction.
236
+ The shape reads batch, sequence, features. Tokenized text and audio feature
237
+ patterns are in the reference.
259
238
 
260
- ## Image Preprocessing
239
+ ## Image input
261
240
 
262
- Image models expect `CVPixelBuffer` input. Use `CGImage` conversion for photos
263
- from the camera or photo library. Vision's `VNCoreMLRequest` handles this
264
- automatically; manual conversion is needed only for direct `MLModel` prediction.
241
+ Image models take a `CVPixelBuffer`. When Vision drives the model
242
+ (`CoreMLRequest` or `VNCoreMLRequest`), conversion happens automatically; the
243
+ manual path is only for direct `MLModel` predictions.
265
244
 
266
245
  ```swift
246
+ import CoreGraphics
267
247
  import CoreVideo
268
248
 
269
- func createPixelBuffer(from cgImage: CGImage, width: Int, height: Int) -> CVPixelBuffer? {
270
- var pixelBuffer: CVPixelBuffer?
271
- let attrs: [CFString: Any] = [
249
+ func pixelBuffer(from picture: CGImage, side: Int) -> CVPixelBuffer? {
250
+ let options = [
272
251
  kCVPixelBufferCGImageCompatibilityKey: true,
273
- kCVPixelBufferCGBitmapContextCompatibilityKey: true,
274
- ]
275
- CVPixelBufferCreate(kCFAllocatorDefault, width, height,
276
- kCVPixelFormatType_32ARGB, attrs as CFDictionary, &pixelBuffer)
277
-
278
- guard let buffer = pixelBuffer else { return nil }
252
+ kCVPixelBufferCGBitmapContextCompatibilityKey: true
253
+ ] as CFDictionary
254
+ var buffer: CVPixelBuffer?
255
+ guard CVPixelBufferCreate(kCFAllocatorDefault, side, side, kCVPixelFormatType_32ARGB, options, &buffer) == kCVReturnSuccess,
256
+ let buffer else { return nil }
279
257
  CVPixelBufferLockBaseAddress(buffer, [])
258
+ defer { CVPixelBufferUnlockBaseAddress(buffer, []) }
280
259
  let context = CGContext(
281
- data: CVPixelBufferGetBaseAddress(buffer),
282
- width: width, height: height,
260
+ data: CVPixelBufferGetBaseAddress(buffer), width: side, height: side,
283
261
  bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(buffer),
284
- space: CGColorSpaceCreateDeviceRGB(),
285
- bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue
262
+ space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue
286
263
  )
287
- context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
288
- CVPixelBufferUnlockBaseAddress(buffer, [])
264
+ context?.draw(picture, in: CGRect(x: 0, y: 0, width: side, height: side))
289
265
  return buffer
290
266
  }
291
267
  ```
292
268
 
293
- For additional preprocessing patterns (normalization, center-cropping), see
294
- [references/coreml-swift-integration.md](references/coreml-swift-integration.md).
269
+ Normalization and center-crop helpers are in the reference.
295
270
 
296
- ## Multi-Model Pipelines
271
+ ## Chaining models
297
272
 
298
- Chain models when preprocessing or postprocessing requires a separate model.
273
+ When pre- or post-processing is its own model, call them in order:
299
274
 
300
275
  ```swift
301
- // Sequential inference: preprocessor -> main model -> postprocessor
302
- let preprocessed = try preprocessor.prediction(from: rawInput)
303
- let mainOutput = try mainModel.prediction(from: preprocessed)
304
- let finalOutput = try postprocessor.prediction(from: mainOutput)
305
- ```
276
+ import CoreML
306
277
 
307
- For Xcode-managed pipelines, use the pipeline model type in the `.mlpackage`.
308
- Each sub-model runs on its optimal compute unit.
278
+ func runChain(_ input: MLFeatureProvider, stages: [MLModel]) async throws -> MLFeatureProvider {
279
+ var current = input
280
+ for stage in stages {
281
+ current = try await stage.prediction(from: current)
282
+ }
283
+ return current
284
+ }
285
+ ```
309
286
 
310
- ## Vision Integration
287
+ For chains that Xcode manages, build a pipeline model inside the `.mlpackage`;
288
+ each sub-model then runs on the compute unit that suits it.
311
289
 
312
- Use Vision to run Core ML image models with automatic image preprocessing
313
- (resizing, normalization, color space, orientation).
290
+ ## Through Vision
314
291
 
315
- ### Modern: CoreMLRequest (iOS 18+)
292
+ Vision takes care of resizing, cropping, normalization, color space and
293
+ orientation.
316
294
 
317
295
  ```swift
318
- import Vision
319
296
  import CoreML
297
+ import Vision
320
298
 
321
- let model = try MLModel(contentsOf: modelURL, configuration: config)
322
- let request = CoreMLRequest(model: .init(model))
323
- let results = try await request.perform(on: cgImage)
324
-
325
- if let classification = results.first as? ClassificationObservation {
326
- print("\(classification.identifier): \(classification.confidence)")
299
+ func dominantLabel(in photo: CGImage, model: MLModel) async throws -> (String, Float)? {
300
+ let request = CoreMLRequest(model: try CoreMLModelContainer(model: model))
301
+ let observations = try await request.perform(on: photo)
302
+ guard let top = observations.first as? ClassificationObservation else { return nil }
303
+ return (top.identifier, top.confidence)
327
304
  }
328
305
  ```
329
306
 
330
- ### Legacy: VNCoreMLRequest
307
+ `CoreMLRequest` needs iOS 18. The legacy route for detection models:
331
308
 
332
309
  ```swift
333
- let vnModel = try VNCoreMLModel(for: model)
334
- let request = VNCoreMLRequest(model: vnModel) { request, error in
335
- guard let results = request.results as? [VNRecognizedObjectObservation] else { return }
336
- for observation in results {
337
- let label = observation.labels.first?.identifier ?? "unknown"
338
- let confidence = observation.labels.first?.confidence ?? 0
339
- let boundingBox = observation.boundingBox // normalized coordinates
340
- print("\(label): \(confidence) at \(boundingBox)")
310
+ import CoreML
311
+ import Vision
312
+
313
+ func legacyDetections(in frame: CVPixelBuffer, model: MLModel) throws -> [(String, Float, CGRect)] {
314
+ let request = VNCoreMLRequest(model: try VNCoreMLModel(for: model))
315
+ request.imageCropAndScaleOption = .scaleFill
316
+ try VNImageRequestHandler(cvPixelBuffer: frame).perform([request])
317
+ let objects = request.results as? [VNRecognizedObjectObservation] ?? []
318
+ return objects.compactMap { object in
319
+ guard let label = object.labels.first else { return nil }
320
+ return (label.identifier, label.confidence, object.boundingBox)
341
321
  }
342
322
  }
343
- request.imageCropAndScaleOption = .scaleFill
344
-
345
- let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer)
346
- try handler.perform([request])
347
323
  ```
348
324
 
349
- > For complete Vision framework patterns (text recognition, barcode detection,
350
- > document scanning), see the `vision-framework` skill.
351
-
352
- ## Performance Profiling
325
+ `boundingBox` is normalized. Everything else about Vision (OCR, barcodes,
326
+ documents) is in `vision-framework`.
353
327
 
354
- ### MLComputePlan (iOS 17.4+)
328
+ ## Profiling
355
329
 
356
- Inspect which compute device each operation will use before running predictions.
330
+ `MLComputePlan` (iOS 17.4+) tells you, before any prediction, which device
331
+ each operation prefers and how expensive it is:
357
332
 
358
333
  ```swift
359
- let computePlan = try await MLComputePlan.load(
360
- contentsOf: modelURL, configuration: config
361
- )
362
- guard case let .program(program) = computePlan.modelStructure else { return }
363
- guard let mainFunction = program.functions["main"] else { return }
364
-
365
- for operation in mainFunction.block.operations {
366
- let deviceUsage = computePlan.deviceUsage(for: operation)
367
- let estimatedCost = computePlan.estimatedCost(of: operation)
368
- print("\(operation.operatorName): \(String(describing: deviceUsage?.preferred))")
334
+ import CoreML
335
+
336
+ func opsOffAccelerators(modelURL: URL) async throws -> [String] {
337
+ let plan = try await MLComputePlan.load(contentsOf: modelURL, configuration: MLModelConfiguration())
338
+ guard case .program(let program) = plan.modelStructure,
339
+ let entry = program.functions["main"] else { return [] }
340
+ return entry.block.operations.compactMap { op in
341
+ guard let usage = plan.deviceUsage(for: op), case .cpu = usage.preferred else { return nil }
342
+ let cost = plan.estimatedCost(of: op)?.weight ?? 0
343
+ return "\(op.operatorName) cost \(cost)"
344
+ }
369
345
  }
370
346
  ```
371
347
 
372
- ### Instruments
373
-
374
- Use the **Core ML** instrument template in Instruments to profile:
375
- - Model load time
376
- - Prediction latency (per-operation breakdown)
377
- - Compute device dispatch (CPU/GPU/ANE per operation)
378
- - Memory allocation
379
-
380
- Run outside the debugger for accurate results (Xcode: Product > Profile).
381
-
382
- ## Model Deployment
348
+ The Instruments Core ML template shows load time, per-prediction latency with a
349
+ per-operation breakdown, which device each operation ran on, and memory.
350
+ Profile with Product > Profile, not under the debugger, or the numbers are
351
+ not representative.
383
352
 
384
- ### Bundle vs Downloaded Assets
353
+ ## Deployment
385
354
 
386
- | Strategy | Pros | Cons |
355
+ | Strategy | Strength | Cost |
387
356
  |---|---|---|
388
- | Bundle in app | Instant availability, works offline | Increases app download size |
389
- | Background Assets | Preferred for large or updateable model assets | Requires asset-pack setup |
390
- | On-demand resources | Smaller initial download for existing ODR apps | Legacy technology; prefer Background Assets for new work |
391
- | CloudKit / server | Maximum flexibility | Requires network, longer setup |
392
-
393
- ### Size Considerations
394
-
395
- - For iOS/iPadOS 18+, App Store Connect lists a 4 GB thinned app bundle limit
396
- and 8 GB thinned ODR asset-pack limit.
397
- - Prefer Background Assets for new large or updateable model assets; keep ODR
398
- guidance for existing projects that already use it.
399
- - Pre-compile to `.mlmodelc` to skip on-device compilation
400
- - For downloaded `.mlmodel` or `.mlpackage` files, compile once with
401
- `MLModel.compileModel(at:)`, move the resulting `.mlmodelc` out of Core ML's
402
- temporary location, and cache it by model version.
403
- - Validate memory and performance on physical target devices, especially the
404
- lowest-memory supported device. Check model load, first prediction, repeated
405
- predictions, background/foreground transitions, and low-memory behavior.
406
-
407
- For Background Assets, make the asset pack locally available, resolve the model
408
- URL, then load the compiled model with `MLModel.load(contentsOf:configuration:)`.
357
+ | In the app bundle | Available instantly and offline | Bigger download |
358
+ | Background Assets | Preferred for large or updatable models | Asset pack setup |
359
+ | On-demand resources | Smaller first download for apps already on ODR | Legacy; choose Background Assets for new work |
360
+ | CloudKit or own server | Most flexible | Needs network, more plumbing |
361
+
362
+ - Size ceilings change; check the current App Store Connect limits. For
363
+ iOS/iPadOS 18 and later they list 4 GB for the thinned app bundle and 8 GB
364
+ per thinned on-demand-resource asset pack.
365
+ - Keep on-demand-resource guidance for projects that already use it.
366
+ - Ship `.mlmodelc` (precompiled) so the device does not compile at first use.
367
+ - For downloaded `.mlmodel`/`.mlpackage` files: compile once with
368
+ `compileModel(at:)`, move the result out of Core ML's temporary directory,
369
+ and key the cache by model version.
370
+ - With Background Assets: make the asset pack locally available, resolve the
371
+ model's URL inside it, then `MLModel.load(contentsOf:configuration:)`.
372
+ - Test on physical devices, above all the lowest-memory one you support: load
373
+ time, first prediction, repeated predictions, background and foreground
374
+ transitions, and low-memory behavior.
375
+
376
+ On-demand resources, for apps that already use them:
409
377
 
410
378
  ```swift
411
- // Existing On-Demand Resources project
412
- let request = NSBundleResourceRequest(tags: ["ml-model-v2"])
413
- try await request.beginAccessingResources()
414
- let modelURL = Bundle.main.url(forResource: "LargeModel", withExtension: "mlmodelc")!
415
- let model = try await MLModel.load(contentsOf: modelURL, configuration: config)
416
- // Call request.endAccessingResources() when done
379
+ import CoreML
380
+
381
+ func loadTaggedModel(tag: String, name: String) async throws -> (MLModel, NSBundleResourceRequest) {
382
+ let request = NSBundleResourceRequest(tags: [tag])
383
+ try await request.beginAccessingResources()
384
+ guard let url = Bundle.main.url(forResource: name, withExtension: "mlmodelc") else {
385
+ request.endAccessingResources()
386
+ throw CocoaError(.fileNoSuchFile)
387
+ }
388
+ let model = try await MLModel.load(contentsOf: url, configuration: MLModelConfiguration())
389
+ return (model, request)
390
+ }
417
391
  ```
418
392
 
419
- ## Memory Management
420
-
421
- - **Unload on background:** Release model references when the app enters background
422
- to free GPU/ANE memory. Reload on foreground return.
423
- - **Choose compute units by context:** use `.all` by default. Consider `.cpuOnly`
424
- only when profiling or app policy shows accelerator contention, thermal state,
425
- energy budget, deterministic testing, or a legitimate background execution
426
- constraint makes CPU the right tradeoff.
427
- - **Share model instances:** Never create multiple `MLModel` instances from the same
428
- compiled model. Use an actor to provide shared access.
429
- - **Monitor memory pressure:** Large models (>100 MB) can trigger memory warnings.
430
- Register for `UIApplication.didReceiveMemoryWarningNotification` and release
431
- cached models when under pressure.
432
-
433
- See [references/coreml-swift-integration.md](references/coreml-swift-integration.md) for an actor-based model manager with
434
- lifecycle-aware loading and cache eviction.
435
-
436
- ## Common Mistakes
437
-
438
- **DON'T:** Load models on the main thread.
439
- **DO:** Use `MLModel.load(contentsOf:configuration:)` async API or load on a background actor.
440
- **Why:** Large models can take seconds to load, freezing the UI.
441
-
442
- **DON'T:** Recompile `.mlpackage` to `.mlmodelc` on every app launch.
443
- **DO:** Compile once with `MLModel.compileModel(at:)` and cache the compiled URL persistently.
444
- **Why:** Compilation is expensive. Cache the `.mlmodelc` in Application Support.
445
-
446
- **DON'T:** Hardcode `.cpuOnly` unless you have a specific reason.
447
- **DO:** Use `.all` and let the system choose the optimal compute unit.
448
- **Why:** `.all` enables Neural Engine and GPU, which are faster and more energy-efficient.
449
-
450
- **DON'T:** Claim GPU or Neural Engine are categorically unavailable for all
451
- background-adjacent work.
452
- **DO:** Treat background execution as policy-, mode-, contention-, thermal-, and
453
- energy-dependent, and profile the actual workload on device.
454
- **Why:** Apps may be suspended, throttled, or limited by their background mode;
455
- `.cpuOnly` is a tradeoff, not a universal requirement.
456
-
457
- **DON'T:** Ignore `MLFeatureValue` type mismatches between input and model expectations.
458
- **DO:** Match types exactly -- use `MLFeatureValue(pixelBuffer:)` for images, not raw data.
459
- **Why:** Type mismatches cause cryptic runtime crashes or silent incorrect results.
460
-
461
- **DON'T:** Create a new `MLModel` instance for every prediction.
462
- **DO:** Load once and reuse. Use an actor to manage the model lifecycle.
463
- **Why:** Model loading allocates significant memory and compute resources.
464
-
465
- **DON'T:** Skip error handling for model loading and prediction.
466
- **DO:** Catch errors and provide fallback behavior when the model fails.
467
- **Why:** Models can fail to load on older devices or when resources are constrained.
468
-
469
- **DON'T:** Assume all operations run on the Neural Engine.
470
- **DO:** Use `MLComputePlan` (iOS 17.4+) to verify device dispatch per operation.
471
- **Why:** Unsupported operations fall back to CPU, which may bottleneck the pipeline.
472
-
473
- **DON'T:** Process images manually before passing to Vision + Core ML.
474
- **DO:** Use `CoreMLRequest` (iOS 18+) or `VNCoreMLRequest` (legacy) to let Vision handle preprocessing.
475
- **Why:** Vision handles orientation, scaling, and pixel format conversion correctly.
476
-
477
- ## Review Checklist
478
-
479
- - [ ] Model loaded asynchronously (not blocking main thread)
480
- - [ ] `MLModelConfiguration.computeUnits` set appropriately for use case
481
- - [ ] Model instance reused across predictions (not recreated each time)
482
- - [ ] Auto-generated class used when available (typed inputs/outputs)
483
- - [ ] Error handling for model loading and prediction failures
484
- - [ ] Compiled model cached persistently if compiled at runtime
485
- - [ ] Image inputs use Vision pipeline (`CoreMLRequest` iOS 18+ or `VNCoreMLRequest`) for correct preprocessing
486
- - [ ] `MLComputePlan` checked to verify compute device dispatch (iOS 17.4+)
487
- - [ ] Batch predictions used when processing multiple inputs
488
- - [ ] Model size appropriate for deployment strategy (bundle, Background Assets, ODR)
489
- - [ ] Memory tested on target devices (especially older devices with less RAM)
490
- - [ ] Predictions run outside debugger for accurate performance measurement
393
+ Keep the returned request alive while the model is in use and call
394
+ `endAccessingResources()` when you are done with it.
395
+
396
+ ## Memory
397
+
398
+ - Drop model references when the app goes to the background to release GPU
399
+ and Neural Engine memory; load again on return to the foreground.
400
+ - `.all` is the default. Use `.cpuOnly` only when profiling or policy points
401
+ to contention, thermal limits, energy, deterministic tests or a real
402
+ background-execution constraint.
403
+ - Keep one `MLModel` per compiled model and share it through an actor.
404
+ - Models above roughly 100 MB can trigger memory warnings; listen for
405
+ `UIApplication.didReceiveMemoryWarningNotification` and release cached
406
+ models.
407
+
408
+ ## Common mistakes
409
+
410
+ 1. **Loading on the main thread.** Large models take seconds; use
411
+ `MLModel.load(contentsOf:configuration:)` or a background actor.
412
+ 2. **Recompiling every launch.** Compilation is expensive; compile once and
413
+ keep the `.mlmodelc` in Application Support.
414
+ 3. **Hard-coding `.cpuOnly`.** `.all` lets Core ML use the Neural Engine and
415
+ GPU, usually faster and more efficient.
416
+ 4. **Declaring GPU or Neural Engine off-limits for anything near the
417
+ background.** Access depends on system policy, execution mode, contention,
418
+ thermal state and energy; profile on a device. `.cpuOnly` is a tradeoff,
419
+ not a rule, and a backgrounded app may be suspended or throttled anyway.
420
+ 5. **Feature type mismatches.** Images go in as `MLFeatureValue(pixelBuffer:)`,
421
+ not raw bytes; mismatches crash obscurely or give silently wrong output.
422
+ 6. **A new `MLModel` per prediction.** Loading costs memory and time; load once
423
+ and reuse through an actor.
424
+ 7. **No error handling.** Loading and prediction can fail on older or
425
+ constrained devices; catch and fall back.
426
+ 8. **Assuming everything runs on the Neural Engine.** Unsupported operations
427
+ fall back to the CPU and can dominate latency; check with `MLComputePlan`.
428
+ 9. **Hand-preprocessing images for Vision.** `CoreMLRequest` (iOS 18) and
429
+ `VNCoreMLRequest` already handle orientation, scaling and pixel format.
430
+ 10. **Dropping `await` on prediction in async code.** On iOS 17 and later the
431
+ async overload is selected there; write `try await`.
432
+
433
+ ## Review checklist
434
+
435
+ - [ ] Model loaded asynchronously
436
+ - [ ] `computeUnits` chosen deliberately
437
+ - [ ] One model instance reused across predictions
438
+ - [ ] Generated class used where Xcode provides one
439
+ - [ ] Load and prediction failures handled
440
+ - [ ] Runtime-compiled models cached in a durable location
441
+ - [ ] Image inputs routed through Vision (`CoreMLRequest` on iOS 18+, otherwise `VNCoreMLRequest`)
442
+ - [ ] Device dispatch checked with `MLComputePlan` (iOS 17.4+)
443
+ - [ ] Batch API used for many inputs
444
+ - [ ] Model size matches the delivery strategy (bundle, Background Assets, ODR)
445
+ - [ ] Memory measured on target devices, especially older low-RAM ones
446
+ - [ ] Latency measured outside the debugger
491
447
 
492
448
  ## References
493
449
 
494
- - Patterns and code: [references/coreml-swift-integration.md](references/coreml-swift-integration.md)
495
- - Model conversion and optimization (Python-side): covered in the `apple-on-device-ai` skill
496
- - Apple docs: [Core ML](https://sosumi.ai/documentation/coreml) |
497
- [MLModel](https://sosumi.ai/documentation/coreml/mlmodel) |
498
- [MLTensor](https://sosumi.ai/documentation/coreml/mltensor) |
499
- [MLComputePlan](https://sosumi.ai/documentation/coreml/mlcomputeplan-1w21n) |
500
- [Background Assets](https://sosumi.ai/documentation/backgroundassets)
450
+ - `references/coreml-swift-integration.md`
451
+ - `apple-on-device-ai` for conversion and compression in Python
452
+ - https://developer.apple.com/documentation/coreml
453
+ - https://developer.apple.com/documentation/coreml/mlmodel
454
+ - https://developer.apple.com/documentation/coreml/mltensor
455
+ - https://developer.apple.com/documentation/coreml/mlcomputeplan-1w21n
456
+ - https://developer.apple.com/documentation/backgroundassets