apple-dev-best-practices
Apple platform development best practices for Swift 6, SwiftUI, SwiftData, and iOS/macOS apps. Use when building any iOS or macOS app, writing Swift code, designing SwiftUI views, working with Xcode projects, implementing navigation, state management, concurrency, networking, persistence, or testing on Apple platforms. Triggers on Swift, SwiftUI, iOS, macOS, Xcode, UIKit, SwiftData, Core Data, XCTest, StoreKit, CloudKit, MapKit, HealthKit, or any Apple framework. Also use when reviewing Swift code, debugging iOS apps, migrating UIKit to SwiftUI, or planning Apple platform architecture.
Best use case
apple-dev-best-practices is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Apple platform development best practices for Swift 6, SwiftUI, SwiftData, and iOS/macOS apps. Use when building any iOS or macOS app, writing Swift code, designing SwiftUI views, working with Xcode projects, implementing navigation, state management, concurrency, networking, persistence, or testing on Apple platforms. Triggers on Swift, SwiftUI, iOS, macOS, Xcode, UIKit, SwiftData, Core Data, XCTest, StoreKit, CloudKit, MapKit, HealthKit, or any Apple framework. Also use when reviewing Swift code, debugging iOS apps, migrating UIKit to SwiftUI, or planning Apple platform architecture.
Teams using apple-dev-best-practices should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/apple-dev-best-practices/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How apple-dev-best-practices Compares
| Feature / Agent | apple-dev-best-practices | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Apple platform development best practices for Swift 6, SwiftUI, SwiftData, and iOS/macOS apps. Use when building any iOS or macOS app, writing Swift code, designing SwiftUI views, working with Xcode projects, implementing navigation, state management, concurrency, networking, persistence, or testing on Apple platforms. Triggers on Swift, SwiftUI, iOS, macOS, Xcode, UIKit, SwiftData, Core Data, XCTest, StoreKit, CloudKit, MapKit, HealthKit, or any Apple framework. Also use when reviewing Swift code, debugging iOS apps, migrating UIKit to SwiftUI, or planning Apple platform architecture.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
AI Agents for Coding
Browse AI agent skills for coding, debugging, testing, refactoring, code review, and developer workflows across Claude, Cursor, and Codex.
Cursor vs Codex for AI Workflows
Compare Cursor and Codex for AI coding workflows, repository assistance, debugging, refactoring, and reusable developer skills.
SKILL.md Source
# Apple Development Best Practices
Modern Apple platform development using Swift 6 and SwiftUI as primary frameworks.
## When to Use
Use this skill when:
- Building iOS or macOS apps with Swift 6 and SwiftUI
- Designing navigation, state management, or concurrency patterns for Apple platforms
- Working with SwiftData, Core Data, StoreKit, CloudKit, or other Apple frameworks
- Reviewing Swift code or planning Apple platform architecture
## When NOT to Use
Do NOT use this skill when:
- Building cross-platform mobile apps (Flutter, React Native, Kotlin Multiplatform) — use a cross-platform mobile persona instead, because Apple-specific patterns like `@Observable` and `NavigationStack` don't apply
- Writing server-side Swift (Vapor, Hummingbird) — use a backend engineering persona instead, because server-side Swift has different concurrency, deployment, and architecture concerns
## Core Philosophy
Build apps that are **previewable, testable, and maintainable**. A previewable app is a testable app. A testable app is a maintainable app.
## Swift 6 Standards
- **Strict concurrency** enabled — treat all warnings as errors
- **`@Observable`** over `ObservableObject` (iOS 17+)
- **`async/await`** for all asynchronous operations
- **Value types** (structs) preferred over reference types (classes) unless identity semantics needed
- **`guard`** for early exits, never deeply nested `if let` chains
- **Typed errors** via `LocalizedError` conformance — no raw strings
- **No force unwrapping** (`!`) without documented justification
- Follow Apple's Swift API Design Guidelines for naming
## SwiftUI Architecture
### State Management — Single Source of Truth (SSOT)
```swift
// Local view state → @State
@State private var isExpanded = false
// Observable model → @State with @Observable class
@State private var viewModel = RecipeViewModel()
// Shared across view tree → @Environment
@Environment(\.recipeStore) private var store
// Bindings to @Observable → @Bindable
@Bindable var viewModel: RecipeViewModel
```
**Rules:**
- `@State` for view-local state only — never shared across views
- `@Observable` classes for ViewModels (replaces `ObservableObject` + `@Published`)
- `@Environment` for dependency injection (services, stores, settings)
- Never pass view models more than 2 levels deep — use Environment instead
### Navigation — NavigationStack with Type-Safe Routing
```swift
enum Route: Hashable {
case recipeDetail(Recipe)
case settings
case profile(User)
}
@Observable
final class Router {
var path = NavigationPath()
func navigate(to route: Route) {
path.append(route)
}
}
```
**Rules:**
- `NavigationStack` only — never deprecated `NavigationView`
- Type-safe routing via `Hashable` enum
- Router as `@Observable` class in `@Environment`
- Sheet presentation via optional ViewModel on parent
### View Composition
- Extract subviews at **50+ lines** or when reusable
- Max **100 lines** per view file before mandatory extraction
- Custom ViewModifiers for shared styling — not repeated inline styles
- Never use `AnyView` — destroys diffing performance and identity
- Prefer `@ViewBuilder` closures over `AnyView` for type erasure
### Performance
- **`LazyVStack`/`LazyHStack`** inside ScrollView — never eager stacks for large lists
- **`EquatableView`** wrapper for complex views that rarely change
- Keep view body **pure** — no side effects, no network calls
- Use `.task` modifier for async work, not `onAppear` with Task
- Profile with SwiftUI Performance Instrument (Xcode 16+)
## Project Structure
```
AppName/
├── App/ # App entry, lifecycle, configuration
│ ├── AppNameApp.swift
│ └── AppDelegate.swift # Only if needed for UIKit integration
├── Features/ # Feature modules (self-contained)
│ ├── Recipes/
│ │ ├── Views/ # SwiftUI views
│ │ ├── ViewModels/ # @Observable classes
│ │ └── Models/ # Data models (structs)
│ ├── MealPlanning/
│ └── Community/
├── Core/ # Shared infrastructure
│ ├── Extensions/
│ ├── Services/ # Networking, auth, analytics
│ ├── Persistence/ # SwiftData / Core Data
│ └── Components/ # Reusable UI components
├── Resources/ # Assets, Localizations, Fonts
└── Tests/
├── UnitTests/ # ViewModel + Service tests
└── UITests/ # Critical user flow tests
```
**Rules:**
- Features are **self-contained** — no cross-feature imports
- Shared code lives in `Core/` only
- Each feature has its own Views, ViewModels, Models
- Feature folders mirror navigation structure
## Concurrency
```swift
// Actor for thread-safe shared state
actor RecipeStore {
private var cache: [UUID: Recipe] = [:]
func recipe(for id: UUID) -> Recipe? {
cache[id]
}
}
// @MainActor for UI-bound classes
@MainActor
@Observable
final class RecipeListViewModel {
var recipes: [Recipe] = []
var isLoading = false
func loadRecipes() async {
isLoading = true
defer { isLoading = false }
recipes = await recipeService.fetchAll()
}
}
```
**Rules:**
- `@MainActor` on all ViewModels
- `actor` for shared mutable state
- `Sendable` conformance for types crossing isolation boundaries
- Never `DispatchQueue.main.async` — use `@MainActor` instead
- `Task` only inside `.task` modifier or explicit user-initiated actions
- `TaskGroup` for parallel independent work
## Testing
- **Swift Testing** (`@Test`, `#expect`) preferred over XCTest for new code
- **Unit tests** for all ViewModel logic — 80%+ coverage on business logic
- **UI tests** for critical user flows only (login, purchase, core CRUD)
- **Dependency injection** via protocols for testability
- **No singletons** in production code — inject via `@Environment`
- Preview-driven development: if a view is hard to preview, it's hard to test
## Persistence
**SwiftData** (iOS 17+) is the default persistence layer:
```swift
@Model
final class Recipe {
var name: String
var ingredients: [String]
var instructions: String
@Relationship(deleteRule: .cascade)
var steps: [CookingStep]
}
```
**Rules:**
- `@Model` classes for SwiftData — not structs
- Define `@Relationship` explicitly with delete rules
- Use `@Query` in views for automatic updates
- ModelContainer configured in App entry point
- Migration strategy documented before schema changes
## Networking
```swift
protocol RecipeServiceProtocol: Sendable {
func fetchAll() async throws -> [Recipe]
func create(_ recipe: Recipe) async throws -> Recipe
}
struct RecipeService: RecipeServiceProtocol {
private let session: URLSession
private let decoder: JSONDecoder
func fetchAll() async throws -> [Recipe] {
let (data, response) = try await session.data(from: endpoint)
guard let http = response as? HTTPURLResponse,
(200...299).contains(http.statusCode) else {
throw AppError.networkError(statusCode: http.statusCode)
}
return try decoder.decode([Recipe].self, from: data)
}
}
```
**Rules:**
- Protocol-based services for testability
- `Sendable` conformance on all service types
- Typed errors with `LocalizedError`
- No third-party HTTP libraries unless justified (URLSession is sufficient)
- Certificate pinning for sensitive data
## Security
- **Keychain** for credentials, tokens, secrets — never UserDefaults
- **App Transport Security** enabled — HTTPS only
- No sensitive data in logs or crash reports
- `@AppStorage` only for non-sensitive user preferences
- Input validation on all user-provided data
- Privacy manifest (`PrivacyInfo.xcprivacy`) for App Store compliance
## Accessibility
- Every interactive element needs an `accessibilityLabel`
- Use semantic SwiftUI elements (Button, Toggle, Picker) — not `.onTapGesture`
- Support Dynamic Type — no hardcoded font sizes
- Minimum tap target 44x44pt
- Test with VoiceOver before shipping
## Deep References
See `references/` for detailed guidance:
- `references/swiftui-patterns.md` — Advanced view patterns, custom layouts, animations
- `references/concurrency-guide.md` — Actor isolation, Sendable, structured concurrency
- `references/xcode-claude-integration.md` — XcodeBuildMCP setup, hooks, sandbox modes
- `references/migration-guide.md` — UIKit → SwiftUI, CoreData → SwiftData pathsRelated Skills
arcanea-react-best-practices
React 19 and Next.js 16 performance optimization for the Arcanea platform. Use when writing, reviewing, or refactoring React components, data fetching logic, bundle optimization, or any frontend performance work. Triggers on: React components, Next.js pages, hooks, data fetching, bundle size, re-renders, Server Components, Client Components, hydration. Sourced from Vercel Engineering's official React best practices (57 rules, 8 categories) and adapted for the Arcanea stack.
applesauce-core
This skill should be used when working with applesauce-core library for Nostr client development, including event stores, queries, observables, and client utilities. Provides comprehensive knowledge of applesauce patterns for building reactive Nostr applications.
apple-appstore-reviewer
Serves as a reviewer of the codebase with instructions on looking for Apple App Store optimizations or rejection reasons.
animation-best-practices
CSS and UI animation patterns for responsive, polished interfaces. Use when implementing hover effects, tooltips, button feedback, transitions, or fixing animation issues like flicker and shakiness.
angular-best-practices
Angular performance optimization and best practices guide. Use when writing, reviewing, or refactoring Angular code for optimal performance, bundle size, and rendering efficiency.
stripe-best-practices
Best practices for building Stripe integrations
power-bi-report-design-best-practices
Comprehensive Power BI report design and visualization best practices based on Microsoft guidance for creating effective, accessible, and performant reports and dashboards. Triggers on: **/*.{pbix,md,json,txt}
best-practices-guidelines
Specifies best practices, including following RESTful API design principles, implementing responsive design, using Zod for data validation, and regularly updating dependencies. This rule promotes mode
apple-ui-design
Apple-inspired clean, minimal, premium UI design. Use when building modern interfaces requiring exceptional UX, clean aesthetics, or Apple-like polish. Triggers on: clean UI, modern design, Apple style, minimal, premium, user-friendly, UX.
apple-hig-designer
Design iOS apps following Apple's Human Interface Guidelines. Generate native components, validate designs, and ensure accessibility compliance for iPhone, iPad, and Apple Watch.
apple-design
Create Apple-inspired modern, minimalist UI designs with glassmorphism, smooth animations, generous whitespace, and elegant typography. Use when designing portfolio websites, landing pages, hero sections, product showcases, or implementing Apple-style components, dark mode, or responsive layouts.
moltbot-best-practices
Best practices for AI agents - Cursor, Claude, ChatGPT, Copilot. Avoid common mistakes. Confirms before executing, drafts before publishing. Vibe-coding essential.