swift-best-practices
$
npx mdskill add HoangNguyen0403/agent-skills-standard/swift-best-practices- **Guard for Early Exit**: Use **`guard let`** over **nested if** statements for better readability and to unwrap optionals early. - **Nested Checks**: Use **`guard`** for **precondition** checks at top of function to reduce nested depth. - **Switch Exhaustiveness**: Always handle all cases; use **`@unknown default`** for freezing enums (enums from frameworks). - **if-case**: Use **`if case .success(let value) = result`** for simple enum pattern matching.
SKILL.md
.github/skills/swift-best-practicesView on GitHub ↗
---
name: swift-best-practices
description: Apply Guard, Value Types, Immutability, and Naming conventions in Swift. Use when writing idiomatic Swift using guard, value types, immutability, or naming conventions.
metadata:
triggers:
files:
- '**/*.swift'
keywords:
- guard
- let
- struct
- final
- swift idiomatic
- swift naming
- swift best practice
- swift conventions
- value type
- immutability swift
- guard let
---
# Swift Best Practices
## **Priority: P0**
## Implementation Guidelines
### Control Flow (Guard over If)
- **Guard for Early Exit**: Use **`guard let`** over **nested if** statements for better readability and to unwrap optionals early.
- **Nested Checks**: Use **`guard`** for **precondition** checks at top of function to reduce nested depth.
- **Switch Exhaustiveness**: Always handle all cases; use **`@unknown default`** for freezing enums (enums from frameworks).
- **if-case**: Use **`if case .success(let value) = result`** for simple enum pattern matching.
### Value Types & Immutability
- **Prefer Structs**: **Default to struct** for **value semantics** and thread safety. Use `class` only when reference identity or **inheritance** required.
- **Immutability**: Always **default to let** for all properties and constants. Use `var` only when change required.
- **Modifiers**: Use **`final`** for all classes that not intended to subclassed to improve performance (static dispatch).
- **Static Dispatch**: Favor methods in structs and `final` classes.
### Naming & Style
- **Clear Intent**: Prefix booleans with **`is, has, or can`**. Example: **`isValid`**, `hasErrors`, **`canEdit`**. Makes boolean state clear.
- **API Guidelines**: Follow official **Swift API Design Guidelines**. Use **`camelCase`** for **clear names** and `PascalCase` for types.
- **Protocols**: Name protocols with **`-able`**, `-ible`, or `-ing` suffixes (e.g., `Codable`, `Identifiable`).
- **Opaque Types**: Use **`some View`** or `some Collection` for return types where underlying type internal.
### Collection Performance
- **Sequence API**: Use **`compactMap`**, **`filter`**, and **`reduce`** instead of explicit **for-where** loops for data transformations.
- **Lazy Collections**: Use **`.lazy`** for large sequences when result consumed partially.
- **Dictionaries**: Use **`default`** values in dictionary access to avoid double optional unwrapping.
## Anti-Patterns
- **No Pyramid of Doom**: Use **`guard`** for early exits.
- **No force unwrap**: Never use **`!`** on optionals. Use **`??`** (nil-coalescing) or **`if let`**.
- **No global var**: Avoid mutable global state. Use **Singletons** (accessed via `static let shared`) or DI.
## References
- [Guard Patterns & Immutability](references/implementation.md)More from HoangNguyen0403/agent-skills-standard
- android-agp-upgradeUpgrade an Android project to Android Gradle Plugin (AGP) 9. Use when migrating to AGP 9, updating Gradle build files, migrating to built-in Kotlin, or adopting the new AGP DSL.
- android-architectureApply Clean Architecture layering, modularization, and Unidirectional Data Flow in Android projects. Use when setting up project structure, placing code in layers, configuring feature/core modules, or implementing UDF patterns.
- android-background-workImplement WorkManager and background processing correctly on Android. Use when creating Worker classes, scheduling tasks, choosing between WorkManager and Foreground Services, or setting up Hilt in workers.
- android-composeBuild high-performance declarative UI with Jetpack Compose. Use when writing Composable functions, optimizing recomposition, hoisting state, or working with LazyColumn and side effects.
- android-compose-migrationMigrate an Android XML View to Jetpack Compose following a structured 10-step workflow. Use when converting XML layouts to Compose, setting up Compose in an existing View-based project, or incrementally adopting Compose.
- android-concurrencyWrite correct coroutine scopes, Flow collection, and dispatcher injection in Android. Use when writing suspend functions, choosing between StateFlow and SharedFlow, or injecting Dispatchers for testability.
- android-deploymentConfigure release signing, R8 obfuscation, and App Bundle publishing for Android. Use when setting up signing configs, enabling minification, adding ProGuard keep rules, or preparing for Play Store submission.
- android-design-systemEnforce Material Design 3 theming and design token usage in Jetpack Compose. Use when implementing M3 components, color schemes, typography, or design tokens.
- android-diConfigure Hilt dependency injection with proper scoping, modules, and constructor injection in Android. Use when setting up Hilt DI, defining modules, or configuring component scoping.
- android-edge-to-edgeMigrate a Jetpack Compose app to edge-to-edge display and fix system bar inset issues. Use when UI components are obscured by navigation/status bars, fixing IME insets, or enabling edge-to-edge for SDK 35+.