Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:28:37 +08:00
commit ccc65b3f07
180 changed files with 53970 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
# Workflow: Add a Feature to an Existing iOS App
<required_reading>
**Read these NOW:**
1. references/app-architecture.md
2. references/swiftui-patterns.md
**Plus relevant refs based on feature** (see Step 2).
</required_reading>
<process>
## Step 1: Understand the Feature
Ask:
- What should it do?
- Where does it belong in the app?
- Any constraints?
## Step 2: Read Relevant References
| Feature Type | Reference |
|--------------|-----------|
| Data persistence | references/data-persistence.md |
| Networking/API | references/networking.md |
| Push notifications | references/push-notifications.md |
| In-app purchases | references/storekit.md |
| Background tasks | references/background-tasks.md |
| Navigation | references/navigation-patterns.md |
| Polish/UX | references/polish-and-ux.md |
## Step 3: Understand Existing Code
Read:
- App entry point
- State management
- Related views
Identify patterns to follow.
## Step 4: Implement with TDD
1. Write test for new behavior → RED
2. Implement → GREEN
3. Refactor
4. Repeat
## Step 5: Integrate
- Wire up navigation
- Connect to state
- Handle errors
## Step 6: Build and Test
```bash
xcodebuild -scheme AppName -destination 'platform=iOS Simulator,name=iPhone 16' build test
xcrun simctl launch booted com.company.AppName
```
## Step 7: Polish
- Haptic feedback for actions
- Animations for transitions
- Accessibility labels
- Dynamic Type support
</process>
<integration_patterns>
**Adding state:**
```swift
@Observable
class AppState {
var newFeatureData: [NewType] = []
func performNewFeature() { ... }
}
```
**Adding a view:**
```swift
struct NewFeatureView: View {
@Environment(AppState.self) private var appState
var body: some View { ... }
}
```
**Adding navigation:**
```swift
NavigationLink("New Feature", value: NewFeatureDestination())
.navigationDestination(for: NewFeatureDestination.self) { _ in
NewFeatureView()
}
```
**Adding a tab:**
```swift
TabView {
NewFeatureView()
.tabItem { Label("New", systemImage: "star") }
}
```
</integration_patterns>

View File

@@ -0,0 +1,111 @@
# Workflow: Build a New iOS App
<required_reading>
**Read these reference files NOW before writing any code:**
1. references/project-scaffolding.md
2. references/cli-workflow.md
3. references/app-architecture.md
4. references/swiftui-patterns.md
</required_reading>
<process>
## Step 1: Clarify Requirements
Ask the user:
- What does the app do? (core functionality)
- What type? (single-screen, tab-based, navigation-based, data-driven)
- Any specific features? (persistence, networking, push notifications, purchases)
## Step 2: Choose App Archetype
| Type | When to Use | Key Patterns |
|------|-------------|--------------|
| Single-screen utility | One primary function | Minimal navigation |
| Tab-based (TabView) | Multiple equal sections | TabView with 3-5 tabs |
| Navigation-based | Hierarchical content | NavigationStack |
| Data-driven | User content library | SwiftData + @Query |
## Step 3: Scaffold Project
Use XcodeGen:
```bash
mkdir AppName && cd AppName
# Create project.yml (see references/project-scaffolding.md)
# Create Swift files in Sources/
xcodegen generate
```
## Step 4: Implement with TDD
1. Write failing test
2. Run → RED
3. Implement minimal code
4. Run → GREEN
5. Refactor
6. Repeat
## Step 5: Build and Launch
```bash
# Build
xcodebuild -project AppName.xcodeproj -scheme AppName \
-destination 'platform=iOS Simulator,name=iPhone 16' build 2>&1 | xcsift
# Launch in simulator
xcrun simctl boot "iPhone 16" 2>/dev/null || true
xcrun simctl install booted ./build/Build/Products/Debug-iphonesimulator/AppName.app
xcrun simctl launch booted com.company.AppName
```
## Step 6: Polish
Read references/polish-and-ux.md for:
- Haptic feedback
- Animations
- Accessibility
- Dynamic Type support
</process>
<minimum_viable_app>
```swift
import SwiftUI
@main
struct MyApp: App {
@State private var appState = AppState()
var body: some Scene {
WindowGroup {
ContentView()
.environment(appState)
}
}
}
@Observable
class AppState {
var items: [Item] = []
}
struct ContentView: View {
@Environment(AppState.self) private var appState
var body: some View {
NavigationStack {
List(appState.items) { item in
Text(item.name)
}
.navigationTitle("Items")
}
}
}
```
</minimum_viable_app>
<success_criteria>
- Follows iOS Human Interface Guidelines
- Builds and runs from CLI
- Tests pass
- Launches in simulator
- User can verify UX manually
</success_criteria>

View File

@@ -0,0 +1,115 @@
# Workflow: Debug an Existing iOS App
<required_reading>
**Read these reference files NOW:**
1. references/cli-observability.md
2. references/testing.md
</required_reading>
<philosophy>
Debugging is iterative. Use whatever gets you to root cause fastest:
- Small app, obvious symptom → read relevant code
- Large codebase, unclear cause → use tools to narrow down
- Code looks correct but fails → tools reveal runtime behavior
- After fixing → tools verify the fix
</philosophy>
<process>
## Step 1: Understand the Symptom
Ask:
- What's happening vs expected?
- When? (startup, after action, under load)
- Reproducible?
- Any error messages?
## Step 2: Build and Check for Compile Errors
```bash
xcodebuild -scheme AppName -destination 'platform=iOS Simulator,name=iPhone 16' build 2>&1 | xcsift
```
Fix compile errors first.
## Step 3: Choose Your Approach
**Know where problem is:** → Read that code
**No idea where to start:** → Use tools (Step 4)
**Code looks correct but fails:** → Runtime observation (Step 4)
## Step 4: Runtime Diagnostics
**Launch with logging:**
```bash
xcrun simctl boot "iPhone 16" 2>/dev/null || true
xcrun simctl install booted ./build/Build/Products/Debug-iphonesimulator/AppName.app
xcrun simctl launch --console booted com.company.AppName
```
**Match symptom to tool:**
| Symptom | Tool | Command |
|---------|------|---------|
| Memory leak | leaks | `leaks AppName` (on simulator process) |
| UI freeze | spindump | `spindump AppName` |
| Crash | crash report | Check Console.app or `~/Library/Logs/DiagnosticReports/` |
| Slow | profiler | `xcrun xctrace record --template 'Time Profiler'` |
| Silent failure | console | `xcrun simctl launch --console booted ...` |
## Step 5: Interpret & Read Relevant Code
Tool output tells you WHERE. Now read THAT code.
## Step 6: Fix the Root Cause
Not the symptom. The actual cause.
## Step 7: Verify
```bash
# Rebuild
xcodebuild build ...
# Run same diagnostic
# Confirm issue is resolved
```
## Step 8: Regression Test
Write a test that would catch this bug in future.
</process>
<common_patterns>
## Memory Leaks
**Cause:** Strong reference cycles in closures
**Fix:** `[weak self]` capture
## UI Freezes
**Cause:** Sync work on main thread
**Fix:** `Task { }` or `Task.detached { }`
## Crashes
**Cause:** Force unwrap, index out of bounds
**Fix:** `guard let`, bounds checking
## Silent Failures
**Cause:** Error swallowed, async not awaited
**Fix:** Add logging, check async chains
</common_patterns>
<ios_specific_tools>
```bash
# Console output from simulator
xcrun simctl spawn booted log stream --predicate 'subsystem == "com.company.AppName"'
# Install and launch
xcrun simctl install booted ./App.app
xcrun simctl launch --console booted com.company.AppName
# Screenshot
xcrun simctl io booted screenshot /tmp/screenshot.png
# Video recording
xcrun simctl io booted recordVideo /tmp/video.mp4
```
</ios_specific_tools>

View File

@@ -0,0 +1,125 @@
# Workflow: Optimize iOS App Performance
<required_reading>
**Read NOW:**
1. references/performance.md
2. references/cli-observability.md
</required_reading>
<philosophy>
Measure first, optimize second. Never optimize based on assumptions.
</philosophy>
<process>
## Step 1: Define the Problem
Ask:
- What feels slow?
- Startup? Scrolling? Specific action?
- When did it start?
## Step 2: Measure
**CPU Profiling:**
```bash
xcrun xctrace record \
--template 'Time Profiler' \
--device 'iPhone 16' \
--attach AppName \
--output profile.trace
```
**Memory:**
```bash
xcrun xctrace record --template 'Allocations' ...
```
**Launch time:**
```bash
# Add DYLD_PRINT_STATISTICS=1 to scheme environment
```
## Step 3: Identify Bottlenecks
Look for:
- Functions with high "self time"
- Main thread blocking
- Repeated expensive operations
- Large allocations
**SwiftUI re-renders:**
```swift
var body: some View {
let _ = Self._printChanges()
// ...
}
```
## Step 4: Common Optimizations
### Main Thread
```swift
// Bad
let data = expensiveWork() // blocks UI
// Good
let data = await Task.detached { expensiveWork() }.value
```
### SwiftUI
```swift
// Bad - rebuilds everything
struct BigView: View {
@State var a, b, c, d, e
}
// Good - isolated state
struct BigView: View {
var body: some View {
SubViewA() // has own @State
SubViewB() // has own @State
}
}
```
### Lists
```swift
// Use LazyVStack for long lists
ScrollView {
LazyVStack {
ForEach(items) { ... }
}
}
```
### Images
```swift
AsyncImage(url: url) { image in
image.resizable()
} placeholder: {
ProgressView()
}
```
## Step 5: Measure Again
Did it improve? If not, revert.
## Step 6: Performance Tests
```swift
func testScrollPerformance() {
measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
// scroll simulation
}
}
```
</process>
<targets>
| Metric | Target | Unacceptable |
|--------|--------|--------------|
| Launch | < 1s | > 2s |
| Scroll | 60 fps | < 30 fps |
| Response | < 100ms | > 500ms |
</targets>

View File

@@ -0,0 +1,122 @@
# Workflow: Ship iOS App
<required_reading>
**Read NOW:**
1. references/app-store.md
2. references/ci-cd.md
</required_reading>
<process>
## Step 1: Pre-Release Checklist
- [ ] Version/build numbers updated
- [ ] No debug code or test data
- [ ] Privacy manifest complete (PrivacyInfo.xcprivacy)
- [ ] App icons all sizes (see references/app-icons.md)
- [ ] Screenshots prepared
- [ ] Release notes written
## Step 2: Archive
```bash
xcodebuild archive \
-project AppName.xcodeproj \
-scheme AppName \
-archivePath ./build/AppName.xcarchive \
-destination 'generic/platform=iOS'
```
## Step 3: Export for Distribution
**For TestFlight/App Store:**
```bash
xcodebuild -exportArchive \
-archivePath ./build/AppName.xcarchive \
-exportPath ./build/export \
-exportOptionsPlist ExportOptions.plist
```
ExportOptions.plist:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store-connect</string>
<key>signingStyle</key>
<string>automatic</string>
</dict>
</plist>
```
## Step 4: Upload to App Store Connect
```bash
xcrun altool --upload-app \
-f ./build/export/AppName.ipa \
-t ios \
--apiKey YOUR_KEY_ID \
--apiIssuer YOUR_ISSUER_ID
```
Or use `xcrun notarytool` with App Store Connect API.
## Step 5: TestFlight
1. Wait for processing in App Store Connect
2. Add testers (internal or external)
3. Gather feedback
4. Iterate
## Step 6: App Store Submission
In App Store Connect:
1. Complete app metadata
2. Add screenshots for all device sizes
3. Set pricing
4. Submit for review
## Step 7: Post-Release
- Monitor crash reports
- Respond to reviews
- Plan next version
</process>
<privacy_manifest>
Required since iOS 17. Create `PrivacyInfo.xcprivacy`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
```
</privacy_manifest>
<common_rejections>
| Reason | Fix |
|--------|-----|
| Crash on launch | Test on real device, check entitlements |
| Missing privacy descriptions | Add all NS*UsageDescription keys |
| Broken links | Verify all URLs work |
| Incomplete metadata | Fill all required fields |
| Guideline 4.3 (spam) | Differentiate from existing apps |
</common_rejections>

View File

@@ -0,0 +1,101 @@
# Workflow: Write and Run Tests
<required_reading>
**Read NOW:**
1. references/testing.md
</required_reading>
<philosophy>
Tests are documentation that runs. They let the user verify correctness without reading code.
</philosophy>
<process>
## Step 1: Understand What to Test
**Claude tests (automated):**
- Core logic
- State management
- Service layer
- Edge cases
**User tests (manual):**
- UX feel
- Visual polish
- Real device behavior
## Step 2: Write Tests
### Unit Tests
```swift
import Testing
@testable import AppName
struct ItemTests {
@Test func creation() {
let item = Item(name: "Test")
#expect(item.name == "Test")
}
@Test func validation() {
let empty = Item(name: "")
#expect(!empty.isValid)
}
}
```
### Async Tests
```swift
@Test func fetchItems() async throws {
let service = MockService()
let items = try await service.fetch()
#expect(items.count > 0)
}
```
### State Tests
```swift
@Test func addItem() {
let state = AppState()
state.addItem(Item(name: "New"))
#expect(state.items.count == 1)
}
```
## Step 3: Run Tests
```bash
xcodebuild test \
-project AppName.xcodeproj \
-scheme AppName \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-resultBundlePath TestResults.xcresult
# Summary
xcrun xcresulttool get test-results summary --path TestResults.xcresult
```
## Step 4: Coverage
```bash
xcodebuild test -enableCodeCoverage YES ...
xcrun xccov view --report TestResults.xcresult
```
## Step 5: TDD Cycle
For new features:
1. Write failing test
2. Run → RED
3. Implement minimum
4. Run → GREEN
5. Refactor
6. Repeat
</process>
<coverage_targets>
| Code Type | Target |
|-----------|--------|
| Business logic | 80-100% |
| State management | 70-90% |
| Views | 0% (manual) |
</coverage_targets>