agy-superpowers 5.0.8 → 5.0.9
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/package.json +1 -1
- package/template/agent/rules/superpowers.md +54 -0
- package/template/agent/skills/frontend-developer/SKILL.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-nextjs.md +343 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_sections.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_template.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-event-handler-refs.md +55 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-init-once.md +42 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-use-latest.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-api-routes.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-defer-await.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-dependencies.md +51 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-parallel.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-suspense-boundaries.md +99 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-barrel-imports.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-conditional.md +31 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-defer-third-party.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-dynamic-imports.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-preload.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-event-listeners.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-localstorage-schema.md +71 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-passive-event-listeners.md +48 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-swr-dedup.md +56 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-batch-dom-css.md +107 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-function-results.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-property-access.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-storage.md +70 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-combine-iterations.md +32 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-early-exit.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-flatmap-filter.md +60 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-hoist-regexp.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-index-maps.md +37 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-length-check-first.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-min-max-loop.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-set-map-lookups.md +24 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-tosorted-immutable.md +57 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-activity.md +26 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-conditional-render.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-content-visibility.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hoist-jsx.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-no-flicker.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-suppress-warning.md +30 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-resource-hints.md +85 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-script-defer-async.md +68 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-svg-precision.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-usetransition-loading.md +75 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-defer-reads.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-dependencies.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state-no-effect.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state.md +29 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-functional-setstate.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-lazy-state-init.md +58 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo-with-default-value.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo.md +44 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-move-effect-to-event.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-no-inline-components.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-simple-expression-in-memo.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-split-combined-hooks.md +64 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-transitions.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-deferred-value.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-ref-transient-values.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-after-nonblocking.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-auth-actions.md +96 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-lru.md +41 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-react.md +76 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-dedup-props.md +65 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-hoist-static-io.md +142 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-parallel-fetching.md +83 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-serialization.md +38 -0
- package/template/agent/skills/frontend-developer/references/svelte-sveltekit.md +220 -0
- package/template/agent/skills/frontend-developer/references/vanilla.md +275 -0
- package/template/agent/skills/frontend-developer/references/vue-nuxt.md +289 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/_index.md +154 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-class-based-technique.md +254 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-state-driven-technique.md +291 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-async.md +97 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-data-flow.md +307 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-fallthrough-attrs.md +174 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-keep-alive.md +137 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-slots.md +216 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-suspense.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-teleport.md +108 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition-group.md +128 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition.md +125 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/composables.md +290 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/directives.md +162 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-v-once-v-memo-directives.md +182 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-virtualize-large-lists.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/plugins.md +166 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/reactivity.md +344 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/render-functions.md +201 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/sfc.md +310 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/state-management.md +135 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/updated-hook-performance.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/_index.md +23 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforeenter-no-param-trigger.md +167 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforerouteenter-no-this.md +176 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-guard-async-await-pattern.md +227 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-infinite-loop.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-next-deprecated.md +150 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-param-change-no-lifecycle.md +181 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-simple-routing-cleanup.md +209 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-use-vue-router-for-production.md +183 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/_index.md +29 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/async-component-testing.md +163 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/teleport-testing-complexity.md +158 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-async-await-flushpromises.md +175 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-browser-vs-node-runners.md +208 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-component-blackbox-approach.md +144 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-composables-helper-wrapper.md +238 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-e2e-playwright-recommended.md +242 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-no-snapshot-only.md +197 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-pinia-store-setup.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-suspense-async-components.md +229 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-vitest-recommended-for-vue.md +204 -0
- package/template/agent/skills/mobile-developer/SKILL.md +52 -0
- package/template/agent/skills/mobile-developer/references/android-native.md +396 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-accessibility.md +36 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-architecture.md +52 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-coroutines.md +139 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-data-layer.md +51 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-emulator-skill.md +108 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-gradle-logic.md +126 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-retrofit.md +142 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-testing.md +102 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-viewmodel.md +43 -0
- package/template/agent/skills/mobile-developer/references/android-rules/coil-compose.md +74 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-navigation.md +422 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-performance-audit.md +199 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-ui.md +49 -0
- package/template/agent/skills/mobile-developer/references/android-rules/gradle-build-performance.md +346 -0
- package/template/agent/skills/mobile-developer/references/android-rules/kotlin-concurrency-expert.md +169 -0
- package/template/agent/skills/mobile-developer/references/android-rules/rxjava-to-coroutines-migration.md +101 -0
- package/template/agent/skills/mobile-developer/references/android-rules/xml-to-compose-migration.md +338 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-best-practices.md +52 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-checks-migration.md +134 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-cli-app-best-practices.md +123 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-doc-validation.md +45 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-matcher-best-practices.md +106 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-modern-features.md +241 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-package-maintenance.md +75 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-test-fundamentals.md +124 -0
- package/template/agent/skills/mobile-developer/references/flutter.md +291 -0
- package/template/agent/skills/mobile-developer/references/ios-native.md +358 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/accessibility-patterns.md +215 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-advanced.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-basics.md +284 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-transitions.md +326 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts-accessibility.md +135 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts.md +602 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/image-optimization.md +203 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/latest-apis.md +464 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/layout-best-practices.md +266 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/liquid-glass.md +416 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/list-patterns.md +394 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-scenes.md +318 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-views.md +357 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-window-styling.md +303 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/performance-patterns.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/scroll-patterns.md +293 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/sheet-navigation-patterns.md +363 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/state-management.md +417 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/view-structure.md +389 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_sections.md +86 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_template.md +28 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-derived-value.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gesture-detector-press.md +95 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gpu-properties.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/design-system-compound-components.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/fonts-config-plugin.md +71 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/imports-design-system-folder.md +68 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/js-hoist-intl.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-callbacks.md +44 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-function-references.md +132 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-images.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-inline-objects.md +97 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-expensive.md +94 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-memo.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-types.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-virtualize.md +67 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-native-deps-in-app.md +46 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-single-dependency-versions.md +63 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/navigation-native-navigators.md +188 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-destructure-functions.md +50 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-reanimated-shared-values.md +48 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-dispatcher.md +91 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-fallback.md +56 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-minimize.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-no-falsy-and.md +74 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-text-in-text-component.md +36 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/scroll-position-no-state.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/state-ground-truth.md +80 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-expo-image.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-image-gallery.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-measure-views.md +78 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-menus.md +174 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-native-modals.md +77 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-pressable.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-safe-area-scroll.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-scrollview-content-inset.md +45 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-styling.md +87 -0
- package/template/agent/skills/mobile-developer/references/react-native.md +345 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Flutter + Dart Reference
|
|
2
|
+
|
|
3
|
+
> **Philosophy:** Everything is a widget. Composition over inheritance. Declarative UI with immutable state.
|
|
4
|
+
> Flutter owns the pixels — no bridge, no compromise.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Setup & Detection
|
|
9
|
+
|
|
10
|
+
**Stack indicators:** `pubspec.yaml` file in project root.
|
|
11
|
+
|
|
12
|
+
**Key config files:**
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `pubspec.yaml` | Dependencies, assets, metadata |
|
|
17
|
+
| `analysis_options.yaml` | Linter rules and static analysis |
|
|
18
|
+
| `lib/main.dart` | App entry point |
|
|
19
|
+
| `android/` | Android-specific config (Gradle, manifest) |
|
|
20
|
+
| `ios/` | iOS-specific config (Xcode project, Info.plist) |
|
|
21
|
+
| `.dart_tool/` | Generated config (do not edit) |
|
|
22
|
+
|
|
23
|
+
**Recommended project structure (feature-based):**
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
lib/
|
|
27
|
+
app/
|
|
28
|
+
app.dart # MaterialApp / CupertinoApp setup
|
|
29
|
+
router.dart # GoRouter configuration
|
|
30
|
+
features/
|
|
31
|
+
auth/
|
|
32
|
+
presentation/
|
|
33
|
+
login_screen.dart
|
|
34
|
+
widgets/auth_form.dart
|
|
35
|
+
domain/
|
|
36
|
+
auth_repository.dart
|
|
37
|
+
data/
|
|
38
|
+
auth_api.dart
|
|
39
|
+
home/
|
|
40
|
+
presentation/
|
|
41
|
+
home_screen.dart
|
|
42
|
+
shared/
|
|
43
|
+
widgets/ # Reusable UI widgets
|
|
44
|
+
extensions/ # Dart extension methods
|
|
45
|
+
theme/ # ThemeData, colors, typography
|
|
46
|
+
utils/ # Pure utility functions
|
|
47
|
+
main.dart # Entry point, ProviderScope
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Architecture Patterns
|
|
53
|
+
|
|
54
|
+
### State Management
|
|
55
|
+
|
|
56
|
+
| Approach | Use When |
|
|
57
|
+
|----------|----------|
|
|
58
|
+
| **Riverpod** (recommended) | Most apps — compile-safe, testable, fine-grained reactivity |
|
|
59
|
+
| **BLoC** | Teams familiar with reactive streams, complex event-driven flows |
|
|
60
|
+
| **Provider** | Simpler apps, legacy codebases (Riverpod supersedes Provider) |
|
|
61
|
+
| **GetX** | Rapid prototyping only — avoid for production (magic, hard to test) |
|
|
62
|
+
|
|
63
|
+
**Riverpod patterns:**
|
|
64
|
+
- Use `@riverpod` annotation (code generation) for type-safe providers
|
|
65
|
+
- Prefer `AsyncNotifier` over `StateNotifier` (built-in async handling)
|
|
66
|
+
- Keep providers at feature level, not global
|
|
67
|
+
- Use `ref.watch()` for reactive, `ref.read()` for one-shot
|
|
68
|
+
|
|
69
|
+
### Navigation
|
|
70
|
+
|
|
71
|
+
**`go_router`** (recommended) — declarative, type-safe routing with deep link support.
|
|
72
|
+
|
|
73
|
+
```dart
|
|
74
|
+
final router = GoRouter(
|
|
75
|
+
routes: [
|
|
76
|
+
GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
|
|
77
|
+
GoRoute(path: '/profile/:id', builder: (_, state) =>
|
|
78
|
+
ProfileScreen(id: state.pathParameters['id']!)),
|
|
79
|
+
],
|
|
80
|
+
);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- Use `ShellRoute` for persistent bottom navigation
|
|
84
|
+
- Use `StatefulShellRoute` for preserving tab state
|
|
85
|
+
- Define routes as constants to avoid typos
|
|
86
|
+
|
|
87
|
+
### Widget Composition
|
|
88
|
+
|
|
89
|
+
- **Extract widgets into separate classes** — don't build deeply nested widget trees in a single `build()` method
|
|
90
|
+
- **Use `const` constructors** wherever possible — marks widget subtrees as immutable so Flutter skips rebuilding them
|
|
91
|
+
- **Prefer composition over inheritance** — compose widgets from smaller pieces rather than extending
|
|
92
|
+
- **Keep `build()` methods lean** — if a build method exceeds ~50 lines, extract sub-widgets
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Performance Optimization
|
|
97
|
+
|
|
98
|
+
### Critical Rules
|
|
99
|
+
|
|
100
|
+
| Metric | Target | Investigate |
|
|
101
|
+
|--------|--------|-------------|
|
|
102
|
+
| App startup | < 2s | > 3s |
|
|
103
|
+
| Frame rendering | 16ms (60fps) | > 16ms (jank) |
|
|
104
|
+
| APK size | < 20MB | > 50MB |
|
|
105
|
+
| Memory (foreground) | < 150MB | > 300MB |
|
|
106
|
+
|
|
107
|
+
### Key Optimizations
|
|
108
|
+
|
|
109
|
+
1. **`const` constructors everywhere** — prevents unnecessary rebuilds. A `const` widget is created once and reused.
|
|
110
|
+
|
|
111
|
+
```dart
|
|
112
|
+
// ❌ Bad: rebuilds every time parent rebuilds
|
|
113
|
+
return Container(color: Colors.blue, child: Text('Hello'));
|
|
114
|
+
|
|
115
|
+
// ✅ Good: created once, never rebuilt
|
|
116
|
+
return const SizedBox(height: 16);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. **`RepaintBoundary`** — isolates repaint regions for complex widgets (animations, canvases). Prevents entire subtree from repainting.
|
|
120
|
+
|
|
121
|
+
3. **`ListView.builder`** over `ListView` — lazy construction, only builds visible items.
|
|
122
|
+
|
|
123
|
+
```dart
|
|
124
|
+
// ❌ Bad: builds all children immediately
|
|
125
|
+
ListView(children: items.map((i) => ItemCard(i)).toList());
|
|
126
|
+
|
|
127
|
+
// ✅ Good: lazy, only visible items built
|
|
128
|
+
ListView.builder(
|
|
129
|
+
itemCount: items.length,
|
|
130
|
+
itemBuilder: (_, i) => ItemCard(items[i]),
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
4. **Impeller rendering engine** — Flutter's new graphics engine (default on iOS, opt-in on Android). Eliminates shader compilation jank.
|
|
135
|
+
|
|
136
|
+
5. **Avoid `setState` in large widget trees** — use fine-grained state solutions (Riverpod, BLoC) to rebuild only affected widgets.
|
|
137
|
+
|
|
138
|
+
6. **Profile with DevTools** — use the Performance overlay to identify jank, the Widget Inspector for layout issues, and the Memory view for leaks.
|
|
139
|
+
|
|
140
|
+
### Shader Warmup
|
|
141
|
+
|
|
142
|
+
For custom shaders, warm them up during a splash screen to avoid first-frame jank:
|
|
143
|
+
|
|
144
|
+
```dart
|
|
145
|
+
await ShaderConfiguration()
|
|
146
|
+
.warmupShader('shaders/gradient.frag');
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Common Libraries Ecosystem
|
|
152
|
+
|
|
153
|
+
| Category | Recommended | Alternative |
|
|
154
|
+
|----------|-------------|-------------|
|
|
155
|
+
| **State** | `riverpod` + `riverpod_generator` | `flutter_bloc`, `provider` |
|
|
156
|
+
| **Navigation** | `go_router` | `auto_route` |
|
|
157
|
+
| **HTTP** | `dio` | `http`, `chopper` |
|
|
158
|
+
| **Local Storage** | `shared_preferences` | `hive`, `objectbox` |
|
|
159
|
+
| **Database** | `drift` (SQLite) | `isar`, `floor` |
|
|
160
|
+
| **Secure Storage** | `flutter_secure_storage` | — |
|
|
161
|
+
| **Images** | `cached_network_image` | `extended_image` |
|
|
162
|
+
| **JSON** | `json_serializable` + `freezed` | `built_value` |
|
|
163
|
+
| **Icons** | `flutter_svg` + `hugeicons` | `font_awesome_flutter` |
|
|
164
|
+
| **Forms** | `reactive_forms` | `flutter_form_builder` |
|
|
165
|
+
| **Testing** | `mocktail` | `mockito` |
|
|
166
|
+
| **Linting** | `very_good_analysis` | `flutter_lints` |
|
|
167
|
+
| **Code Gen** | `build_runner` | — |
|
|
168
|
+
| **Deep Links** | `go_router` (built-in) | `uni_links` |
|
|
169
|
+
| **Analytics** | `firebase_analytics` | `amplitude_flutter` |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Anti-Patterns & Gotchas
|
|
174
|
+
|
|
175
|
+
| ❌ Don't | Why | ✅ Do Instead |
|
|
176
|
+
|----------|-----|---------------|
|
|
177
|
+
| Deeply nested widget trees (10+ levels) | Unreadable, hard to debug, poor perf | Extract into named widget classes |
|
|
178
|
+
| `setState` for global/shared state | Rebuilds entire widget subtree | Riverpod/BLoC for shared state |
|
|
179
|
+
| `FutureBuilder` with inline `Future` | Re-fetches on every rebuild | Cache Future in `initState` or use `AsyncNotifier` |
|
|
180
|
+
| Missing `const` constructors | Unnecessary rebuilds every frame | Add `const` to every eligible constructor |
|
|
181
|
+
| `print()` for debugging | No log levels, clutters output | Use `dart:developer` `log()` or `logger` package |
|
|
182
|
+
| `dynamic` types everywhere | No compile-time safety | Strong typing with generics + `freezed` |
|
|
183
|
+
| Business logic in `build()` | Untestable, mixed concerns | Separate into providers/blocs/services |
|
|
184
|
+
| Ignoring `dispose()` | Memory leaks (streams, controllers) | Always dispose controllers, subscriptions |
|
|
185
|
+
| Platform channels for simple tasks | Complex, error-prone | Use existing plugins (`url_launcher`, etc.) |
|
|
186
|
+
| Single massive `lib/main.dart` | Impossible to navigate or test | Feature-based folder structure |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Testing
|
|
191
|
+
|
|
192
|
+
| Layer | Tool | Purpose |
|
|
193
|
+
|-------|------|---------|
|
|
194
|
+
| **Unit** | `flutter_test` + `mocktail` | Business logic, providers, repositories |
|
|
195
|
+
| **Widget** | `flutter_test` (widget testing) | Component rendering and interaction |
|
|
196
|
+
| **BLoC** | `bloc_test` | State machine transitions |
|
|
197
|
+
| **Integration** | `integration_test` package | Full app flows on real device/emulator |
|
|
198
|
+
| **Golden** | `golden_toolkit` | Visual regression (screenshot comparison) |
|
|
199
|
+
|
|
200
|
+
**Testing principles:**
|
|
201
|
+
- Test behavior through public API, not widget internals
|
|
202
|
+
- Use `pumpWidget` + `pumpAndSettle` for async widget tests
|
|
203
|
+
- Mock dependencies at the repository/service boundary
|
|
204
|
+
- Golden tests for design-system components (catch visual regressions)
|
|
205
|
+
|
|
206
|
+
```dart
|
|
207
|
+
testWidgets('shows login button', (tester) async {
|
|
208
|
+
await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
|
|
209
|
+
expect(find.text('Log In'), findsOneWidget);
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Deployment & Distribution
|
|
216
|
+
|
|
217
|
+
### Build Commands
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Debug (hot reload enabled)
|
|
221
|
+
flutter run
|
|
222
|
+
|
|
223
|
+
# Release build
|
|
224
|
+
flutter build apk --release # Android APK
|
|
225
|
+
flutter build appbundle --release # Android App Bundle (Play Store)
|
|
226
|
+
flutter build ipa --release # iOS (requires Xcode)
|
|
227
|
+
|
|
228
|
+
# Analyze app size
|
|
229
|
+
flutter build apk --analyze-size
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### CI/CD Options
|
|
233
|
+
|
|
234
|
+
| Tool | Strength |
|
|
235
|
+
|------|----------|
|
|
236
|
+
| **Codemagic** | Flutter-first CI/CD, code signing built-in |
|
|
237
|
+
| **Fastlane** | Flexible, widely adopted, multi-platform |
|
|
238
|
+
| **GitHub Actions** | Free for open source, custom workflows |
|
|
239
|
+
| **Bitrise** | Mobile-focused, visual workflow builder |
|
|
240
|
+
|
|
241
|
+
### OTA Code Push
|
|
242
|
+
|
|
243
|
+
**Shorebird** — Flutter's code push solution. Push Dart code updates without app store review.
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Initialize Shorebird
|
|
247
|
+
shorebird init
|
|
248
|
+
|
|
249
|
+
# Create a release
|
|
250
|
+
shorebird release android
|
|
251
|
+
shorebird release ios
|
|
252
|
+
|
|
253
|
+
# Push a patch
|
|
254
|
+
shorebird patch android
|
|
255
|
+
shorebird patch ios
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Limitations:** Dart code only — native code changes still require full build + store submission.
|
|
259
|
+
|
|
260
|
+
### App Size Optimization
|
|
261
|
+
- Use `--split-per-abi` for Android to reduce per-device APK size
|
|
262
|
+
- Enable `--obfuscate --split-debug-info=symbols/` for release builds
|
|
263
|
+
- Use deferred components for large features (lazy loading)
|
|
264
|
+
- Audit unused packages with `dart pub outdated`
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Quick Reference — Granular Rules
|
|
269
|
+
|
|
270
|
+
Individual Dart skill files in `flutter-rules/` with detailed patterns and
|
|
271
|
+
best practices for the Dart language foundation that underpins Flutter development.
|
|
272
|
+
|
|
273
|
+
> Source: [kevmoo/dash_skills](https://github.com/kevmoo/dash_skills) — Agent Skills for Dart & Flutter ecosystem
|
|
274
|
+
|
|
275
|
+
### Dart Language & Best Practices
|
|
276
|
+
|
|
277
|
+
- [dart-best-practices.md](flutter-rules/dart-best-practices.md) — Dart coding best practices
|
|
278
|
+
- [dart-modern-features.md](flutter-rules/dart-modern-features.md) — Modern Dart features (patterns, records, sealed classes)
|
|
279
|
+
- [dart-cli-app-best-practices.md](flutter-rules/dart-cli-app-best-practices.md) — CLI app patterns
|
|
280
|
+
|
|
281
|
+
### Testing & Quality
|
|
282
|
+
|
|
283
|
+
- [dart-test-fundamentals.md](flutter-rules/dart-test-fundamentals.md) — Test patterns with `package:test`
|
|
284
|
+
- [dart-matcher-best-practices.md](flutter-rules/dart-matcher-best-practices.md) — Matcher expressions (expect, isA)
|
|
285
|
+
- [dart-checks-migration.md](flutter-rules/dart-checks-migration.md) — Migrating from `package:matcher` to `package:checks`
|
|
286
|
+
|
|
287
|
+
### Documentation & Maintenance
|
|
288
|
+
|
|
289
|
+
- [dart-doc-validation.md](flutter-rules/dart-doc-validation.md) — Doc comment validation
|
|
290
|
+
- [dart-package-maintenance.md](flutter-rules/dart-package-maintenance.md) — Package maintenance standards
|
|
291
|
+
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# iOS Native (SwiftUI / UIKit) Reference
|
|
2
|
+
|
|
3
|
+
> **Philosophy:** Platform-native, human-interface-first. Respect Apple's design language.
|
|
4
|
+
> SwiftUI for new code, UIKit for legacy and complex custom views.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Setup & Detection
|
|
9
|
+
|
|
10
|
+
**Stack indicators:** `*.xcodeproj`, `*.xcworkspace`, `Package.swift`, or `*.swift` files.
|
|
11
|
+
|
|
12
|
+
**Key config files:**
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `*.xcodeproj` / `*.xcworkspace` | Xcode project/workspace configuration |
|
|
17
|
+
| `Info.plist` | App metadata, permissions, capabilities |
|
|
18
|
+
| `Package.swift` | Swift Package Manager dependencies |
|
|
19
|
+
| `Podfile` | CocoaPods dependencies (legacy) |
|
|
20
|
+
| `*.entitlements` | App capabilities (push, iCloud, etc.) |
|
|
21
|
+
| `Assets.xcassets` | App icons, images, colors |
|
|
22
|
+
|
|
23
|
+
**Recommended project structure:**
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
MyApp/
|
|
27
|
+
App/
|
|
28
|
+
MyAppApp.swift # @main entry point
|
|
29
|
+
ContentView.swift # Root view
|
|
30
|
+
Features/
|
|
31
|
+
Auth/
|
|
32
|
+
Views/LoginView.swift
|
|
33
|
+
ViewModels/AuthViewModel.swift
|
|
34
|
+
Models/User.swift
|
|
35
|
+
Services/AuthService.swift
|
|
36
|
+
Home/
|
|
37
|
+
Views/HomeView.swift
|
|
38
|
+
ViewModels/HomeViewModel.swift
|
|
39
|
+
Shared/
|
|
40
|
+
Components/ # Reusable SwiftUI views
|
|
41
|
+
Extensions/ # Swift extensions
|
|
42
|
+
Services/ # Networking, storage
|
|
43
|
+
Utilities/ # Helpers
|
|
44
|
+
Resources/
|
|
45
|
+
Assets.xcassets
|
|
46
|
+
Localizable.xcstrings
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Architecture Patterns
|
|
52
|
+
|
|
53
|
+
### MVVM (Recommended for SwiftUI)
|
|
54
|
+
|
|
55
|
+
```swift
|
|
56
|
+
// ViewModel
|
|
57
|
+
@Observable
|
|
58
|
+
class ProfileViewModel {
|
|
59
|
+
var user: User?
|
|
60
|
+
var isLoading = false
|
|
61
|
+
var error: Error?
|
|
62
|
+
|
|
63
|
+
func loadProfile() async {
|
|
64
|
+
isLoading = true
|
|
65
|
+
defer { isLoading = false }
|
|
66
|
+
do {
|
|
67
|
+
user = try await userService.fetchProfile()
|
|
68
|
+
} catch {
|
|
69
|
+
self.error = error
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// View
|
|
75
|
+
struct ProfileView: View {
|
|
76
|
+
@State private var viewModel = ProfileViewModel()
|
|
77
|
+
|
|
78
|
+
var body: some View {
|
|
79
|
+
Group {
|
|
80
|
+
if viewModel.isLoading {
|
|
81
|
+
ProgressView()
|
|
82
|
+
} else if let user = viewModel.user {
|
|
83
|
+
UserProfileContent(user: user)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
.task { await viewModel.loadProfile() }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### State Management
|
|
92
|
+
|
|
93
|
+
| Property Wrapper | Use When |
|
|
94
|
+
|-----------------|----------|
|
|
95
|
+
| `@State` | View-local value types (toggles, text input) |
|
|
96
|
+
| `@Binding` | Pass write access to a child view |
|
|
97
|
+
| `@Observable` (iOS 17+) | ViewModel or shared model classes |
|
|
98
|
+
| `@Environment` | Inject dependencies or system values |
|
|
99
|
+
| `@AppStorage` | Persist simple values to UserDefaults |
|
|
100
|
+
|
|
101
|
+
**SwiftData** (iOS 17+) replaces Core Data for persistence:
|
|
102
|
+
|
|
103
|
+
```swift
|
|
104
|
+
@Model
|
|
105
|
+
class Task {
|
|
106
|
+
var title: String
|
|
107
|
+
var isComplete: Bool
|
|
108
|
+
var createdAt: Date
|
|
109
|
+
|
|
110
|
+
init(title: String) {
|
|
111
|
+
self.title = title
|
|
112
|
+
self.isComplete = false
|
|
113
|
+
self.createdAt = .now
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### The Composable Architecture (TCA)
|
|
119
|
+
|
|
120
|
+
For complex apps needing predictable state, testable effects, and feature composition:
|
|
121
|
+
- Centralized state tree with reducers
|
|
122
|
+
- Side effects managed through `Effect` type
|
|
123
|
+
- Built-in testing with `TestStore`
|
|
124
|
+
- Steep learning curve but excellent testability
|
|
125
|
+
|
|
126
|
+
### Navigation
|
|
127
|
+
|
|
128
|
+
**NavigationStack** (iOS 16+) — type-safe, value-driven navigation:
|
|
129
|
+
|
|
130
|
+
```swift
|
|
131
|
+
NavigationStack(path: $path) {
|
|
132
|
+
HomeView()
|
|
133
|
+
.navigationDestination(for: Item.self) { item in
|
|
134
|
+
ItemDetailView(item: item)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- Use `NavigationSplitView` for iPad/Mac adaptive layouts
|
|
140
|
+
- Use `sheet()` and `fullScreenCover()` for modals
|
|
141
|
+
- Deep link handling through `.onOpenURL`
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Performance Optimization
|
|
146
|
+
|
|
147
|
+
### Critical Thresholds
|
|
148
|
+
|
|
149
|
+
| Metric | Target | Investigate |
|
|
150
|
+
|--------|--------|-------------|
|
|
151
|
+
| App launch (time to first frame) | < 1s | > 2s |
|
|
152
|
+
| Memory (foreground) | < 100MB | > 200MB |
|
|
153
|
+
| UI frame rate | 60fps / 120fps (ProMotion) | < 60fps |
|
|
154
|
+
| Binary size | < 30MB | > 100MB |
|
|
155
|
+
|
|
156
|
+
### Key Optimizations
|
|
157
|
+
|
|
158
|
+
1. **`LazyVStack` / `LazyHStack`** — only creates views when they scroll into the visible area.
|
|
159
|
+
|
|
160
|
+
```swift
|
|
161
|
+
// ❌ Bad: creates all rows immediately
|
|
162
|
+
VStack { ForEach(items) { ItemRow(item: $0) } }
|
|
163
|
+
|
|
164
|
+
// ✅ Good: lazy, only visible rows created
|
|
165
|
+
LazyVStack { ForEach(items) { ItemRow(item: $0) } }
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
2. **Avoid recomputing views** — extract subviews, use `@Observable` fine-grained tracking.
|
|
169
|
+
|
|
170
|
+
3. **Background tasks** — use `BGTaskScheduler` for deferred work (push refresh, data sync). Minimize wake-ups for battery.
|
|
171
|
+
|
|
172
|
+
4. **Network monitoring** — use `NWPathMonitor` to detect connectivity changes and adapt behavior.
|
|
173
|
+
|
|
174
|
+
5. **Instruments profiling:**
|
|
175
|
+
- **Time Profiler** — find slow functions
|
|
176
|
+
- **Allocations** — track memory leaks
|
|
177
|
+
- **SwiftUI** instrument — identify excessive view body evaluations
|
|
178
|
+
- **Energy Log** — battery impact analysis
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Common Libraries Ecosystem
|
|
183
|
+
|
|
184
|
+
| Category | Recommended | Alternative |
|
|
185
|
+
|----------|-------------|-------------|
|
|
186
|
+
| **Networking** | `URLSession` (built-in) | `Alamofire` |
|
|
187
|
+
| **JSON** | `Codable` (built-in) | — |
|
|
188
|
+
| **Storage (simple)** | `UserDefaults` / `@AppStorage` | — |
|
|
189
|
+
| **Storage (encrypted)** | `Keychain Services` | `KeychainAccess` |
|
|
190
|
+
| **Database** | `SwiftData` (iOS 17+) | `Core Data`, `GRDB`, `Realm` |
|
|
191
|
+
| **Images** | `AsyncImage` (built-in) | `Kingfisher`, `Nuke` |
|
|
192
|
+
| **DI** | `@Environment` / manual | `Factory`, `Swinject` |
|
|
193
|
+
| **Analytics** | `Firebase Analytics` | `Mixpanel`, `Amplitude` |
|
|
194
|
+
| **Testing** | `Swift Testing` + `XCTest` | — |
|
|
195
|
+
| **Linting** | `SwiftLint` | `swift-format` |
|
|
196
|
+
| **Package Manager** | Swift Package Manager | CocoaPods (legacy) |
|
|
197
|
+
|
|
198
|
+
**Prefer built-in frameworks** — Apple provides excellent APIs. Only add third-party dependencies when built-in solutions are insufficient.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Anti-Patterns & Gotchas
|
|
203
|
+
|
|
204
|
+
| ❌ Don't | Why | ✅ Do Instead |
|
|
205
|
+
|----------|-----|---------------|
|
|
206
|
+
| Massive `body` properties (100+ lines) | SwiftUI compiles slow, unreadable | Extract into named subviews |
|
|
207
|
+
| Force unwrapping (`!`) | Crash at runtime | `guard let`, `if let`, or `??` with default |
|
|
208
|
+
| Missing `@MainActor` on UI updates | Crash from background thread | Annotate ViewModels with `@MainActor` |
|
|
209
|
+
| Synchronous network calls | Blocks main thread, UI freezes | `async/await` with `Task {}` |
|
|
210
|
+
| Ignoring `Sendable` (Swift 6) | Concurrency warnings → errors in Swift 6 | Mark types `Sendable`, use actors for mutable state |
|
|
211
|
+
| Core Data for new projects | Complex, boilerplate-heavy | SwiftData (iOS 17+) for new code |
|
|
212
|
+
| `ObservableObject` (legacy) | Less efficient than `@Observable` | Use `@Observable` macro (iOS 17+) |
|
|
213
|
+
| `AnyView` for type erasure | Breaks SwiftUI diffing, poor performance | Use `@ViewBuilder`, generics, or concrete types |
|
|
214
|
+
| Navigation via state booleans | Unscalable, unmaintainable | `NavigationStack` with value-based navigation |
|
|
215
|
+
| Tight coupling to UIKit | Limits SwiftUI adoption | Use `UIViewRepresentable` only when needed |
|
|
216
|
+
|
|
217
|
+
### Swift 6 Concurrency
|
|
218
|
+
|
|
219
|
+
Swift 6 enforces strict concurrency checking:
|
|
220
|
+
- All mutable shared state must be in `actor` or `@MainActor`
|
|
221
|
+
- Types crossing concurrency boundaries must conform to `Sendable`
|
|
222
|
+
- Enable strict concurrency checking early: `SWIFT_STRICT_CONCURRENCY = complete`
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Testing
|
|
227
|
+
|
|
228
|
+
| Layer | Tool | Purpose |
|
|
229
|
+
|-------|------|---------|
|
|
230
|
+
| **Unit** | `Swift Testing` (new) / `XCTest` | Logic, ViewModels, services |
|
|
231
|
+
| **UI** | `XCUITest` | Full UI flow automation |
|
|
232
|
+
| **Snapshot** | `swift-snapshot-testing` | Visual regression |
|
|
233
|
+
| **Performance** | `XCTest` + `measure {}` | Execution time benchmarks |
|
|
234
|
+
|
|
235
|
+
**Swift Testing** (Xcode 16+) replaces XCTest with modern syntax:
|
|
236
|
+
|
|
237
|
+
```swift
|
|
238
|
+
import Testing
|
|
239
|
+
|
|
240
|
+
@Test func userDisplayName() {
|
|
241
|
+
let user = User(first: "John", last: "Doe")
|
|
242
|
+
#expect(user.displayName == "John Doe")
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
@Test(arguments: ["", " ", " "])
|
|
246
|
+
func rejectsBlankNames(name: String) {
|
|
247
|
+
#expect(throws: ValidationError.self) {
|
|
248
|
+
try User(name: name)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
- Use `@MainActor` on tests that touch UI state
|
|
254
|
+
- Mock network with `URLProtocol` subclass — no third-party mock library needed
|
|
255
|
+
- Golden/snapshot testing for design-system components
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Deployment & Distribution
|
|
260
|
+
|
|
261
|
+
### Build & Release
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Archive for distribution
|
|
265
|
+
xcodebuild archive -scheme MyApp -archivePath build/MyApp.xcarchive
|
|
266
|
+
|
|
267
|
+
# Export IPA
|
|
268
|
+
xcodebuild -exportArchive -archivePath build/MyApp.xcarchive \
|
|
269
|
+
-exportOptionsPlist ExportOptions.plist -exportPath build/
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Distribution Channels
|
|
273
|
+
|
|
274
|
+
| Channel | Use When |
|
|
275
|
+
|---------|----------|
|
|
276
|
+
| **TestFlight** | Internal + external beta testing (up to 10,000 testers) |
|
|
277
|
+
| **App Store Connect** | Production release |
|
|
278
|
+
| **Ad Hoc** | Direct install for registered devices |
|
|
279
|
+
| **Enterprise** | In-house apps (requires Enterprise Program) |
|
|
280
|
+
|
|
281
|
+
### CI/CD
|
|
282
|
+
|
|
283
|
+
| Tool | Strength |
|
|
284
|
+
|------|----------|
|
|
285
|
+
| **Xcode Cloud** | Apple-native, integrated with App Store Connect |
|
|
286
|
+
| **Fastlane** | Community standard, `match` for code signing |
|
|
287
|
+
| **GitHub Actions** + `macos-latest` | Free for open source |
|
|
288
|
+
|
|
289
|
+
### Fastlane essentials
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Install
|
|
293
|
+
gem install fastlane
|
|
294
|
+
|
|
295
|
+
# Beta release
|
|
296
|
+
fastlane beta # build + upload to TestFlight
|
|
297
|
+
|
|
298
|
+
# Production release
|
|
299
|
+
fastlane release # build + upload to App Store
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Entitlements & Capabilities
|
|
303
|
+
- Configure in Xcode → Signing & Capabilities
|
|
304
|
+
- Push Notifications, In-App Purchase, iCloud, HealthKit each require specific entitlements
|
|
305
|
+
- App Groups for sharing data between app and extensions (widgets, intents)
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Quick Reference — Granular Rules
|
|
310
|
+
|
|
311
|
+
Individual SwiftUI reference files in `ios-rules/` with detailed patterns,
|
|
312
|
+
code examples, and best practices for modern iOS/macOS development.
|
|
313
|
+
|
|
314
|
+
> Source: [AvdLee/SwiftUI-Agent-Skill](https://github.com/AvdLee/SwiftUI-Agent-Skill) — SwiftUI Expert Skill by Antoine van der Lee
|
|
315
|
+
|
|
316
|
+
### State & Architecture
|
|
317
|
+
|
|
318
|
+
- [state-management.md](ios-rules/state-management.md) — Property wrappers, @Observable, data flow patterns
|
|
319
|
+
- [view-structure.md](ios-rules/view-structure.md) — View extraction, composition, identity stability
|
|
320
|
+
|
|
321
|
+
### View Composition & Layout
|
|
322
|
+
|
|
323
|
+
- [layout-best-practices.md](ios-rules/layout-best-practices.md) — Layout patterns, GeometryReader alternatives
|
|
324
|
+
- [scroll-patterns.md](ios-rules/scroll-patterns.md) — ScrollViewReader, programmatic scrolling
|
|
325
|
+
- [image-optimization.md](ios-rules/image-optimization.md) — AsyncImage, downsampling, caching
|
|
326
|
+
|
|
327
|
+
### Performance & Lists
|
|
328
|
+
|
|
329
|
+
- [performance-patterns.md](ios-rules/performance-patterns.md) — Hot-path optimizations, update control
|
|
330
|
+
- [list-patterns.md](ios-rules/list-patterns.md) — ForEach identity, list performance
|
|
331
|
+
|
|
332
|
+
### Animation
|
|
333
|
+
|
|
334
|
+
- [animation-basics.md](ios-rules/animation-basics.md) — Core concepts, implicit/explicit, timing
|
|
335
|
+
- [animation-advanced.md](ios-rules/animation-advanced.md) — Performance, interpolation, complex chains
|
|
336
|
+
- [animation-transitions.md](ios-rules/animation-transitions.md) — View transitions, matchedGeometryEffect
|
|
337
|
+
|
|
338
|
+
### Navigation & Sheets
|
|
339
|
+
|
|
340
|
+
- [sheet-navigation-patterns.md](ios-rules/sheet-navigation-patterns.md) — Sheets, type-safe navigation state
|
|
341
|
+
|
|
342
|
+
### Swift Charts
|
|
343
|
+
|
|
344
|
+
- [charts.md](ios-rules/charts.md) — Marks, axes, selection, styling, Chart3D
|
|
345
|
+
- [charts-accessibility.md](ios-rules/charts-accessibility.md) — Charts accessibility, fallback strategies
|
|
346
|
+
|
|
347
|
+
### macOS
|
|
348
|
+
|
|
349
|
+
- [macos-scenes.md](ios-rules/macos-scenes.md) — Scene lifecycle, multi-window, menu bar
|
|
350
|
+
- [macos-views.md](ios-rules/macos-views.md) — macOS-specific views, platform differences
|
|
351
|
+
- [macos-window-styling.md](ios-rules/macos-window-styling.md) — Window chrome, toolbar, title bar styling
|
|
352
|
+
|
|
353
|
+
### Modern APIs
|
|
354
|
+
|
|
355
|
+
- [liquid-glass.md](ios-rules/liquid-glass.md) — iOS 26+ glass effects, fallback patterns
|
|
356
|
+
- [latest-apis.md](ios-rules/latest-apis.md) — Deprecated-to-modern migration (iOS 15–26+)
|
|
357
|
+
- [accessibility-patterns.md](ios-rules/accessibility-patterns.md) — VoiceOver, Dynamic Type, traits
|
|
358
|
+
|