- Indentation: 4 spaces
- Braces: Opening brace on same line
- Spacing: Single space around operators and commas
- Naming: PascalCase for types, camelCase for properties/methods
- Logical directory grouping
- PascalCase files for types,
+for extensions - Modular design with extensions
- @Observable macro: Replace
ObservableObject/@Published - Swift concurrency:
async/await,Task,actor,@MainActor - Result builders: Declarative APIs
- Property wrappers: Use line breaks for long declarations
- Opaque types:
somefor protocol returns
- Early returns to reduce nesting
- Guard statements for optional unwrapping
- Single responsibility per type/extension
- Value types over reference types
Resultenum for typed errorsthrows/tryfor propagation- Optional chaining with
guard let/if let - Typed error definitions
- Avoid using protocol-oriented design unless necessary
- Dependency injection over singletons
- Composition over inheritance
- Factory/Repository patterns
- Use
assert()for development-time invariant checking - Use
assertionFailure()for unreachable code paths - Assertions removed in release builds for performance
- Precondition checking with
precondition()for fatal errors
weakreferences for cyclesunownedwhen guaranteed non-nil- Capture lists in closures
deinitfor cleanup