@haposoft/cafekit 0.16.0-rc.8 → 0.16.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/README.md +116 -27
- package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
- package/bin/__tests__/codex-hooks.test.js +50 -0
- package/bin/__tests__/codex-native.test.js +1882 -70
- package/bin/__tests__/develop-contract.test.js +400 -23
- package/bin/__tests__/installer-safety.test.js +3 -3
- package/bin/__tests__/optional-skill-inventory.test.js +249 -0
- package/bin/__tests__/output-styles.test.js +214 -0
- package/bin/__tests__/package-inventory.test.js +1735 -98
- package/bin/__tests__/runtime-schema.test.js +111 -0
- package/bin/__tests__/secret-output-guardrail.test.js +122 -0
- package/bin/__tests__/skill-routing-source.test.js +172 -0
- package/bin/__tests__/specs-v2-execution-closeout.test.js +1 -1
- package/bin/install.js +10 -0
- package/bin/lib/codex-install.js +170 -5
- package/bin/lib/context.js +14 -0
- package/bin/lib/i18n.js +12 -6
- package/bin/lib/skill-deps.js +5 -5
- package/bin/phases/claude-runtime.js +23 -0
- package/bin/phases/claude-settings.js +8 -0
- package/bin/phases/codex-hooks.js +156 -0
- package/bin/phases/codex-runtime.js +29 -38
- package/bin/phases/copy-payload.js +8 -2
- package/bin/phases/select-skill-bundles.js +96 -0
- package/bin/phases/skill-inventory.js +71 -0
- package/bin/phases/skills-setup.js +9 -2
- package/bin/phases/write-metadata.js +8 -5
- package/package.json +8 -2
- package/src/claude/CLAUDE.md +3 -3
- package/src/claude/agents/brainstormer.md +52 -69
- package/src/claude/agents/code-auditor.md +32 -14
- package/src/claude/agents/debugger.md +35 -20
- package/src/claude/agents/deployer.md +12 -5
- package/src/claude/agents/docs-keeper.md +11 -1
- package/src/claude/agents/implementer.md +25 -13
- package/src/claude/agents/inspector.md +6 -3
- package/src/claude/agents/project-manager.md +1 -1
- package/src/claude/agents/researcher.md +26 -55
- package/src/claude/agents/spec-maker.md +12 -7
- package/src/claude/agents/strategist.md +52 -0
- package/src/claude/agents/test-runner.md +117 -132
- package/src/claude/agents/ui-ux-designer.md +1 -1
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -0
- package/src/claude/hooks/__tests__/precompact.test.js +158 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +10 -3
- package/src/claude/hooks/__tests__/state.test.js +5 -0
- package/src/claude/hooks/__tests__/statusline.test.js +196 -0
- package/src/claude/hooks/agent.cjs +1 -1
- package/src/claude/hooks/docs-sync.cjs +12 -10
- package/src/claude/hooks/inspect-block.cjs +1 -1
- package/src/claude/hooks/lib/config.cjs +3 -0
- package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
- package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
- package/src/claude/hooks/precompact.cjs +105 -0
- package/src/claude/hooks/rules.cjs +1 -1
- package/src/claude/hooks/secret-output-guardrail.cjs +43 -0
- package/src/claude/hooks/session.cjs +27 -1
- package/src/claude/hooks/spec-gate.cjs +3 -3
- package/src/claude/hooks/spec-state.cjs +2 -2
- package/src/claude/hooks/state.cjs +1 -1
- package/src/claude/hooks/task-scaffold-guard.cjs +1 -1
- package/src/claude/hooks/usage.cjs +1 -1
- package/src/claude/migration-manifest.json +29 -15
- package/src/claude/output-styles/coding-level-0-eli5.md +103 -0
- package/src/claude/output-styles/coding-level-1-junior.md +124 -0
- package/src/claude/output-styles/coding-level-2-mid.md +146 -0
- package/src/claude/output-styles/coding-level-3-senior.md +148 -0
- package/src/claude/output-styles/coding-level-4-lead.md +159 -0
- package/src/claude/output-styles/coding-level-5-god.md +91 -0
- package/src/claude/references/debugger/core-philosophy.md +5 -3
- package/src/claude/references/debugger/frontend-verification.md +2 -2
- package/src/claude/references/debugger/log-ci-analysis.md +13 -1
- package/src/claude/references/debugger/parallel-agent-hydration.md +19 -34
- package/src/claude/references/debugger/performance-diagnostics.md +2 -2
- package/src/claude/references/debugger/root-cause-tracing.md +37 -6
- package/src/claude/references/debugger/side-effect-gate.md +3 -1
- package/src/claude/references/debugger/verification-protocol.md +13 -12
- package/src/claude/rules/orchestrator.md +7 -1
- package/src/claude/rules/process-management.md +39 -0
- package/src/claude/rules/review-audit-self-decision.md +48 -0
- package/src/claude/rules/skill-domain-routing.md +26 -24
- package/src/claude/rules/skill-workflow-routing.md +22 -14
- package/src/claude/rules/workflow.md +3 -3
- package/src/claude/runtime.json +1 -0
- package/src/claude/runtime.schema.json +205 -0
- package/src/claude/scripts/generate-skill-catalog.cjs +156 -122
- package/src/claude/scripts/provenance.cjs +18 -5
- package/src/claude/scripts/workflow-policy.cjs +1 -1
- package/src/claude/settings/settings.json +16 -0
- package/src/claude/skills/agent-browser/SKILL.md +1 -1
- package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
- package/src/claude/skills/brainstorm/SKILL.md +193 -172
- package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
- package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
- package/src/claude/skills/code-review/SKILL.md +43 -25
- package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
- package/src/claude/skills/code-review/references/verification-gate.md +1 -1
- package/src/claude/skills/debug/SKILL.md +48 -19
- package/src/claude/skills/delegate/SKILL.md +1 -1
- package/src/claude/skills/develop/SKILL.md +92 -65
- package/src/claude/skills/develop/references/parallel-waves.md +36 -63
- package/src/claude/skills/develop/references/quality-gate.md +31 -4
- package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
- package/src/claude/skills/docs/SKILL.md +42 -23
- package/src/claude/skills/docs/references/init-workflow.md +4 -4
- package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
- package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
- package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +9 -7
- package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
- package/src/claude/skills/docx/SKILL.md +1 -1
- package/src/claude/skills/git/SKILL.md +1 -1
- package/src/claude/skills/git/references/commit-protocols.md +1 -1
- package/src/claude/skills/git/references/finish-branch.md +1 -1
- package/src/claude/skills/hotfix/SKILL.md +159 -170
- package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
- package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
- package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
- package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
- package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
- package/src/claude/skills/inspect/SKILL.md +55 -46
- package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
- package/src/claude/skills/loop/SKILL.md +114 -0
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
- package/src/claude/skills/pdf/SKILL.md +1 -1
- package/src/claude/skills/pptx/SKILL.md +1 -1
- package/src/claude/skills/question/SKILL.md +16 -13
- package/src/claude/skills/research/SKILL.md +70 -43
- package/src/claude/skills/route/SKILL.md +94 -0
- package/src/claude/skills/route/references/agent-timing.md +46 -0
- package/src/claude/skills/route/references/chaining-patterns.md +53 -0
- package/src/claude/skills/route/references/task-taxonomy.md +48 -0
- package/src/claude/skills/specs/SKILL.md +41 -60
- package/src/claude/skills/specs/references/review.md +11 -8
- package/src/claude/skills/specs/references/templates.md +34 -18
- package/src/claude/skills/specs/templates/requirements-init.md +1 -1
- package/src/claude/skills/specs/templates/research.md +2 -2
- package/src/claude/skills/sync/SKILL.md +6 -6
- package/src/claude/skills/sync/references/sync-protocols.md +1 -1
- package/src/claude/skills/test/SKILL.md +120 -120
- package/src/claude/skills/test/references/execution-strategy.md +208 -361
- package/src/claude/skills/test/references/failure-triage.md +55 -121
- package/src/claude/skills/test/references/test-memory.md +20 -34
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/src/claude/skills/web-testing/SKILL.md +1 -1
- package/src/claude/skills/xlsx/SKILL.md +1 -1
- package/src/claude/status.cjs +135 -33
- package/src/codex/AGENTS.md +14 -4
- package/src/codex/hooks/docs-sync.cjs +8 -3
- package/src/codex/hooks/lib/hook-context.cjs +18 -4
- package/src/codex/hooks/rules.cjs +29 -1
- package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
- package/src/codex/hooks/spec-gate.cjs +3 -8
- package/src/codex/hooks/spec-state.cjs +2 -1
- package/src/codex/hooks.json +5 -0
- package/src/codex/runtime.json +2 -0
- package/src/common/.env.example +1 -1
- package/src/claude/skills/backend-development/SKILL.md +0 -101
- package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
- package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
- package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
- package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
- package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
- package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
- package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
- package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
- package/src/claude/skills/backend-development/references/backend-security.md +0 -342
- package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
- package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
- package/src/claude/skills/devops/.env.example +0 -76
- package/src/claude/skills/devops/SKILL.md +0 -102
- package/src/claude/skills/devops/references/browser-rendering.md +0 -305
- package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
- package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
- package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
- package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
- package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
- package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
- package/src/claude/skills/devops/references/docker-basics.md +0 -297
- package/src/claude/skills/devops/references/docker-compose.md +0 -292
- package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
- package/src/claude/skills/devops/references/gcloud-services.md +0 -304
- package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
- package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
- package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
- package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
- package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
- package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
- package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
- package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
- package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
- package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
- package/src/claude/skills/devops/scripts/requirements.txt +0 -20
- package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
- package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
- package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
- package/src/claude/skills/frontend-design/SKILL.md +0 -135
- package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
- package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
- package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
- package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
- package/src/claude/skills/frontend-design/references/animejs.md +0 -396
- package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
- package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
- package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
- package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
- package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
- package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
- package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
- package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
- package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
- package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
- package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
- package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
- package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
- package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
- package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
- package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
- package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
- package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
- package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
- package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
- package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
- package/src/claude/skills/frontend-development/SKILL.md +0 -406
- package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
- package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
- package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
- package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
- package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
- package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
- package/src/claude/skills/frontend-development/resources/performance.md +0 -406
- package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
- package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
- package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
- package/src/claude/skills/mobile-development/SKILL.md +0 -218
- package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
- package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
- package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
- package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
- package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
- package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
- package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
- package/src/claude/skills/react-best-practices/README.md +0 -123
- package/src/claude/skills/react-best-practices/SKILL.md +0 -128
- package/src/claude/skills/react-best-practices/metadata.json +0 -15
- package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
- package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
- package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
- package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
- package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
- package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
- package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
- package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
- package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
- package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
- package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
- package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
- package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
- package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
- package/src/claude/skills/react-best-practices/rules/server-serialization.md +0 -38
|
@@ -1,496 +0,0 @@
|
|
|
1
|
-
# iOS Native Development
|
|
2
|
-
|
|
3
|
-
Complete guide to iOS development with Swift and SwiftUI (2024-2025).
|
|
4
|
-
|
|
5
|
-
## Swift 6 Overview
|
|
6
|
-
|
|
7
|
-
### Key Features
|
|
8
|
-
- **Data race safety**: Compile-time detection (default in Swift 6)
|
|
9
|
-
- **Concurrency**: async/await, actors, @MainActor
|
|
10
|
-
- **Macro system**: Code generation at compile time
|
|
11
|
-
- **Move semantics**: Ownership optimization
|
|
12
|
-
- **Enhanced generics**: More powerful type system
|
|
13
|
-
|
|
14
|
-
### Modern Swift Patterns
|
|
15
|
-
|
|
16
|
-
**Async/Await:**
|
|
17
|
-
```swift
|
|
18
|
-
func fetchUser(id: String) async throws -> User {
|
|
19
|
-
let (data, _) = try await URLSession.shared.data(from: url)
|
|
20
|
-
return try JSONDecoder().decode(User.self, from: data)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Usage
|
|
24
|
-
Task {
|
|
25
|
-
do {
|
|
26
|
-
let user = try await fetchUser(id: "123")
|
|
27
|
-
self.user = user
|
|
28
|
-
} catch {
|
|
29
|
-
self.error = error
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**Actors (Thread-safe classes):**
|
|
35
|
-
```swift
|
|
36
|
-
actor UserCache {
|
|
37
|
-
private var cache: [String: User] = [:]
|
|
38
|
-
|
|
39
|
-
func get(_ id: String) -> User? {
|
|
40
|
-
cache[id]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func set(_ id: String, user: User) {
|
|
44
|
-
cache[id] = user
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## SwiftUI vs UIKit
|
|
50
|
-
|
|
51
|
-
### When to Use SwiftUI
|
|
52
|
-
✅ New projects (iOS 13+)
|
|
53
|
-
✅ Declarative UI preferred
|
|
54
|
-
✅ Fast iteration needed
|
|
55
|
-
✅ Cross-platform (macOS, watchOS, tvOS)
|
|
56
|
-
✅ Less code vs UIKit
|
|
57
|
-
|
|
58
|
-
### When to Use UIKit
|
|
59
|
-
✅ Legacy app maintenance
|
|
60
|
-
✅ Complex customizations
|
|
61
|
-
✅ Fine-grained control needed
|
|
62
|
-
✅ Specific UIKit features required
|
|
63
|
-
✅ Pre-iOS 13 support
|
|
64
|
-
|
|
65
|
-
### SwiftUI Basics
|
|
66
|
-
|
|
67
|
-
```swift
|
|
68
|
-
struct ContentView: View {
|
|
69
|
-
@State private var count = 0
|
|
70
|
-
|
|
71
|
-
var body: some View {
|
|
72
|
-
VStack(spacing: 20) {
|
|
73
|
-
Text("Count: \(count)")
|
|
74
|
-
.font(.title)
|
|
75
|
-
|
|
76
|
-
Button("Increment") {
|
|
77
|
-
count += 1
|
|
78
|
-
}
|
|
79
|
-
.buttonStyle(.borderedProminent)
|
|
80
|
-
}
|
|
81
|
-
.padding()
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**Property Wrappers:**
|
|
87
|
-
- `@State`: View-local state
|
|
88
|
-
- `@Binding`: Two-way binding
|
|
89
|
-
- `@StateObject`: Observable object owner
|
|
90
|
-
- `@ObservedObject`: Observable object reference
|
|
91
|
-
- `@EnvironmentObject`: Dependency injection
|
|
92
|
-
- `@Published`: Observable property
|
|
93
|
-
|
|
94
|
-
## Architecture Patterns
|
|
95
|
-
|
|
96
|
-
### MVVM (Most Popular)
|
|
97
|
-
|
|
98
|
-
```swift
|
|
99
|
-
// Model
|
|
100
|
-
struct User: Identifiable, Codable {
|
|
101
|
-
let id: String
|
|
102
|
-
let name: String
|
|
103
|
-
let email: String
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// ViewModel
|
|
107
|
-
@MainActor
|
|
108
|
-
class UserViewModel: ObservableObject {
|
|
109
|
-
@Published var users: [User] = []
|
|
110
|
-
@Published var isLoading = false
|
|
111
|
-
@Published var error: Error?
|
|
112
|
-
|
|
113
|
-
private let repository: UserRepository
|
|
114
|
-
|
|
115
|
-
init(repository: UserRepository = UserRepository()) {
|
|
116
|
-
self.repository = repository
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
func loadUsers() async {
|
|
120
|
-
isLoading = true
|
|
121
|
-
defer { isLoading = false }
|
|
122
|
-
|
|
123
|
-
do {
|
|
124
|
-
users = try await repository.fetchUsers()
|
|
125
|
-
} catch {
|
|
126
|
-
self.error = error
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// View
|
|
132
|
-
struct UserListView: View {
|
|
133
|
-
@StateObject private var viewModel = UserViewModel()
|
|
134
|
-
|
|
135
|
-
var body: some View {
|
|
136
|
-
List(viewModel.users) { user in
|
|
137
|
-
Text(user.name)
|
|
138
|
-
}
|
|
139
|
-
.task {
|
|
140
|
-
await viewModel.loadUsers()
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### TCA (The Composable Architecture)
|
|
147
|
-
|
|
148
|
-
**When to use:**
|
|
149
|
-
- Complex state management
|
|
150
|
-
- Predictable state updates
|
|
151
|
-
- Excellent testing
|
|
152
|
-
- Enterprise apps
|
|
153
|
-
|
|
154
|
-
**Trade-offs:**
|
|
155
|
-
- Steeper learning curve
|
|
156
|
-
- More boilerplate
|
|
157
|
-
- Excellent for large teams
|
|
158
|
-
|
|
159
|
-
## Performance Optimization
|
|
160
|
-
|
|
161
|
-
### Compiler Optimizations
|
|
162
|
-
|
|
163
|
-
**1. Use `final` classes:**
|
|
164
|
-
```swift
|
|
165
|
-
final class FastClass {
|
|
166
|
-
// Compiler can optimize (no dynamic dispatch)
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
**2. Private methods:**
|
|
171
|
-
```swift
|
|
172
|
-
private func optimize() {
|
|
173
|
-
// Compiler can inline
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
**3. Whole-module optimization:**
|
|
178
|
-
```bash
|
|
179
|
-
# Build Settings
|
|
180
|
-
SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Memory Management
|
|
184
|
-
|
|
185
|
-
**ARC (Automatic Reference Counting):**
|
|
186
|
-
```swift
|
|
187
|
-
class Parent {
|
|
188
|
-
var child: Child?
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
class Child {
|
|
192
|
-
weak var parent: Parent? // Weak to avoid retain cycle
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Common Retain Cycles:**
|
|
197
|
-
```swift
|
|
198
|
-
// ❌ Bad: Retain cycle
|
|
199
|
-
class ViewController: UIViewController {
|
|
200
|
-
var completion: (() -> Void)?
|
|
201
|
-
|
|
202
|
-
func setup() {
|
|
203
|
-
completion = {
|
|
204
|
-
self.doSomething() // Strong capture
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// ✅ Good: Weak self
|
|
210
|
-
class ViewController: UIViewController {
|
|
211
|
-
var completion: (() -> Void)?
|
|
212
|
-
|
|
213
|
-
func setup() {
|
|
214
|
-
completion = { [weak self] in
|
|
215
|
-
self?.doSomething()
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### SwiftUI Performance
|
|
222
|
-
|
|
223
|
-
**1. Use const modifiers:**
|
|
224
|
-
```swift
|
|
225
|
-
Text("Hello") // Recreated on every render
|
|
226
|
-
|
|
227
|
-
vs
|
|
228
|
-
|
|
229
|
-
Text("Hello")
|
|
230
|
-
.font(.title) // Modifier creates new view
|
|
231
|
-
|
|
232
|
-
// Better: Extract static views
|
|
233
|
-
let titleText = Text("Hello").font(.title)
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**2. Avoid expensive computations:**
|
|
237
|
-
```swift
|
|
238
|
-
struct ExpensiveView: View {
|
|
239
|
-
let data: [Item]
|
|
240
|
-
|
|
241
|
-
// Computed every render
|
|
242
|
-
var sortedData: [Item] {
|
|
243
|
-
data.sorted() // ❌ Bad
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Better: Cache with @State or pass sorted
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Testing Strategies
|
|
251
|
-
|
|
252
|
-
### XCTest (Unit Testing)
|
|
253
|
-
|
|
254
|
-
```swift
|
|
255
|
-
import XCTest
|
|
256
|
-
@testable import MyApp
|
|
257
|
-
|
|
258
|
-
final class UserViewModelTests: XCTestCase {
|
|
259
|
-
var viewModel: UserViewModel!
|
|
260
|
-
var mockRepository: MockUserRepository!
|
|
261
|
-
|
|
262
|
-
override func setUp() {
|
|
263
|
-
super.setUp()
|
|
264
|
-
mockRepository = MockUserRepository()
|
|
265
|
-
viewModel = UserViewModel(repository: mockRepository)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
func testLoadUsers() async throws {
|
|
269
|
-
// Given
|
|
270
|
-
let expectedUsers = [User(id: "1", name: "Test", email: "test@example.com")]
|
|
271
|
-
mockRepository.usersToReturn = expectedUsers
|
|
272
|
-
|
|
273
|
-
// When
|
|
274
|
-
await viewModel.loadUsers()
|
|
275
|
-
|
|
276
|
-
// Then
|
|
277
|
-
XCTAssertEqual(viewModel.users, expectedUsers)
|
|
278
|
-
XCTAssertFalse(viewModel.isLoading)
|
|
279
|
-
XCTAssertNil(viewModel.error)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### XCUITest (UI Testing)
|
|
285
|
-
|
|
286
|
-
```swift
|
|
287
|
-
import XCTest
|
|
288
|
-
|
|
289
|
-
final class LoginUITests: XCTestCase {
|
|
290
|
-
let app = XCUIApplication()
|
|
291
|
-
|
|
292
|
-
override func setUp() {
|
|
293
|
-
super.setUp()
|
|
294
|
-
app.launch()
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
func testLoginFlow() {
|
|
298
|
-
let emailField = app.textFields["emailField"]
|
|
299
|
-
emailField.tap()
|
|
300
|
-
emailField.typeText("test@example.com")
|
|
301
|
-
|
|
302
|
-
let passwordField = app.secureTextFields["passwordField"]
|
|
303
|
-
passwordField.tap()
|
|
304
|
-
passwordField.typeText("password123")
|
|
305
|
-
|
|
306
|
-
app.buttons["loginButton"].tap()
|
|
307
|
-
|
|
308
|
-
XCTAssertTrue(app.staticTexts["Welcome"].waitForExistence(timeout: 5))
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
**Target Coverage:**
|
|
314
|
-
- Unit tests: 70-80%+
|
|
315
|
-
- Critical paths: 100%
|
|
316
|
-
- UI tests: Key user flows only (slow)
|
|
317
|
-
|
|
318
|
-
## iOS-Specific Features
|
|
319
|
-
|
|
320
|
-
### WidgetKit
|
|
321
|
-
|
|
322
|
-
```swift
|
|
323
|
-
import WidgetKit
|
|
324
|
-
import SwiftUI
|
|
325
|
-
|
|
326
|
-
struct SimpleWidget: Widget {
|
|
327
|
-
var body: some WidgetConfiguration {
|
|
328
|
-
StaticConfiguration(kind: "SimpleWidget", provider: Provider()) { entry in
|
|
329
|
-
SimpleWidgetView(entry: entry)
|
|
330
|
-
}
|
|
331
|
-
.configurationDisplayName("My Widget")
|
|
332
|
-
.description("This is my widget")
|
|
333
|
-
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Live Activities (iOS 16.1+)
|
|
339
|
-
|
|
340
|
-
```swift
|
|
341
|
-
import ActivityKit
|
|
342
|
-
|
|
343
|
-
struct OrderAttributes: ActivityAttributes {
|
|
344
|
-
struct ContentState: Codable, Hashable {
|
|
345
|
-
var status: String
|
|
346
|
-
var estimatedTime: Date
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
var orderId: String
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Start activity
|
|
353
|
-
let attributes = OrderAttributes(orderId: "123")
|
|
354
|
-
let initialState = OrderAttributes.ContentState(
|
|
355
|
-
status: "Preparing",
|
|
356
|
-
estimatedTime: Date().addingTimeInterval(1800)
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
let activity = try Activity.request(
|
|
360
|
-
attributes: attributes,
|
|
361
|
-
contentState: initialState
|
|
362
|
-
)
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### App Clips
|
|
366
|
-
|
|
367
|
-
**Characteristics:**
|
|
368
|
-
- <10MB size limit
|
|
369
|
-
- Fast, lightweight experiences
|
|
370
|
-
- No installation required
|
|
371
|
-
- Invoked via NFC, QR, Safari, Maps
|
|
372
|
-
|
|
373
|
-
## Human Interface Guidelines (HIG)
|
|
374
|
-
|
|
375
|
-
### Navigation Patterns
|
|
376
|
-
|
|
377
|
-
**Tab Bar:**
|
|
378
|
-
- 2-5 top-level sections
|
|
379
|
-
- Bottom placement
|
|
380
|
-
- Always visible
|
|
381
|
-
- Immediate navigation
|
|
382
|
-
|
|
383
|
-
**Navigation Bar:**
|
|
384
|
-
- Hierarchical navigation
|
|
385
|
-
- Back button automatic
|
|
386
|
-
- Title and actions
|
|
387
|
-
- Large/inline title modes
|
|
388
|
-
|
|
389
|
-
**Modal Presentation:**
|
|
390
|
-
- Interrupting tasks
|
|
391
|
-
- Self-contained flow
|
|
392
|
-
- Clear dismiss action
|
|
393
|
-
- Use sparingly
|
|
394
|
-
|
|
395
|
-
### Design Principles
|
|
396
|
-
|
|
397
|
-
**Clarity:**
|
|
398
|
-
- Legible text (minimum 11pt)
|
|
399
|
-
- Sufficient contrast (WCAG AA)
|
|
400
|
-
- Precise icons
|
|
401
|
-
|
|
402
|
-
**Deference:**
|
|
403
|
-
- Content first, UI second
|
|
404
|
-
- Translucent backgrounds
|
|
405
|
-
- Minimal UI elements
|
|
406
|
-
|
|
407
|
-
**Depth:**
|
|
408
|
-
- Layering (sheets, overlays)
|
|
409
|
-
- Visual hierarchy
|
|
410
|
-
- Motion provides meaning
|
|
411
|
-
|
|
412
|
-
### Colors
|
|
413
|
-
|
|
414
|
-
**System Colors:**
|
|
415
|
-
```swift
|
|
416
|
-
Color.primary // Adaptive black/white
|
|
417
|
-
Color.secondary // Gray
|
|
418
|
-
Color.accentColor // App tint color
|
|
419
|
-
Color(uiColor: .systemBlue)
|
|
420
|
-
Color(uiColor: .label)
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
**Dark Mode:**
|
|
424
|
-
```swift
|
|
425
|
-
// Automatic
|
|
426
|
-
Color.primary // Adapts to light/dark
|
|
427
|
-
|
|
428
|
-
// Custom
|
|
429
|
-
Color("CustomColor") // Define in Assets.xcassets
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
### SF Symbols
|
|
433
|
-
|
|
434
|
-
```swift
|
|
435
|
-
Image(systemName: "star.fill")
|
|
436
|
-
.foregroundColor(.yellow)
|
|
437
|
-
.font(.title)
|
|
438
|
-
|
|
439
|
-
// Rendering modes
|
|
440
|
-
Image(systemName: "heart.fill")
|
|
441
|
-
.symbolRenderingMode(.multicolor)
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
## App Store Requirements (2024-2025)
|
|
445
|
-
|
|
446
|
-
### SDK Requirements
|
|
447
|
-
- **Current**: Xcode 15+ with iOS 17 SDK (required as of April 2024)
|
|
448
|
-
- **Upcoming**: Xcode 16+ with iOS 18 SDK (recommended for 2025 submissions)
|
|
449
|
-
|
|
450
|
-
### Privacy
|
|
451
|
-
- **Privacy manifest**: Required for third-party SDKs
|
|
452
|
-
- **Tracking permission**: ATT framework for advertising
|
|
453
|
-
- **Privacy nutrition labels**: Accurate data collection info
|
|
454
|
-
- **Account deletion**: In-app deletion required
|
|
455
|
-
|
|
456
|
-
### Capabilities
|
|
457
|
-
- **Sandbox**: All apps sandboxed
|
|
458
|
-
- **Entitlements**: Request only needed capabilities
|
|
459
|
-
- **Background modes**: Justify background usage
|
|
460
|
-
- **HealthKit**: Privacy-sensitive, strict review
|
|
461
|
-
|
|
462
|
-
### Submission Checklist
|
|
463
|
-
✅ App icons (all required sizes)
|
|
464
|
-
✅ Screenshots (all device sizes)
|
|
465
|
-
✅ App description and keywords
|
|
466
|
-
✅ Privacy policy URL
|
|
467
|
-
✅ Support URL
|
|
468
|
-
✅ Age rating questionnaire
|
|
469
|
-
✅ Export compliance
|
|
470
|
-
✅ Test on real devices
|
|
471
|
-
✅ No crashes or major bugs
|
|
472
|
-
|
|
473
|
-
## Common Pitfalls
|
|
474
|
-
|
|
475
|
-
1. **Strong reference cycles**: Use `[weak self]` in closures
|
|
476
|
-
2. **Main thread blocking**: Use async/await, avoid sync operations
|
|
477
|
-
3. **Large images**: Resize before displaying
|
|
478
|
-
4. **Unhandled errors**: Always handle async throws
|
|
479
|
-
5. **Ignoring safe areas**: Use `.ignoresSafeArea()` intentionally
|
|
480
|
-
6. **Not testing dark mode**: Design for both appearances
|
|
481
|
-
7. **Hardcoded strings**: Use localization from start
|
|
482
|
-
8. **Memory leaks**: Profile with Instruments regularly
|
|
483
|
-
|
|
484
|
-
## Resources
|
|
485
|
-
|
|
486
|
-
**Official:**
|
|
487
|
-
- Swift Documentation: https://swift.org/documentation/
|
|
488
|
-
- SwiftUI Tutorials: https://developer.apple.com/tutorials/swiftui
|
|
489
|
-
- HIG: https://developer.apple.com/design/human-interface-guidelines/
|
|
490
|
-
- WWDC Videos: https://developer.apple.com/videos/
|
|
491
|
-
|
|
492
|
-
**Community:**
|
|
493
|
-
- Hacking with Swift: https://www.hackingwithswift.com/
|
|
494
|
-
- Swift by Sundell: https://www.swiftbysundell.com/
|
|
495
|
-
- objc.io: https://www.objc.io/
|
|
496
|
-
- iOS Dev Weekly: https://iosdevweekly.com/
|