buildanything 1.7.0 → 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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +55 -0
- package/README.md +71 -61
- package/agents/ios-app-review-guardian.md +49 -0
- package/agents/ios-foundation-models-specialist.md +46 -0
- package/agents/ios-storekit-specialist.md +52 -0
- package/agents/ios-swift-architect.md +102 -0
- package/agents/ios-swift-search.md +130 -0
- package/agents/ios-swift-ui-design.md +104 -0
- package/commands/build.md +80 -176
- package/commands/fix.md +65 -0
- package/commands/setup.md +73 -0
- package/commands/ux-review.md +63 -0
- package/commands/verify.md +72 -0
- package/hooks/session-start +18 -1
- package/package.json +5 -2
- package/protocols/brainstorm.md +99 -0
- package/protocols/build-fix.md +52 -0
- package/protocols/cleanup.md +54 -0
- package/protocols/design.md +269 -0
- package/protocols/eval-harness.md +61 -0
- package/protocols/fake-data-detector.md +64 -0
- package/protocols/ios-context.md +235 -0
- package/protocols/ios-frameworks-map.md +323 -0
- package/protocols/ios-phase-branches.md +162 -0
- package/protocols/ios-preflight.md +27 -0
- package/protocols/metric-loop.md +93 -0
- package/protocols/planning.md +87 -0
- package/protocols/smoke-test.md +110 -0
- package/protocols/verify.md +67 -0
- package/protocols/web-phase-branches.md +201 -0
- package/skills/ios/_VENDORED.md +60 -0
- package/skills/ios/activitykit/LICENSE +131 -0
- package/skills/ios/activitykit/SKILL.md +505 -0
- package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
- package/skills/ios/app-intents/LICENSE +131 -0
- package/skills/ios/app-intents/SKILL.md +494 -0
- package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
- package/skills/ios/apple-on-device-ai/LICENSE +131 -0
- package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
- package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
- package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/skills/ios/ios-26-platform/SKILL.md +53 -0
- package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
- package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
- package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
- package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
- package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
- package/skills/ios/ios-bootstrap/SKILL.md +98 -0
- package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
- package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
- package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
- package/skills/ios/ios-debugger-agent/LICENSE +21 -0
- package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
- package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
- package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
- package/skills/ios/ios-hig/SKILL.md +41 -0
- package/skills/ios/ios-hig/references/accessibility.md +81 -0
- package/skills/ios/ios-hig/references/content.md +142 -0
- package/skills/ios/ios-hig/references/feedback.md +123 -0
- package/skills/ios/ios-hig/references/interaction.md +199 -0
- package/skills/ios/ios-hig/references/performance-platform.md +129 -0
- package/skills/ios/ios-hig/references/privacy-permissions.md +181 -0
- package/skills/ios/ios-hig/references/visual-design.md +84 -0
- package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
- package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
- package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
- package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
- package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
- package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
- package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
- package/skills/ios/swift-accessibility/LICENSE +21 -0
- package/skills/ios/swift-accessibility/SKILL.md +371 -0
- package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
- package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
- package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
- package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
- package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
- package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
- package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
- package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
- package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
- package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
- package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
- package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
- package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
- package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
- package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
- package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
- package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
- package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
- package/skills/ios/swift-concurrency/LICENSE +21 -0
- package/skills/ios/swift-concurrency/SKILL.md +171 -0
- package/skills/ios/swift-concurrency/references/_index.md +50 -0
- package/skills/ios/swift-concurrency/references/actors.md +660 -0
- package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
- package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
- package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
- package/skills/ios/swift-concurrency/references/core-data.md +560 -0
- package/skills/ios/swift-concurrency/references/glossary.md +135 -0
- package/skills/ios/swift-concurrency/references/linting.md +155 -0
- package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
- package/skills/ios/swift-concurrency/references/migration.md +1104 -0
- package/skills/ios/swift-concurrency/references/performance.md +593 -0
- package/skills/ios/swift-concurrency/references/sendable.md +598 -0
- package/skills/ios/swift-concurrency/references/tasks.md +636 -0
- package/skills/ios/swift-concurrency/references/testing.md +592 -0
- package/skills/ios/swift-concurrency/references/threading.md +495 -0
- package/skills/ios/swift-security-expert/LICENSE +21 -0
- package/skills/ios/swift-security-expert/SKILL.md +470 -0
- package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
- package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
- package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
- package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
- package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
- package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
- package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
- package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
- package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
- package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
- package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
- package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
- package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
- package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
- package/skills/ios/swift-testing-expert/LICENSE +21 -0
- package/skills/ios/swift-testing-expert/SKILL.md +79 -0
- package/skills/ios/swift-testing-expert/references/_index.md +12 -0
- package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
- package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
- package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
- package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
- package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
- package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
- package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
- package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
- package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
- package/skills/ios/swiftdata-pro/LICENSE +21 -0
- package/skills/ios/swiftdata-pro/SKILL.md +102 -0
- package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
- package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
- package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
- package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
- package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
- package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
- package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
- package/skills/ios/swiftui-design-principles/LICENSE +21 -0
- package/skills/ios/swiftui-design-principles/README.md +41 -0
- package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
- package/skills/ios/swiftui-design-principles/metadata.json +10 -0
- package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
- package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
- package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
- package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
- package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
- package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
- package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
- package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
- package/skills/ios/swiftui-pro/LICENSE +21 -0
- package/skills/ios/swiftui-pro/SKILL.md +108 -0
- package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
- package/skills/ios/swiftui-pro/references/api.md +39 -0
- package/skills/ios/swiftui-pro/references/data.md +43 -0
- package/skills/ios/swiftui-pro/references/design.md +31 -0
- package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
- package/skills/ios/swiftui-pro/references/navigation.md +14 -0
- package/skills/ios/swiftui-pro/references/performance.md +46 -0
- package/skills/ios/swiftui-pro/references/swift.md +56 -0
- package/skills/ios/swiftui-pro/references/views.md +35 -0
- package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
- package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
- package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
- package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
- package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
- package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
- package/skills/ios/widgetkit/LICENSE +131 -0
- package/skills/ios/widgetkit/SKILL.md +502 -0
- package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# XcodeBuildMCP — MCP config snippet
|
|
2
|
+
|
|
3
|
+
Add the following under the `mcpServers` object in `~/.claude.json` (user-wide) or `./.mcp.json` (project-scoped).
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"mcpServers": {
|
|
8
|
+
"xcodebuildmcp": {
|
|
9
|
+
"command": "npx",
|
|
10
|
+
"args": ["-y", "xcodebuildmcp@latest"]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## What it gives you
|
|
17
|
+
- Discover schemes, targets, and destinations from `.xcodeproj` / `.xcworkspace`
|
|
18
|
+
- Build, clean, archive via `xcodebuild` with structured output
|
|
19
|
+
- Boot, shutdown, and install apps on simulators
|
|
20
|
+
- Toggle target capabilities (Push, HealthKit, App Groups, iCloud, Sign in with Apple)
|
|
21
|
+
- Read and patch Info.plist / entitlements plists safely
|
|
22
|
+
|
|
23
|
+
## Verification
|
|
24
|
+
After adding and restarting Claude Code, confirm tools prefixed `mcp__xcodebuildmcp__` appear in the tool list.
|
|
25
|
+
|
|
26
|
+
## Troubleshooting
|
|
27
|
+
- **`npx` missing** — install Node 20+ (`brew install node`).
|
|
28
|
+
- **Server never initializes** — check Claude Code logs; usually first-run `npx` download stalled behind a proxy.
|
|
29
|
+
- **Multiple Xcode installs** — run `sudo xcode-select -s /Applications/Xcode.app` so the MCP picks up 26.3.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Thomas Ricouard
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ios-debugger-agent
|
|
3
|
+
description: Use XcodeBuildMCP to build, run, launch, and debug the current iOS project on a booted simulator. Trigger when asked to run an iOS app, interact with the simulator UI, inspect on-screen state, capture logs/console output, or diagnose runtime behavior using XcodeBuildMCP tools.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# iOS Debugger Agent
|
|
7
|
+
|
|
8
|
+
> scope=inner dev-loop; Maestro owns E2E
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
Use XcodeBuildMCP to build and run the current project scheme on a booted iOS simulator, interact with the UI, and capture logs. Prefer the MCP tools for simulator control, logs, and view inspection.
|
|
12
|
+
|
|
13
|
+
## Core Workflow
|
|
14
|
+
Follow this sequence unless the user asks for a narrower action.
|
|
15
|
+
|
|
16
|
+
### 1) Discover the booted simulator
|
|
17
|
+
- Call `mcp__XcodeBuildMCP__list_sims` and select the simulator with state `Booted`.
|
|
18
|
+
- If none are booted, ask the user to boot one (do not boot automatically unless asked).
|
|
19
|
+
|
|
20
|
+
### 2) Set session defaults
|
|
21
|
+
- Call `mcp__XcodeBuildMCP__session-set-defaults` with:
|
|
22
|
+
- `projectPath` or `workspacePath` (whichever the repo uses)
|
|
23
|
+
- `scheme` for the current app
|
|
24
|
+
- `simulatorId` from the booted device
|
|
25
|
+
- Optional: `configuration: "Debug"`, `useLatestOS: true`
|
|
26
|
+
|
|
27
|
+
### 3) Build + run (when requested)
|
|
28
|
+
- Call `mcp__XcodeBuildMCP__build_run_sim`.
|
|
29
|
+
- **If the build fails**, check the error output and retry (optionally with `preferXcodebuild: true`) or escalate to the user before attempting any UI interaction.
|
|
30
|
+
- **After a successful build**, verify the app launched by calling `mcp__XcodeBuildMCP__describe_ui` or `mcp__XcodeBuildMCP__screenshot` before proceeding to UI interaction.
|
|
31
|
+
- If the app is already built and only launch is requested, use `mcp__XcodeBuildMCP__launch_app_sim`.
|
|
32
|
+
- If bundle id is unknown:
|
|
33
|
+
1) `mcp__XcodeBuildMCP__get_sim_app_path`
|
|
34
|
+
2) `mcp__XcodeBuildMCP__get_app_bundle_id`
|
|
35
|
+
|
|
36
|
+
## UI Interaction & Debugging
|
|
37
|
+
Use these when asked to inspect or interact with the running app.
|
|
38
|
+
|
|
39
|
+
- **Describe UI**: `mcp__XcodeBuildMCP__describe_ui` before tapping or swiping.
|
|
40
|
+
- **Tap**: `mcp__XcodeBuildMCP__tap` (prefer `id` or `label`; use coordinates only if needed).
|
|
41
|
+
- **Type**: `mcp__XcodeBuildMCP__type_text` after focusing a field.
|
|
42
|
+
- **Gestures**: `mcp__XcodeBuildMCP__gesture` for common scrolls and edge swipes.
|
|
43
|
+
- **Screenshot**: `mcp__XcodeBuildMCP__screenshot` for visual confirmation.
|
|
44
|
+
|
|
45
|
+
## Logs & Console Output
|
|
46
|
+
- Start logs: `mcp__XcodeBuildMCP__start_sim_log_cap` with the app bundle id.
|
|
47
|
+
- Stop logs: `mcp__XcodeBuildMCP__stop_sim_log_cap` and summarize important lines.
|
|
48
|
+
- For console output, set `captureConsole: true` and relaunch if required.
|
|
49
|
+
|
|
50
|
+
## Troubleshooting
|
|
51
|
+
- If build fails, ask whether to retry with `preferXcodebuild: true`.
|
|
52
|
+
- If the wrong app launches, confirm the scheme and bundle id.
|
|
53
|
+
- If UI elements are not hittable, re-run `describe_ui` after layout changes.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
Vendored from: https://github.com/Dimillian/Skills/tree/main/ios-debugger-agent
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ios-entitlements-generator
|
|
3
|
+
description: Generates a .entitlements plist from ios_features flags and syncs Xcode capability toggles via XcodeBuildMCP. Delegates the capability→entitlement table to protocols/ios-frameworks-map.md §4. Use during Phase 4 Foundation.
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
status: ready
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# iOS Entitlements Generator (Phase 4)
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
Turns the `ios_features` checklist in `.build-state.md` into a correct `.entitlements` plist and syncs the Xcode capability UI. Removes the foot-gun of hand-editing entitlement keys.
|
|
12
|
+
|
|
13
|
+
## Authoritative mapping source
|
|
14
|
+
**This skill does NOT maintain its own capability→entitlement table.** It DELEGATES to `protocols/ios-frameworks-map.md` **§4 Entitlement Mapping**. Always consult that table at generation time — it is the single source of truth and is kept in sync with iOS SDK releases.
|
|
15
|
+
|
|
16
|
+
## When this fires
|
|
17
|
+
- Phase 4 Foundation, after architecture decisions finalized
|
|
18
|
+
- A new capability is added mid-project (Push, App Groups, CloudKit, …)
|
|
19
|
+
- Pre-archive audit to confirm entitlements match used capabilities
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
- `ios_features` object from `docs/plans/.build-state.md` — boolean flags like `push`, `cloudKit`, `healthKit`, `appGroups`, `signInWithApple`, `associatedDomains`, `keychainSharing`, `weatherKit`, `musicKit`, `networkExtension`
|
|
23
|
+
- `app_groups_ids` (string[], optional)
|
|
24
|
+
- `associated_domains` (string[], optional — e.g. `applinks:app.example.com`)
|
|
25
|
+
- `icloud_container_ids` (string[], optional)
|
|
26
|
+
- `background_modes` (string[], optional — `fetch`, `remote-notification`, `processing`, `audio`, `location`, `bluetooth-central`, `voip`)
|
|
27
|
+
|
|
28
|
+
## Outputs
|
|
29
|
+
- `<ProjectName>.entitlements` plist at the target's Signing/Capabilities dir
|
|
30
|
+
- `docs/plans/entitlements-summary.md` — diff of added/removed keys, per-capability rationale
|
|
31
|
+
- XcodeBuildMCP capability toggles (Push, HealthKit, CloudKit, App Groups, Sign in with Apple) flipped on in the target UI
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
1. **Read state** — load `ios_features` from `docs/plans/.build-state.md`.
|
|
35
|
+
2. **Resolve entitlements** — for each flag set `true`, look up the entitlement key(s) in `protocols/ios-frameworks-map.md §4`. Do not invent keys; if the table doesn't cover it, query `apple-docs-mcp` and surface as a TODO in the summary.
|
|
36
|
+
3. **Merge plist immutably** — read existing `<ProjectName>.entitlements` if present, compute new dict as a merge (never clobber user-added keys), write a new file. Preserve key ordering for clean diffs.
|
|
37
|
+
4. **Sync Xcode capability UI** — for capabilities that require target-level toggles (Push, HealthKit, CloudKit, App Groups, Sign in with Apple, Background Modes), call XcodeBuildMCP's capability-toggle tool so the Signing & Capabilities tab matches the plist.
|
|
38
|
+
5. **Emit summary** — write `entitlements-summary.md` listing each capability, keys added, and values requiring user input (team ID, container IDs, domain list).
|
|
39
|
+
|
|
40
|
+
## Validation
|
|
41
|
+
- Every key in the output must trace back to a row in `ios-frameworks-map.md §4` or an explicit user-provided value.
|
|
42
|
+
- `aps-environment` must be `development` in debug configs, `production` in release.
|
|
43
|
+
- Associated domains must be prefixed (`applinks:`, `webcredentials:`, `activitycontinuation:`).
|
|
44
|
+
- iCloud container IDs must start with `iCloud.` and match the CloudKit dashboard.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
_Part of buildanything iOS mode. Delegates to `protocols/ios-frameworks-map.md §4`. See `protocols/ios-context.md` for persona._
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ios-hig
|
|
3
|
+
description: Use when designing iOS interfaces, implementing accessibility (VoiceOver, Dynamic Type), handling dark mode, ensuring adequate touch targets, providing animation/haptic feedback, or requesting user permissions. Apple Human Interface Guidelines for iOS compliance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# iOS Human Interface Guidelines
|
|
7
|
+
|
|
8
|
+
Apple's Human Interface Guidelines define the visual language, interaction patterns, and accessibility standards that make iOS apps feel native and intuitive. The core principle: clarity and consistency through thoughtful design.
|
|
9
|
+
|
|
10
|
+
## Reference Loading Guide
|
|
11
|
+
|
|
12
|
+
**ALWAYS load reference files if there is even a small chance the content may be required.** It's better to have the context than to miss a pattern or make a mistake.
|
|
13
|
+
|
|
14
|
+
| Reference | Load When |
|
|
15
|
+
|-----------|-----------|
|
|
16
|
+
| **[Interaction](references/interaction.md)** | Touch targets, navigation, layout, hierarchy, or gesture patterns |
|
|
17
|
+
| **[Content](references/content.md)** | Empty states, writing copy, typography, or placeholder text |
|
|
18
|
+
| **[Visual Design](references/visual-design.md)** | Colors, materials, contrast, dark mode, or SF Symbols |
|
|
19
|
+
| **[Accessibility](references/accessibility.md)** | VoiceOver, Dynamic Type, Reduce Motion, or accessibility labels |
|
|
20
|
+
| **[Feedback](references/feedback.md)** | Animations, haptics, loading states, or error messages |
|
|
21
|
+
| **[Performance](references/performance-platform.md)** | Responsiveness, system components, or app launch |
|
|
22
|
+
| **[Privacy](references/privacy-permissions.md)** | Permission requests, data handling, or privacy-sensitive APIs |
|
|
23
|
+
|
|
24
|
+
## Common Mistakes
|
|
25
|
+
|
|
26
|
+
1. **Touch targets smaller than 44x44 points** — Buttons and interactive elements must be at least 44x44 points (iOS) to accommodate thumbs. Smaller targets cause frustrated users and accessibility failures.
|
|
27
|
+
|
|
28
|
+
2. **Ignoring Dynamic Type constraints** — Text with fixed sizes doesn't respect user accessibility settings. Use Dynamic Type sizes, test with Large or Extra Large settings, and avoid hardcoded font sizes.
|
|
29
|
+
|
|
30
|
+
3. **Insufficient color contrast in dark mode** — Colors that work in light mode may fail accessibility in dark mode. Test with Reduce Contrast accessibility setting enabled for both modes.
|
|
31
|
+
|
|
32
|
+
4. **Over-animating transitions** — Animations that feel smooth at 60fps can trigger motion sickness in users with vestibular issues. Respect Reduce Motion settings and keep animations under 300ms.
|
|
33
|
+
|
|
34
|
+
5. **Missing VoiceOver labels on custom controls** — Custom buttons, toggles, or interactive views need `.accessibilityLabel()` and `.accessibilityHint()` or they're completely unusable to screen reader users.
|
|
35
|
+
|
|
36
|
+
6. **Haptic overuse** — Every action does NOT need haptic feedback. Reserve haptics for confirmations (purchase, critical action) and errors. Excessive haptics are annoying and drain battery.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
Vendored from: https://github.com/johnrogers/claude-swift-engineering/tree/main/plugins/swift-engineering/skills/ios-hig
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Accessibility
|
|
2
|
+
|
|
3
|
+
Apple Human Interface Guidelines for accessible iOS app design.
|
|
4
|
+
|
|
5
|
+
## Critical Rules
|
|
6
|
+
|
|
7
|
+
- Provide meaningful accessibility labels/hints for icon-only controls and custom components
|
|
8
|
+
- Ensure Dynamic Type works end-to-end; avoid layouts that collapse at larger sizes
|
|
9
|
+
- Maintain readable contrast and avoid conveying meaning by color alone
|
|
10
|
+
- Respect platform accessibility settings (Reduce Motion/Transparency) when relevant
|
|
11
|
+
- Prefer system controls that come with good accessibility defaults
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Icon-Only Buttons
|
|
16
|
+
|
|
17
|
+
```swift
|
|
18
|
+
// ✅ Icon-only button with accessible label
|
|
19
|
+
Button(action: model.refresh) {
|
|
20
|
+
Image(systemName: "arrow.clockwise")
|
|
21
|
+
}
|
|
22
|
+
.accessibilityLabel("Refresh")
|
|
23
|
+
.accessibilityHint("Reloads the list")
|
|
24
|
+
|
|
25
|
+
// ❌ Icon-only control with no label; VoiceOver reads "arrow.clockwise"
|
|
26
|
+
Button(action: model.refresh) {
|
|
27
|
+
Image(systemName: "arrow.clockwise")
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Dynamic Type Support
|
|
32
|
+
|
|
33
|
+
```swift
|
|
34
|
+
// ✅ Dynamic Type with proper layout
|
|
35
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
36
|
+
Text(item.title)
|
|
37
|
+
.font(.headline)
|
|
38
|
+
.lineLimit(2)
|
|
39
|
+
|
|
40
|
+
if let summary = item.summary {
|
|
41
|
+
Text(summary)
|
|
42
|
+
.font(.body)
|
|
43
|
+
.foregroundStyle(.secondary)
|
|
44
|
+
.lineLimit(3)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ❌ Hard-coded sizes that don't scale
|
|
49
|
+
VStack(alignment: .leading) {
|
|
50
|
+
Text(item.title)
|
|
51
|
+
.font(.system(size: 14))
|
|
52
|
+
.lineLimit(1)
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Reduce Motion
|
|
57
|
+
|
|
58
|
+
```swift
|
|
59
|
+
// ✅ Respect Reduce Motion setting
|
|
60
|
+
@Environment(\.accessibilityReduceMotion) var reduceMotion
|
|
61
|
+
|
|
62
|
+
var body: some View {
|
|
63
|
+
content
|
|
64
|
+
.animation(reduceMotion ? .none : .spring, value: isExpanded)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ❌ Always animate regardless of setting
|
|
68
|
+
var body: some View {
|
|
69
|
+
content
|
|
70
|
+
.animation(.spring, value: isExpanded)
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Summary
|
|
75
|
+
|
|
76
|
+
**Key Principles**:
|
|
77
|
+
1. Use `.accessibilityLabel()` and `.accessibilityHint()` for icon-only controls
|
|
78
|
+
2. Support Dynamic Type with system font styles
|
|
79
|
+
3. Maintain sufficient color contrast
|
|
80
|
+
4. Respect accessibility settings like Reduce Motion
|
|
81
|
+
5. Prefer system controls with built-in accessibility
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Content
|
|
2
|
+
|
|
3
|
+
Apple Human Interface Guidelines for content, empty states, writing, and typography.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
1. [Empty States](#empty-states)
|
|
7
|
+
2. [Writing and Labels](#writing-and-labels)
|
|
8
|
+
3. [Typography and Dynamic Type](#typography-and-dynamic-type)
|
|
9
|
+
|
|
10
|
+
## Empty States
|
|
11
|
+
|
|
12
|
+
### Critical Rules
|
|
13
|
+
|
|
14
|
+
- Use empty states to **explain what this screen is** and **what to do next**
|
|
15
|
+
- Prefer lightweight guidance (one sentence + primary action) over multi-step tutorials
|
|
16
|
+
- Keep onboarding contextual: explain features at the moment the user needs them
|
|
17
|
+
- Avoid placeholder junk content that looks real; make it obvious when content is sample/demo
|
|
18
|
+
|
|
19
|
+
### Examples
|
|
20
|
+
|
|
21
|
+
```swift
|
|
22
|
+
// ✅ Helpful empty state with a clear next step
|
|
23
|
+
ContentUnavailableView {
|
|
24
|
+
Label("No links yet", systemImage: "link")
|
|
25
|
+
} description: {
|
|
26
|
+
Text("Save links to find them quickly later.")
|
|
27
|
+
} actions: {
|
|
28
|
+
Button("Add link", systemImage: "plus") { model.presentAddLink() }
|
|
29
|
+
.buttonStyle(.borderedProminent)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ❌ Empty UI with no explanation
|
|
33
|
+
List { }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Writing and Labels
|
|
37
|
+
|
|
38
|
+
### Critical Rules
|
|
39
|
+
|
|
40
|
+
- Prefer **plain language** and short phrases; avoid jargon and developer terms
|
|
41
|
+
- Buttons should describe the action ("Save", "Add link"), not vague labels ("OK", "Yes")
|
|
42
|
+
- Keep terminology consistent across the app (e.g., "Link" vs "URL"); choose one and stick to it
|
|
43
|
+
- Error messages should explain the problem and the next step, without blame
|
|
44
|
+
|
|
45
|
+
### Examples
|
|
46
|
+
|
|
47
|
+
```swift
|
|
48
|
+
// ✅ Clear action labels and consistent terminology
|
|
49
|
+
Button("Add link", systemImage: "plus") { model.addLink() }
|
|
50
|
+
Button("Save", action: model.save)
|
|
51
|
+
|
|
52
|
+
// Error message example
|
|
53
|
+
Text("Could not save link. Check your connection and try again.")
|
|
54
|
+
|
|
55
|
+
// ❌ Vague and inconsistent
|
|
56
|
+
Button("OK") { model.save() }
|
|
57
|
+
Button("Add URL") { model.addLink() }
|
|
58
|
+
|
|
59
|
+
// Error message without guidance
|
|
60
|
+
Text("Error: Save failed")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Writing Guidelines
|
|
64
|
+
|
|
65
|
+
**Button Labels**:
|
|
66
|
+
- ✅ "Delete", "Save", "Add link"
|
|
67
|
+
- ❌ "OK", "Yes", "No"
|
|
68
|
+
|
|
69
|
+
**Error Messages**:
|
|
70
|
+
- ✅ "Could not load items. Pull to refresh."
|
|
71
|
+
- ❌ "Error code 404"
|
|
72
|
+
|
|
73
|
+
**Terminology Consistency**:
|
|
74
|
+
- Choose one term and use it throughout
|
|
75
|
+
- "Link" not "URL" or "Website"
|
|
76
|
+
- "Save" not "Add" or "Create" interchangeably
|
|
77
|
+
|
|
78
|
+
## Typography and Dynamic Type
|
|
79
|
+
|
|
80
|
+
### Critical Rules
|
|
81
|
+
|
|
82
|
+
- Use **Dynamic Type** styles (`.body`, `.headline`, `.caption`) instead of hard-coded sizes
|
|
83
|
+
- Prefer **short, scannable labels**; use secondary text (`.secondary`) for supporting detail
|
|
84
|
+
- Avoid truncation for critical info; if truncation can happen, provide an alternative (multi-line, disclosure, copy)
|
|
85
|
+
- Use appropriate alignment and line limits; avoid overly dense paragraphs
|
|
86
|
+
- Ensure text remains legible in accessibility sizes (test with larger sizes)
|
|
87
|
+
|
|
88
|
+
### Examples
|
|
89
|
+
|
|
90
|
+
```swift
|
|
91
|
+
// ✅ Dynamic Type + predictable wrapping for important content
|
|
92
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
93
|
+
Text(item.title)
|
|
94
|
+
.font(.headline)
|
|
95
|
+
.lineLimit(2)
|
|
96
|
+
|
|
97
|
+
if let summary = item.summary {
|
|
98
|
+
Text(summary)
|
|
99
|
+
.font(.body)
|
|
100
|
+
.foregroundStyle(.secondary)
|
|
101
|
+
.lineLimit(3)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ❌ Hard-coded sizes and single-line truncation for critical info
|
|
106
|
+
VStack(alignment: .leading) {
|
|
107
|
+
Text(item.title)
|
|
108
|
+
.font(.system(size: 14))
|
|
109
|
+
.lineLimit(1)
|
|
110
|
+
Text(item.summary ?? "")
|
|
111
|
+
.font(.system(size: 11))
|
|
112
|
+
.lineLimit(1)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Dynamic Type Styles
|
|
117
|
+
|
|
118
|
+
Use system text styles that scale with Dynamic Type:
|
|
119
|
+
- `.largeTitle`, `.title`, `.title2`, `.title3`
|
|
120
|
+
- `.headline`, `.body`, `.callout`
|
|
121
|
+
- `.subheadline`, `.footnote`, `.caption`, `.caption2`
|
|
122
|
+
|
|
123
|
+
```swift
|
|
124
|
+
// ✅ System styles that scale
|
|
125
|
+
Text("Main heading")
|
|
126
|
+
.font(.title2)
|
|
127
|
+
Text("Body content")
|
|
128
|
+
.font(.body)
|
|
129
|
+
Text("Supporting detail")
|
|
130
|
+
.font(.caption)
|
|
131
|
+
.foregroundStyle(.secondary)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Summary
|
|
135
|
+
|
|
136
|
+
**Key Principles**:
|
|
137
|
+
1. Use `ContentUnavailableView` for helpful empty states
|
|
138
|
+
2. Write clear, action-oriented button labels
|
|
139
|
+
3. Keep terminology consistent throughout the app
|
|
140
|
+
4. Error messages explain the problem and next step
|
|
141
|
+
5. Use Dynamic Type styles, never hard-coded sizes
|
|
142
|
+
6. Allow important text to wrap (don't truncate critical info)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Feedback
|
|
2
|
+
|
|
3
|
+
Apple Human Interface Guidelines for motion, haptics, loading states, and error handling.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
1. [Motion and Haptics](#motion-and-haptics)
|
|
7
|
+
2. [Status and Error Feedback](#status-and-error-feedback)
|
|
8
|
+
|
|
9
|
+
## Motion and Haptics
|
|
10
|
+
|
|
11
|
+
### Critical Rules
|
|
12
|
+
|
|
13
|
+
- Motion should be **purposeful**: reinforce state change, hierarchy, or causality—not decoration
|
|
14
|
+
- Keep animations **subtle and consistent**; avoid stacking multiple effects (scale + rotate + blur) for routine interactions
|
|
15
|
+
- Respect accessibility settings (Reduce Motion); don't rely on animation as the only feedback
|
|
16
|
+
- Use haptics sparingly for meaningful moments (confirmations, errors), not for every tap
|
|
17
|
+
|
|
18
|
+
### Examples
|
|
19
|
+
|
|
20
|
+
```swift
|
|
21
|
+
// ✅ Subtle animation tied to state change
|
|
22
|
+
withAnimation(.spring(response: 0.35, dampingFraction: 0.85)) {
|
|
23
|
+
model.isExpanded.toggle()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ❌ Excessive motion for routine UI; feels noisy and fatiguing
|
|
27
|
+
withAnimation(.easeInOut(duration: 2.0)) {
|
|
28
|
+
model.isExpanded.toggle()
|
|
29
|
+
}
|
|
30
|
+
// Plus additional scale/rotation/blur effects on the entire screen
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Motion Guidelines
|
|
34
|
+
|
|
35
|
+
**Purposeful Animation**:
|
|
36
|
+
- State transitions (expanding/collapsing)
|
|
37
|
+
- Hierarchy changes (list reordering)
|
|
38
|
+
- Causality (deletion leading to list reflow)
|
|
39
|
+
|
|
40
|
+
**Animation Parameters**:
|
|
41
|
+
- Spring response: 0.3-0.4 seconds
|
|
42
|
+
- Damping fraction: 0.8-0.9 (less bouncy)
|
|
43
|
+
- Easing: Prefer springs over linear or custom curves
|
|
44
|
+
|
|
45
|
+
**Accessibility**:
|
|
46
|
+
- Always respect `@Environment(\.accessibilityReduceMotion)`
|
|
47
|
+
- Provide non-animated alternatives
|
|
48
|
+
- Don't use motion as the only feedback mechanism
|
|
49
|
+
|
|
50
|
+
## Status and Error Feedback
|
|
51
|
+
|
|
52
|
+
### Critical Rules
|
|
53
|
+
|
|
54
|
+
- Always show **state feedback** for async work: loading, success, failure, and empty
|
|
55
|
+
- Prefer **inline** status for local issues (validation) and **alerts** for exceptional interruptions
|
|
56
|
+
- Make errors **actionable**: explain what happened in plain language and offer a next step (retry, fix input, dismiss)
|
|
57
|
+
- Avoid blaming the user; avoid exposing raw system error text
|
|
58
|
+
- Use system patterns for empty states (`ContentUnavailableView`) and progress (`ProgressView`)
|
|
59
|
+
|
|
60
|
+
### Examples
|
|
61
|
+
|
|
62
|
+
```swift
|
|
63
|
+
// ✅ Clear empty state and recoverable error with retry
|
|
64
|
+
Group {
|
|
65
|
+
if model.isLoading {
|
|
66
|
+
ProgressView("Loading…")
|
|
67
|
+
} else if model.items.isEmpty {
|
|
68
|
+
ContentUnavailableView(
|
|
69
|
+
"No items",
|
|
70
|
+
systemImage: "tray",
|
|
71
|
+
description: Text("Add your first item to get started.")
|
|
72
|
+
)
|
|
73
|
+
} else {
|
|
74
|
+
List(model.items) { item in Text(item.title) }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
.alert("Couldn't load items", isPresented: $model.isShowingError) {
|
|
78
|
+
Button("Retry", action: model.reload)
|
|
79
|
+
Button("Cancel", role: .cancel) {}
|
|
80
|
+
} message: {
|
|
81
|
+
Text("Check your connection and try again.")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ❌ Silent failures and raw errors; no next step
|
|
85
|
+
List(model.items) { item in Text(item.title) }
|
|
86
|
+
// On error: print(error) and keep stale UI with no feedback
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Status Guidelines
|
|
90
|
+
|
|
91
|
+
**Loading States**:
|
|
92
|
+
- Use `ProgressView` for async operations
|
|
93
|
+
- Show progress for operations >1 second
|
|
94
|
+
- Provide context ("Loading items…")
|
|
95
|
+
|
|
96
|
+
**Empty States**:
|
|
97
|
+
- Use `ContentUnavailableView` for empty collections
|
|
98
|
+
- Explain what the view is for
|
|
99
|
+
- Provide a primary action to get started
|
|
100
|
+
|
|
101
|
+
**Error States**:
|
|
102
|
+
- Use alerts for unexpected errors that interrupt flow
|
|
103
|
+
- Use inline validation for expected errors (form fields)
|
|
104
|
+
- Always provide a recovery action
|
|
105
|
+
|
|
106
|
+
**Error Messages**:
|
|
107
|
+
- ✅ "Couldn't save item. Check your connection and try again."
|
|
108
|
+
- ❌ "Error: NetworkError.timeout"
|
|
109
|
+
|
|
110
|
+
**Next Steps**:
|
|
111
|
+
- Retry button for transient failures
|
|
112
|
+
- Fix input guidance for validation errors
|
|
113
|
+
- Dismiss or cancel for unrecoverable errors
|
|
114
|
+
|
|
115
|
+
## Summary
|
|
116
|
+
|
|
117
|
+
**Key Principles**:
|
|
118
|
+
1. Keep motion subtle, purposeful, and tied to state changes
|
|
119
|
+
2. Respect Reduce Motion accessibility setting
|
|
120
|
+
3. Always show feedback for async operations (loading, empty, error)
|
|
121
|
+
4. Make errors actionable with plain language and recovery steps
|
|
122
|
+
5. Use system patterns (`ProgressView`, `ContentUnavailableView`, alerts)
|
|
123
|
+
6. Prefer inline validation for expected errors, alerts for exceptional interruptions
|