by keskinonur
A comprehensive guide for setting up Claude Code CLI with PRD-driven workflows, extended thinking (ultrathink), and planning modes optimized for Swift/SwiftUI iOS development.
# Add to your Claude Code skills
git clone https://github.com/keskinonur/claude-code-ios-dev-guideA comprehensive guide for setting up Claude Code CLI with PRD-driven workflows, extended thinking (ultrathink), and planning modes optimized for Swift/SwiftUI iOS development.
# macOS/Linux - Native installer (no Node.js required)
curl -fsSL https://claude.ai/install.sh | bash
# Or install latest version
curl -fsSL https://claude.ai/install.sh | bash -s latest
No comments yet. Be the first to share your thoughts!
# Global npm install (do NOT use sudo)
npm install -g @anthropic-ai/claude-code
# Migrate existing npm install to native
claude install
# Start Claude Code and authenticate via OAuth
claude
# Or set API key environment variable
export ANTHROPIC_API_KEY="your-key-here"
# Use specific model at startup
claude --model claude-opus-4-5-20250929
claude --model claude-sonnet-4-5-20250929
claude --model claude-3-5-haiku-20241022
# Or set default model
export ANTHROPIC_MODEL="claude-sonnet-4-5-20250929"
Claude Code uses a layered configuration system where each level can override the one below:
Priority (Highest to Lowest):
├── 1. Session flags (--model, --permission-mode)
├── 2. Environment variables
├── 3. .claude/settings.local.json (local - personal, gitignored)
├── 4. .claude/settings.json (project - shared with team)
└── 5. ~/.claude/settings.json (user - global)
| Scope | Description | Storage |
|-------|-------------|---------|
| local | Available only to you in current project (default for MCP) | .claude/settings.local.json |
| project | Shared with team via git | .claude/settings.json, .mcp.json |
| user | Available across all your projects | ~/.claude/settings.json |
| File | Scope | Git Status | Purpose |
|------|-------|------------|---------|
| ~/.claude/settings.json | User | N/A | Global preferences |
| ~/.claude/CLAUDE.md | User | N/A | Global instructions |
| ~/.claude/skills/ | User | N/A | Personal Agent Skills |
| ~/.claude/commands/ | User | N/A | Personal slash commands |
| .claude/settings.json | Project | Committed | Team settings |
| .claude/settings.local.json | Local | Gitignored | Personal overrides |
| .mcp.json | Project | Committed | Shared MCP servers |
| CLAUDE.md | Project | Committed | Main project context |
| .claude/skills/ | Project | Committed | Project Agent Skills |
| .claude/commands/ | Project | Committed | Project slash commands |
| .claude/agents/ | Project | Committed | Project subagents |
The CLAUDE.md file is your primary context provider. Claude automatically loads it at session start.
Create CLAUDE.md in your project root:
# Project: [Your App Name]
## Quick Reference
- **Platform**: iOS 17+ / macOS 14+
- **Language**: Swift 6.0
- **UI Framework**: SwiftUI
- **Architecture**: MVVM with @Observable
- **Minimum Deployment**: iOS 17.0
- **Package Manager**: Swift Package Manager
## XcodeBuildMCP Integration
**IMPORTANT**: This project uses XcodeBuildMCP for all Xcode operations.
- Build: `mcp__xcodebuildmcp__build_sim_name_proj`
- Test: `mcp__xcodebuildmcp__test_sim_name_proj`
- Clean: `mcp__xcodebuildmcp__clean`
## Project Structure
MyApp/ ├── App/ # App entry point, App delegate ├── Features/ # Feature modules │ ├── [FeatureName]/ │ │ ├── Views/ # SwiftUI views │ │ ├── ViewModels/ # @Observable classes │ │ └── Models/ # Data models ├── Core/ # Shared utilities │ ├── Extensions/ │ ├── Services/ │ └── Networking/ ├── Resources/ # Assets, Localizations └── Tests/
## Coding Standards
### Swift Style
- Use Swift 6 strict concurrency
- Prefer `@Observable` over `ObservableObject`
- Use `async/await` for all async operations
- Follow Apple's Swift API Design Guidelines
- Use `guard` for early exits
- Prefer value types (structs) over reference types (classes)
### SwiftUI Patterns
- Extract views when they exceed 100 lines
- Use `@State` for local view state only
- Use `@Environment` for dependency injection
- Prefer `NavigationStack` over deprecated `NavigationView`
- Use `@Bindable` for bindings to @Observable objects
### Navigation Pattern
```swift
// Use NavigationStack with type-safe routing
enum Route: Hashable {
case detail(Item)
case settings
}
NavigationStack(path: $router.path) {
ContentView()
.navigationDestination(for: Route.self) { route in
// Handle routing
}
}
// Always use typed errors
enum AppError: LocalizedError {
case networkError(underlying: Error)
case validationError(message: String)
var errorDescription: String? {
switch self {
case .networkError(let error): return error.localizedDescription
case .validationError(let msg): return msg
}
}
}
@Test, #expect)!) without justificationWhen starting new features:
docs/PRD.mddocs/specs/[feature-name].mdultrathink for architectural decisionsShift+Tab) for implementation strategy@import docs/PRD.md @import docs/ARCHITECTURE.md @import docs/ROADMAP.md
### Nested CLAUDE.md for Feature Directories
Create `.claude/CLAUDE.md` or `Features/[FeatureName]/CLAUDE.md`:
```markdown
# [Feature Name] Module
## Purpose
[Description of what this feature does]
## Architecture
- Uses MVVM with @Observable ViewModels
- Parent stores create child stores for modal presentations
## Navigation Pattern
### Sheet-Based Navigation
**Pattern**: Parent stores create optional child stores for modal presentations
**Rules**:
1. Parent ViewModel holds `@Published var childViewModel: ChildViewModel?`
2. View observes and presents sheet when non-nil
3. Dismissal sets childViewModel to nil
### Example
```swift
@Observable
final class ParentViewModel {
var detailViewModel: DetailViewModel?
func showDetail(for item: Item) {
detailViewModel = DetailViewModel(item: item)
}
}
Run tests: mcp__xcodebuildmcp__swift_package_test
---
## 4. PRD-Driven Development Workflow
### Directory Structure for PRD Workflow
docs/ ├── PRD.md # Main Product Requirements Document ├── ARCHITECTURE.md # System architecture decisions ├── ROADMAP.md # Development roadmap & priorities ├── specs/ # Feature specifications │ ├── 000-project-setup.md │ ├── 001-authentication.md │ ├── 002-dashboard.md │ └── template.md └── tasks/ # Task breakdowns ├── 000-sample.md └── [feature]-tasks.md
### PRD Template (`docs/PRD.md`)
```markdown
# Product Requirements Document: [App Name]
## Executive Summary
[Brief description of the product and its primary value proposition]
## Problem Statement
[What problem does this solve? Who experiences this problem?]
## Target Users
- **Primary**: [Description]
- **Secondary**: [Description]
## Success Metrics
| Metric | Target | Measurement |
|--------|--------|-------------|
| User Retention | 40% D7 | Analytics |
| App Rating | 4.5+ | App Store |
| Crash-Free Rate | 99.5% | Crashlytics |
## Core Features
### Feature 1: [Name]
**Priority**: P0 (Must Have)
**Description**: [Detailed description]
**User Stories**:
- As a [user type], I want [action] so that [benefit]
**Acceptance Criteria**:
- [ ] Criterion 1
- [ ] Criterion 2
**Technical Requirements**:
- iOS 17+ required
- Offline support needed
- Data persistence via SwiftData
### Feature 2: [Name]
[Continue pattern...]
## Non-Functional Requirements
- **Performance**: App launch < 2s, smooth 60fps scrolling
- **Accessibility**: WCAG 2.1 AA compliance
- **Localization**: English (primary), [other languages]
- **Security**: Keychain for credentials, certificate pinning
## Out of Scope (v1.0)
- [Feature explicitly not included]
## Technical Constraints
- Swift 6.0+ with strict concurrency
- SwiftUI-only (no UIKit unless necessary)
- SwiftData for persistence
- Minimum iOS 17.0
## Timeline
| Phase | Duration | Deliverables |
|-------|----------|--------------|
| Design | 2 weeks | Figma mockups |