buildanything 1.7.1 → 1.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 (221) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +55 -0
  4. package/agents/ios-app-review-guardian.md +49 -0
  5. package/agents/ios-foundation-models-specialist.md +46 -0
  6. package/agents/ios-storekit-specialist.md +52 -0
  7. package/agents/ios-swift-architect.md +102 -0
  8. package/agents/ios-swift-search.md +130 -0
  9. package/agents/ios-swift-ui-design.md +104 -0
  10. package/commands/build.md +80 -176
  11. package/commands/fix.md +65 -0
  12. package/commands/setup.md +73 -0
  13. package/commands/ux-review.md +63 -0
  14. package/commands/verify.md +72 -0
  15. package/hooks/session-start +18 -1
  16. package/package.json +5 -2
  17. package/protocols/brainstorm.md +99 -0
  18. package/protocols/build-fix.md +52 -0
  19. package/protocols/cleanup.md +54 -0
  20. package/protocols/design.md +269 -0
  21. package/protocols/eval-harness.md +61 -0
  22. package/protocols/fake-data-detector.md +64 -0
  23. package/protocols/ios-context.md +235 -0
  24. package/protocols/ios-frameworks-map.md +323 -0
  25. package/protocols/ios-phase-branches.md +162 -0
  26. package/protocols/ios-preflight.md +27 -0
  27. package/protocols/metric-loop.md +93 -0
  28. package/protocols/planning.md +87 -0
  29. package/protocols/smoke-test.md +110 -0
  30. package/protocols/verify.md +67 -0
  31. package/protocols/web-phase-branches.md +201 -0
  32. package/skills/ios/_VENDORED.md +60 -0
  33. package/skills/ios/activitykit/LICENSE +131 -0
  34. package/skills/ios/activitykit/SKILL.md +505 -0
  35. package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
  36. package/skills/ios/app-intents/LICENSE +131 -0
  37. package/skills/ios/app-intents/SKILL.md +494 -0
  38. package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
  39. package/skills/ios/apple-on-device-ai/LICENSE +131 -0
  40. package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
  41. package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
  42. package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
  43. package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
  44. package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
  45. package/skills/ios/ios-26-platform/SKILL.md +53 -0
  46. package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
  47. package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
  48. package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
  49. package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
  50. package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
  51. package/skills/ios/ios-bootstrap/SKILL.md +98 -0
  52. package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
  53. package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
  54. package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
  55. package/skills/ios/ios-debugger-agent/LICENSE +21 -0
  56. package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
  57. package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
  58. package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
  59. package/skills/ios/ios-hig/SKILL.md +41 -0
  60. package/skills/ios/ios-hig/references/accessibility.md +81 -0
  61. package/skills/ios/ios-hig/references/content.md +142 -0
  62. package/skills/ios/ios-hig/references/feedback.md +123 -0
  63. package/skills/ios/ios-hig/references/interaction.md +199 -0
  64. package/skills/ios/ios-hig/references/performance-platform.md +129 -0
  65. package/skills/ios/ios-hig/references/privacy-permissions.md +181 -0
  66. package/skills/ios/ios-hig/references/visual-design.md +84 -0
  67. package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
  68. package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
  69. package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
  70. package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
  71. package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
  72. package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
  73. package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
  74. package/skills/ios/swift-accessibility/LICENSE +21 -0
  75. package/skills/ios/swift-accessibility/SKILL.md +371 -0
  76. package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
  77. package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
  78. package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
  79. package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
  80. package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
  81. package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
  82. package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
  83. package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
  84. package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
  85. package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
  86. package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
  87. package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
  88. package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
  89. package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
  90. package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
  91. package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
  92. package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
  93. package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
  94. package/skills/ios/swift-concurrency/LICENSE +21 -0
  95. package/skills/ios/swift-concurrency/SKILL.md +171 -0
  96. package/skills/ios/swift-concurrency/references/_index.md +50 -0
  97. package/skills/ios/swift-concurrency/references/actors.md +660 -0
  98. package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
  99. package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
  100. package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
  101. package/skills/ios/swift-concurrency/references/core-data.md +560 -0
  102. package/skills/ios/swift-concurrency/references/glossary.md +135 -0
  103. package/skills/ios/swift-concurrency/references/linting.md +155 -0
  104. package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
  105. package/skills/ios/swift-concurrency/references/migration.md +1104 -0
  106. package/skills/ios/swift-concurrency/references/performance.md +593 -0
  107. package/skills/ios/swift-concurrency/references/sendable.md +598 -0
  108. package/skills/ios/swift-concurrency/references/tasks.md +636 -0
  109. package/skills/ios/swift-concurrency/references/testing.md +592 -0
  110. package/skills/ios/swift-concurrency/references/threading.md +495 -0
  111. package/skills/ios/swift-security-expert/LICENSE +21 -0
  112. package/skills/ios/swift-security-expert/SKILL.md +470 -0
  113. package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
  114. package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
  115. package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
  116. package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
  117. package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
  118. package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
  119. package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
  120. package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
  121. package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
  122. package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
  123. package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
  124. package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
  125. package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
  126. package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
  127. package/skills/ios/swift-testing-expert/LICENSE +21 -0
  128. package/skills/ios/swift-testing-expert/SKILL.md +79 -0
  129. package/skills/ios/swift-testing-expert/references/_index.md +12 -0
  130. package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
  131. package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
  132. package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
  133. package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
  134. package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
  135. package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
  136. package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
  137. package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
  138. package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
  139. package/skills/ios/swiftdata-pro/LICENSE +21 -0
  140. package/skills/ios/swiftdata-pro/SKILL.md +102 -0
  141. package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
  142. package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
  143. package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
  144. package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
  145. package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
  146. package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
  147. package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
  148. package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
  149. package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
  150. package/skills/ios/swiftui-design-principles/LICENSE +21 -0
  151. package/skills/ios/swiftui-design-principles/README.md +41 -0
  152. package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
  153. package/skills/ios/swiftui-design-principles/metadata.json +10 -0
  154. package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
  155. package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
  156. package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
  157. package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
  158. package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
  159. package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
  160. package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
  161. package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
  162. package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
  163. package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
  164. package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
  165. package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
  166. package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
  167. package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
  168. package/skills/ios/swiftui-pro/LICENSE +21 -0
  169. package/skills/ios/swiftui-pro/SKILL.md +108 -0
  170. package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
  171. package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  172. package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  173. package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
  174. package/skills/ios/swiftui-pro/references/api.md +39 -0
  175. package/skills/ios/swiftui-pro/references/data.md +43 -0
  176. package/skills/ios/swiftui-pro/references/design.md +31 -0
  177. package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
  178. package/skills/ios/swiftui-pro/references/navigation.md +14 -0
  179. package/skills/ios/swiftui-pro/references/performance.md +46 -0
  180. package/skills/ios/swiftui-pro/references/swift.md +56 -0
  181. package/skills/ios/swiftui-pro/references/views.md +35 -0
  182. package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
  183. package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
  184. package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
  185. package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
  186. package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
  187. package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
  188. package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
  189. package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
  190. package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
  191. package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
  192. package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
  193. package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
  194. package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  195. package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  196. package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
  197. package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  198. package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
  199. package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  200. package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
  201. package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
  202. package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
  203. package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
  204. package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
  205. package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
  206. package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  207. package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
  208. package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
  209. package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
  210. package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
  211. package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
  212. package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
  213. package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
  214. package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
  215. package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
  216. package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
  217. package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
  218. package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
  219. package/skills/ios/widgetkit/LICENSE +131 -0
  220. package/skills/ios/widgetkit/SKILL.md +502 -0
  221. package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
@@ -0,0 +1,131 @@
1
+ Required Notice: Copyright (c) 2025 dpearson2699 (https://github.com/dpearson2699)
2
+
3
+ # PolyForm Perimeter License 1.0.0
4
+
5
+ <https://polyformproject.org/licenses/perimeter/1.0.0>
6
+
7
+ ## Acceptance
8
+
9
+ In order to get any license under these terms, you must agree
10
+ to them as both strict obligations and conditions to all
11
+ your licenses.
12
+
13
+ ## Copyright License
14
+
15
+ The licensor grants you a copyright license for the
16
+ software to do everything you might do with the software
17
+ that would otherwise infringe the licensor's copyright
18
+ in it for any permitted purpose. However, you may
19
+ only distribute the software according to [Distribution
20
+ License](#distribution-license) and make changes or new works
21
+ based on the software according to [Changes and New Works
22
+ License](#changes-and-new-works-license).
23
+
24
+ ## Distribution License
25
+
26
+ The licensor grants you an additional copyright license
27
+ to distribute copies of the software. Your license
28
+ to distribute covers distributing the software with
29
+ changes and new works permitted by [Changes and New Works
30
+ License](#changes-and-new-works-license).
31
+
32
+ ## Notices
33
+
34
+ You must ensure that anyone who gets a copy of any part of
35
+ the software from you also gets a copy of these terms or the
36
+ URL for them above, as well as copies of any plain-text lines
37
+ beginning with `Required Notice:` that the licensor provided
38
+ with the software. For example:
39
+
40
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
41
+
42
+ ## Changes and New Works License
43
+
44
+ The licensor grants you an additional copyright license to
45
+ make changes and new works based on the software for any
46
+ permitted purpose.
47
+
48
+ ## Patent License
49
+
50
+ The licensor grants you a patent license for the software that
51
+ covers patent claims the licensor can license, or becomes able
52
+ to license, that you would infringe by using the software.
53
+
54
+ ## Noncompete
55
+
56
+ Any purpose is a permitted purpose, except for providing to
57
+ others any product that competes with the software.
58
+
59
+ ## Competition
60
+
61
+ If you use this software to market a product as a substitute
62
+ for the functionality or value of the software, it competes
63
+ with the software. A product may compete regardless how it is
64
+ designed or deployed. For example, a product may compete even
65
+ if it provides its functionality via any kind of interface
66
+ (including services, libraries or plug-ins), even if it is
67
+ ported to a different platforms or programming languages,
68
+ and even if it is provided free of charge.
69
+
70
+ ## Fair Use
71
+
72
+ You may have "fair use" rights for the software under the
73
+ law. These terms do not limit them.
74
+
75
+ ## No Other Rights
76
+
77
+ These terms do not allow you to sublicense or transfer any of
78
+ your licenses to anyone else, or prevent the licensor from
79
+ granting licenses to anyone else. These terms do not imply
80
+ any other licenses.
81
+
82
+ ## Patent Defense
83
+
84
+ If you make any written claim that the software infringes or
85
+ contributes to infringement of any patent, your patent license
86
+ for the software granted under these terms ends immediately. If
87
+ your company makes such a claim, your patent license ends
88
+ immediately for work on behalf of your company.
89
+
90
+ ## Violations
91
+
92
+ The first time you are notified in writing that you have
93
+ violated any of these terms, or done anything with the software
94
+ not covered by your licenses, your licenses can nonetheless
95
+ continue if you come into full compliance with these terms,
96
+ and take practical steps to correct past violations, within
97
+ 32 days of receiving notice. Otherwise, all your licenses
98
+ end immediately.
99
+
100
+ ## No Liability
101
+
102
+ ***As far as the law allows, the software comes as is, without
103
+ any warranty or condition, and the licensor will not be liable
104
+ to you for any damages arising out of these terms or the use
105
+ or nature of the software, under any kind of legal claim.***
106
+
107
+ ## Definitions
108
+
109
+ The **licensor** is the individual or entity offering these
110
+ terms, and the **software** is the software the licensor makes
111
+ available under these terms.
112
+
113
+ A **product** can be a good or service, or a combination
114
+ of them.
115
+
116
+ **You** refers to the individual or entity agreeing to these
117
+ terms.
118
+
119
+ **Your company** is any legal entity, sole proprietorship,
120
+ or other kind of organization that you work for, plus all
121
+ organizations that have control over, are under the control of,
122
+ or are under common control with that organization. **Control**
123
+ means ownership of substantially all the assets of an entity,
124
+ or the power to direct its management and policies by vote,
125
+ contract, or otherwise. Control can be direct or indirect.
126
+
127
+ **Your licenses** are all the licenses granted to you for the
128
+ software under these terms.
129
+
130
+ **Use** means anything you do with the software requiring one
131
+ of your licenses.
@@ -0,0 +1,505 @@
1
+ ---
2
+ name: activitykit
3
+ description: "Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media playback, or any time-sensitive information that updates in real time. Also use when working with ActivityKit, ActivityAttributes, Activity lifecycle (request/update/end), Dynamic Island layouts (compact/minimal/expanded), push-to-update Live Activities, or Lock Screen live widgets."
4
+ ---
5
+
6
+ # ActivityKit
7
+
8
+ Build real-time, glanceable experiences on the Lock Screen, Dynamic Island,
9
+ StandBy, CarPlay, and a paired Mac using ActivityKit. Patterns target iOS 26+
10
+ with Swift 6.3, backward-compatible to iOS 16.1 unless noted.
11
+
12
+ See [references/activitykit-patterns.md](references/activitykit-patterns.md) for complete code patterns including push payload formats, concurrent activities, state observation, and testing.
13
+
14
+ ## Contents
15
+
16
+ - [Workflow](#workflow)
17
+ - [ActivityAttributes Definition](#activityattributes-definition)
18
+ - [Activity Lifecycle](#activity-lifecycle)
19
+ - [Lock Screen Presentation](#lock-screen-presentation)
20
+ - [Dynamic Island](#dynamic-island)
21
+ - [Push-to-Update](#push-to-update)
22
+ - [iOS 26 Additions](#ios-26-additions)
23
+ - [Common Mistakes](#common-mistakes)
24
+ - [Review Checklist](#review-checklist)
25
+ - [References](#references)
26
+
27
+ ## Workflow
28
+
29
+ ### 1. Create a new Live Activity
30
+
31
+ 1. Add `NSSupportsLiveActivities = YES` to the host app's Info.plist.
32
+ 2. Define an `ActivityAttributes` struct with a nested `ContentState`.
33
+ 3. Create an `ActivityConfiguration` in the widget bundle with Lock Screen
34
+ content and Dynamic Island closures.
35
+ 4. Start the activity with `Activity.request(attributes:content:pushType:)`.
36
+ 5. Update with `activity.update(_:)` and end with `activity.end(_:dismissalPolicy:)`.
37
+ 6. Forward push tokens to your server for remote updates.
38
+
39
+ ### 2. Review existing Live Activity code
40
+
41
+ Run through the Review Checklist at the end of this document.
42
+
43
+ ## ActivityAttributes Definition
44
+
45
+ Define both static data (immutable for the activity lifetime) and dynamic
46
+ `ContentState` (changes with each update). Keep `ContentState` small because
47
+ the entire struct is serialized on every update and push payload.
48
+
49
+ ```swift
50
+ import ActivityKit
51
+
52
+ struct DeliveryAttributes: ActivityAttributes {
53
+ // Static -- set once at activity creation, never changes
54
+ var orderNumber: Int
55
+ var restaurantName: String
56
+
57
+ // Dynamic -- updated throughout the activity lifetime
58
+ struct ContentState: Codable, Hashable {
59
+ var driverName: String
60
+ var estimatedDeliveryTime: ClosedRange<Date>
61
+ var currentStep: DeliveryStep
62
+ }
63
+ }
64
+
65
+ enum DeliveryStep: String, Codable, Hashable, CaseIterable {
66
+ case confirmed, preparing, pickedUp, delivering, delivered
67
+
68
+ var icon: String {
69
+ switch self {
70
+ case .confirmed: "checkmark.circle"
71
+ case .preparing: "frying.pan"
72
+ case .pickedUp: "bag.fill"
73
+ case .delivering: "box.truck.fill"
74
+ case .delivered: "house.fill"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### Stale Date
81
+
82
+ Set `staleDate` on `ActivityContent` to tell the system when content becomes outdated. The system sets `context.isStale` to `true` after this date; show fallback UI (e.g., "Updating...") in your views.
83
+
84
+ ```swift
85
+ let content = ActivityContent(
86
+ state: state,
87
+ staleDate: Date().addingTimeInterval(300), // stale after 5 minutes
88
+ relevanceScore: 75
89
+ )
90
+ ```
91
+
92
+ ## Activity Lifecycle
93
+
94
+ ### Starting
95
+
96
+ Use `Activity.request` to create and display a Live Activity. Pass `.token` as
97
+ the `pushType` to enable remote updates via APNs.
98
+
99
+ ```swift
100
+ let attributes = DeliveryAttributes(orderNumber: 42, restaurantName: "Pizza Place")
101
+ let state = DeliveryAttributes.ContentState(
102
+ driverName: "Alex",
103
+ estimatedDeliveryTime: Date()...Date().addingTimeInterval(1800),
104
+ currentStep: .preparing
105
+ )
106
+ let content = ActivityContent(state: state, staleDate: nil, relevanceScore: 75)
107
+
108
+ do {
109
+ let activity = try Activity.request(
110
+ attributes: attributes,
111
+ content: content,
112
+ pushType: .token
113
+ )
114
+ print("Started activity: \(activity.id)")
115
+ } catch {
116
+ print("Failed to start activity: \(error)")
117
+ }
118
+ ```
119
+
120
+ ### Updating
121
+
122
+ Update the dynamic content state from the app. Use `AlertConfiguration` to
123
+ trigger a visible banner and sound alongside the update.
124
+
125
+ ```swift
126
+ let updatedState = DeliveryAttributes.ContentState(
127
+ driverName: "Alex",
128
+ estimatedDeliveryTime: Date()...Date().addingTimeInterval(600),
129
+ currentStep: .delivering
130
+ )
131
+ let updatedContent = ActivityContent(
132
+ state: updatedState,
133
+ staleDate: Date().addingTimeInterval(300),
134
+ relevanceScore: 90
135
+ )
136
+
137
+ // Silent update
138
+ await activity.update(updatedContent)
139
+
140
+ // Update with an alert
141
+ await activity.update(updatedContent, alertConfiguration: AlertConfiguration(
142
+ title: "Order Update",
143
+ body: "Your driver is nearby!",
144
+ sound: .default
145
+ ))
146
+ ```
147
+
148
+ ### Ending
149
+
150
+ End the activity when the tracked event completes. Choose a dismissal policy
151
+ to control how long the ended activity lingers on the Lock Screen.
152
+
153
+ ```swift
154
+ let finalState = DeliveryAttributes.ContentState(
155
+ driverName: "Alex",
156
+ estimatedDeliveryTime: Date()...Date(),
157
+ currentStep: .delivered
158
+ )
159
+ let finalContent = ActivityContent(state: finalState, staleDate: nil, relevanceScore: 0)
160
+
161
+ // System decides when to remove (up to 4 hours)
162
+ await activity.end(finalContent, dismissalPolicy: .default)
163
+
164
+ // Remove immediately
165
+ await activity.end(finalContent, dismissalPolicy: .immediate)
166
+
167
+ // Remove after a specific time (max 4 hours from now)
168
+ await activity.end(finalContent, dismissalPolicy: .after(Date().addingTimeInterval(3600)))
169
+ ```
170
+
171
+ Always end activities on all code paths -- success, error, and cancellation.
172
+ A leaked activity stays on the Lock Screen until the system kills it (up to
173
+ 8 hours), which frustrates users.
174
+
175
+ ## Lock Screen Presentation
176
+
177
+ The Lock Screen is the primary surface for Live Activities. Every device with
178
+ iOS 16.1+ displays Live Activities here. Design this layout first.
179
+
180
+ ```swift
181
+ struct DeliveryActivityWidget: Widget {
182
+ var body: some WidgetConfiguration {
183
+ ActivityConfiguration(for: DeliveryAttributes.self) { context in
184
+ // Lock Screen / StandBy / CarPlay / paired Mac content
185
+ VStack(alignment: .leading, spacing: 8) {
186
+ HStack {
187
+ Text(context.attributes.restaurantName)
188
+ .font(.headline)
189
+ Spacer()
190
+ Text("Order #\(context.attributes.orderNumber)")
191
+ .font(.caption)
192
+ .foregroundStyle(.secondary)
193
+ }
194
+
195
+ if context.isStale {
196
+ Label("Updating...", systemImage: "arrow.trianglehead.2.clockwise")
197
+ .font(.subheadline)
198
+ .foregroundStyle(.secondary)
199
+ } else {
200
+ HStack {
201
+ Label(context.state.driverName, systemImage: "person.fill")
202
+ Spacer()
203
+ Text(timerInterval: context.state.estimatedDeliveryTime,
204
+ countsDown: true)
205
+ .monospacedDigit()
206
+ }
207
+ .font(.subheadline)
208
+
209
+ // Progress steps
210
+ HStack(spacing: 12) {
211
+ ForEach(DeliveryStep.allCases, id: \.self) { step in
212
+ Image(systemName: step.icon)
213
+ .foregroundStyle(
214
+ step <= context.state.currentStep ? .primary : .tertiary
215
+ )
216
+ }
217
+ }
218
+ }
219
+ }
220
+ .padding()
221
+ } dynamicIsland: { context in
222
+ // Dynamic Island closures (see next section)
223
+ DynamicIsland {
224
+ // Expanded regions...
225
+ DynamicIslandExpandedRegion(.leading) {
226
+ Image(systemName: "box.truck.fill").font(.title2)
227
+ }
228
+ DynamicIslandExpandedRegion(.trailing) {
229
+ Text(timerInterval: context.state.estimatedDeliveryTime,
230
+ countsDown: true)
231
+ .font(.caption).monospacedDigit()
232
+ }
233
+ DynamicIslandExpandedRegion(.center) {
234
+ Text(context.attributes.restaurantName).font(.headline)
235
+ }
236
+ DynamicIslandExpandedRegion(.bottom) {
237
+ HStack(spacing: 12) {
238
+ ForEach(DeliveryStep.allCases, id: \.self) { step in
239
+ Image(systemName: step.icon)
240
+ .foregroundStyle(
241
+ step <= context.state.currentStep ? .primary : .tertiary
242
+ )
243
+ }
244
+ }
245
+ }
246
+ } compactLeading: {
247
+ Image(systemName: "box.truck.fill")
248
+ } compactTrailing: {
249
+ Text(timerInterval: context.state.estimatedDeliveryTime,
250
+ countsDown: true)
251
+ .frame(width: 40).monospacedDigit()
252
+ } minimal: {
253
+ Image(systemName: "box.truck.fill")
254
+ }
255
+ }
256
+ }
257
+ }
258
+ ```
259
+
260
+ ### Lock Screen Sizing
261
+
262
+ The Lock Screen presentation has limited vertical space. Avoid layouts taller
263
+ than roughly 160 points. Use `supplementalActivityFamilies` to opt into
264
+ `.small` (compact) or `.medium` (standard) sizing:
265
+
266
+ ```swift
267
+ ActivityConfiguration(for: DeliveryAttributes.self) { context in
268
+ // Lock Screen content
269
+ } dynamicIsland: { context in
270
+ // Dynamic Island
271
+ }
272
+ .supplementalActivityFamilies([.small, .medium])
273
+ ```
274
+
275
+ ## Dynamic Island
276
+
277
+ The Dynamic Island is available on iPhone 14 Pro and later. It has three
278
+ presentation modes. Design all three, but treat the Lock Screen as the primary
279
+ surface since not all devices have a Dynamic Island.
280
+
281
+ ### Compact (Leading + Trailing)
282
+
283
+ Always visible when a single Live Activity is active. Space is extremely
284
+ limited -- show only the most critical information.
285
+
286
+ | Region | Purpose |
287
+ |---|---|
288
+ | `compactLeading` | Icon or tiny label identifying the activity |
289
+ | `compactTrailing` | One key value (timer, score, status) |
290
+
291
+ ### Minimal
292
+
293
+ Shown when multiple Live Activities compete for space. Only one activity gets
294
+ the minimal slot. Display a single icon or glyph.
295
+
296
+ ### Expanded Regions
297
+
298
+ Shown when the user long-presses the Dynamic Island.
299
+
300
+ | Region | Position |
301
+ |---|---|
302
+ | `.leading` | Left of the TrueDepth camera; wraps below |
303
+ | `.trailing` | Right of the TrueDepth camera; wraps below |
304
+ | `.center` | Directly below the camera |
305
+ | `.bottom` | Below all other regions |
306
+
307
+ ### Keyline Tint
308
+
309
+ Apply a subtle tint to the Dynamic Island border:
310
+
311
+ ```swift
312
+ DynamicIsland { /* expanded */ }
313
+ compactLeading: { /* ... */ }
314
+ compactTrailing: { /* ... */ }
315
+ minimal: { /* ... */ }
316
+ .keylineTint(.blue)
317
+ ```
318
+
319
+ ## Push-to-Update
320
+
321
+ Push-to-update sends Live Activity updates through APNs, which is more
322
+ efficient than polling from the app and works when the app is suspended.
323
+
324
+ ### Setup
325
+
326
+ Pass `.token` as the `pushType` when starting the activity, then forward the
327
+ push token to your server:
328
+
329
+ ```swift
330
+ let activity = try Activity.request(
331
+ attributes: attributes,
332
+ content: content,
333
+ pushType: .token
334
+ )
335
+
336
+ // Observe token changes -- tokens can rotate
337
+ Task {
338
+ for await token in activity.pushTokenUpdates {
339
+ let tokenString = token.map { String(format: "%02x", $0) }.joined()
340
+ try await ServerAPI.shared.registerActivityToken(
341
+ tokenString, activityID: activity.id
342
+ )
343
+ }
344
+ }
345
+ ```
346
+
347
+ ### APNs Payload Format
348
+
349
+ Send an HTTP/2 POST to APNs with these headers and JSON body:
350
+
351
+ **Required HTTP headers:**
352
+ - `apns-push-type: liveactivity`
353
+ - `apns-topic: <bundle-id>.push-type.liveactivity`
354
+ - `apns-priority: 5` (low) or `10` (high, triggers alert)
355
+
356
+ **Update payload:**
357
+
358
+ ```json
359
+ {
360
+ "aps": {
361
+ "timestamp": 1700000000,
362
+ "event": "update",
363
+ "content-state": {
364
+ "driverName": "Alex",
365
+ "estimatedDeliveryTime": {
366
+ "lowerBound": 1700000000,
367
+ "upperBound": 1700001800
368
+ },
369
+ "currentStep": "delivering"
370
+ },
371
+ "stale-date": 1700000300,
372
+ "alert": {
373
+ "title": "Delivery Update",
374
+ "body": "Your driver is nearby!"
375
+ }
376
+ }
377
+ }
378
+ ```
379
+
380
+ **End payload:** Same structure with `"event": "end"` and optional `"dismissal-date"`.
381
+
382
+ The `content-state` JSON must match the `ContentState` Codable structure
383
+ exactly. Mismatched keys or types cause silent failures.
384
+
385
+ ### Push-to-Start
386
+
387
+ Start a Live Activity remotely without the app running (iOS 17.2+):
388
+
389
+ ```swift
390
+ Task {
391
+ for await token in Activity<DeliveryAttributes>.pushToStartTokenUpdates {
392
+ let tokenString = token.map { String(format: "%02x", $0) }.joined()
393
+ try await ServerAPI.shared.registerPushToStartToken(tokenString)
394
+ }
395
+ }
396
+ ```
397
+
398
+ ### Frequent Push Updates
399
+
400
+ Add `NSSupportsLiveActivitiesFrequentUpdates = YES` to Info.plist to increase
401
+ the push update budget. Use for activities that update more than once per
402
+ minute (sports scores, ride tracking).
403
+
404
+ ## iOS 26 Additions
405
+
406
+ ### Scheduled Live Activities (iOS 26+)
407
+
408
+ Schedule a Live Activity to start at a future time. The system starts the
409
+ activity automatically without the app being in the foreground. Use for events
410
+ with known start times (sports games, flights, scheduled deliveries).
411
+
412
+ ```swift
413
+ let scheduledDate = Calendar.current.date(
414
+ from: DateComponents(year: 2026, month: 3, day: 15, hour: 19, minute: 0)
415
+ )!
416
+
417
+ let activity = try Activity.request(
418
+ attributes: attributes,
419
+ content: content,
420
+ pushType: .token,
421
+ start: scheduledDate
422
+ )
423
+ ```
424
+
425
+ ### ActivityStyle (iOS 16.1+ type, `style:` parameter iOS 26+)
426
+
427
+ Control persistence: `.standard` (persists until ended, default) or `.transient` (system may dismiss automatically). Use `.transient` for short-lived updates like transit arrivals. The `style:` parameter on `Activity.request` requires iOS 26+.
428
+
429
+ ```swift
430
+ let activity = try Activity.request(
431
+ attributes: attributes, content: content,
432
+ pushType: .token, style: .transient
433
+ )
434
+ ```
435
+
436
+ ### Paired Mac & CarPlay (iOS 26+)
437
+
438
+ Live Activities automatically appear on a paired Mac running macOS Tahoe and on the CarPlay Home Screen. No additional code needed — ensure Lock Screen layout is legible at smaller scales.
439
+
440
+ ### Channel-Based Push (iOS 18+)
441
+
442
+ Broadcast updates to many Live Activities at once with `.channel`:
443
+
444
+ ```swift
445
+ let activity = try Activity.request(
446
+ attributes: attributes, content: content,
447
+ pushType: .channel("delivery-updates")
448
+ )
449
+ ```
450
+
451
+ ## Common Mistakes
452
+
453
+ **DON'T:** Put too much content in the compact presentation -- it is tiny.
454
+ **DO:** Show only the most critical info (icon + one value) in compact leading/trailing.
455
+
456
+ **DON'T:** Update Live Activities too frequently from the app (drains battery).
457
+ **DO:** Use push-to-update for server-driven updates. Limit app-side updates to user actions.
458
+
459
+ **DON'T:** Forget to end the activity when the event completes.
460
+ **DO:** Always end activities on success, error, and cancellation paths. A leaked activity frustrates users.
461
+
462
+ **DON'T:** Assume the Dynamic Island is available (only iPhone 14 Pro+).
463
+ **DO:** Design for the Lock Screen as the primary surface; Dynamic Island is supplementary.
464
+
465
+ **DON'T:** Store sensitive information in ActivityAttributes (visible on Lock Screen).
466
+ **DO:** Keep sensitive data in the app and show only safe-to-display summaries.
467
+
468
+ **DON'T:** Forget to handle stale dates.
469
+ **DO:** Check `context.isStale` in views and show fallback UI ("Updating..." or similar).
470
+
471
+ **DON'T:** Ignore push token rotation. Tokens can change at any time.
472
+ **DO:** Use `activity.pushTokenUpdates` async sequence and re-register on every emission.
473
+
474
+ **DON'T:** Forget the `NSSupportsLiveActivities` Info.plist key.
475
+ **DO:** Add `NSSupportsLiveActivities = YES` to the host app's Info.plist (not the extension).
476
+
477
+ **DON'T:** Use the deprecated `contentState`-based API for request/update/end.
478
+ **DO:** Use `ActivityContent` for all lifecycle calls.
479
+
480
+ **DON'T:** Put heavy logic in Live Activity views. They render in a size-limited widget process.
481
+ **DO:** Pre-compute display values and pass them through `ContentState`.
482
+
483
+ ## Review Checklist
484
+
485
+ - [ ] `ActivityAttributes` defines static properties and `ContentState`
486
+ - [ ] `NSSupportsLiveActivities = YES` in host app Info.plist
487
+ - [ ] Activity uses `ActivityContent` (not deprecated contentState API)
488
+ - [ ] Activity ended in all code paths (success, error, cancellation)
489
+ - [ ] Lock Screen layout handles `context.isStale`
490
+ - [ ] Dynamic Island compact, expanded, and minimal implemented
491
+ - [ ] Push token forwarded to server via `activity.pushTokenUpdates`
492
+ - [ ] `AlertConfiguration` used for important updates
493
+ - [ ] `ActivityAuthorizationInfo` checked before starting
494
+ - [ ] ContentState kept small (serialized on every update)
495
+ - [ ] Tested on device (Dynamic Island differs from Simulator)
496
+ - [ ] Ensure ActivityAttributes and ContentState types are Sendable; update Live Activity UI on @MainActor
497
+
498
+ ## References
499
+
500
+ - See [references/activitykit-patterns.md](references/activitykit-patterns.md) for patterns and code examples
501
+
502
+
503
+ ---
504
+
505
+ Vendored from: https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/activitykit