iOS Development Guidelines
Purpose
Establish consistency and best practices across iOS applications using Swift/SwiftUI with TCA (The Composable Architecture), following Clean Architecture principles.
When to Use This Skill
Automatically activates when working on:
- •Creating or modifying Swift/SwiftUI views
- •Building view models and use cases
- •Implementing repositories and network layers
- •Working with async/await and concurrency
- •iOS-specific features (Keychain, Core Data, etc.)
- •Navigation with TCA
- •iOS testing and refactoring
- •Clean Architecture patterns
Quick Start
New iOS Feature Checklist
- • View: SwiftUI view with TCA integration
- • Use Case: Business logic in Domain/UseCases/
- • Repository: Protocol in Domain/Repositories/, implementation in Infrastructure/
- • Entity: Domain model in Domain/Entities/
- • ViewModel: Application/ViewModels/ (if needed)
- • Tests: Unit + integration tests
- • Error Handling: Custom Error enum
- • No empty catch: Prohibido
catchvacío (AST: common.error.empty_catch)
New Module Checklist
- • Directory structure (see architecture-overview.md)
- • Repository protocol in Domain/Repositories/
- • Repository implementation in Infrastructure/
- • Use cases in Domain/UseCases/
- • ViewModels in Application/ViewModels/
- • Views in Presentation/Views/
- • Testing setup
Architecture Overview
Clean Architecture Layers
User Interaction
↓
Presentation (SwiftUI Views, TCA)
↓
Application (ViewModels, Coordinators)
↓
Domain (Entities, Use Cases, Repository Protocols)
↓
Infrastructure (Repository Implementations, Network, Persistence)
Key Principle: Dependencies point inward. Domain has no dependencies.
See architecture-overview.md for complete details.
Directory Structure
apps/ios-mobile/
├── Domain/
│ ├── Entities/ # Business models (Order, User, Store)
│ ├── UseCases/ # Business logic (CreateOrderUseCase)
│ └── Repositories/ # Protocols (OrdersRepositoryProtocol)
├── Application/
│ ├── ViewModels/ # ViewModels (ObservableObject)
│ └── Coordinators/ # Navigation logic (TCA)
├── Infrastructure/
│ ├── Network/
│ │ ├── API/ # API client (URLSession)
│ │ └── Repositories/ # Repository implementations
│ └── Persistence/
│ ├── CoreData/ # Core Data stack
│ ├── Keychain/ # Secure storage
│ └── UserDefaults/ # Simple key-value
└── Presentation/
├── Views/ # SwiftUI Views
└── Components/ # Reusable UI components
Naming Conventions:
- •Views:
PascalCase + View-OrdersListView.swift - •ViewModels:
PascalCase + ViewModel-OrdersListViewModel.swift - •Use Cases:
PascalCase + UseCase-CreateOrderUseCase.swift - •Repositories:
PascalCase + Repository-OrdersRepository.swift - •Protocols:
PascalCase + Protocol-OrdersRepositoryProtocol.swift
Core Principles
1. SwiftUI First (UIKit Legacy/Necesario)
// ✅ SwiftUI (preferred)
struct OrdersListView: View {
var body: some View {
List(orders) { order in
OrderRow(order: order)
}
}
}
// ✅ UIKit (Legacy/Necesario - solo cuando sea estrictamente necesario)
class OrdersViewController: UIViewController {
// Programmatic UI, no Storyboards
}
2. Clean Architecture Layers
// Domain (no dependencies)
protocol OrdersRepositoryProtocol {
func fetchOrders() async throws -> [Order]
}
// Infrastructure (implements domain protocol)
class OrdersRepository: OrdersRepositoryProtocol {
private let apiClient: APIClient
func fetchOrders() async throws -> [Order] {
return try await apiClient.get("/orders")
}
}
// Application (use cases)
class GetOrdersUseCase {
private let repository: OrdersRepositoryProtocol
func execute() async throws -> [Order] {
return try await repository.fetchOrders()
}
}
// Presentation (SwiftUI view)
struct OrdersListView: View {
@StateObject private var viewModel = OrdersListViewModel()
var body: some View {
List(viewModel.orders) { order in
OrderRow(order: order)
}
}
}
3. Protocol-Oriented Programming
// Protocol in Domain
protocol NetworkServiceProtocol {
func request<T: Decodable>(_ endpoint: String) async throws -> T
}
// Implementation in Infrastructure
class NetworkService: NetworkServiceProtocol {
func request<T: Decodable>(_ endpoint: String) async throws -> T {
// Implementation
}
}
4. Value Types Preferred
// ✅ struct (preferred)
struct Order {
let id: String
let status: OrderStatus
}
// ✅ class (only when needed)
class OrderViewModel: ObservableObject {
@Published var orders: [Order] = []
}
5. Memory Management
// ✅ [weak self] in closures
Task { [weak self] in
guard let self = self else { return }
await self.loadData()
}
// ✅ No force unwrapping
guard let order = orders.first else { return }
6. Async/Await (No Completion Handlers)
// ✅ async/await
func fetchOrders() async throws -> [Order] {
return try await repository.fetchOrders()
}
// ❌ Completion handlers (avoid in new code)
func fetchOrders(completion: @escaping (Result<[Order], Error>) -> Void) {
// Avoid
}
7. Testing Required
@MainActor
func testGetOrdersUseCase() async throws {
let useCase = GetOrdersUseCase(repository: mockRepository)
let orders = try await useCase.execute()
XCTAssertEqual(orders.count, 5)
}
Common Imports
// SwiftUI import SwiftUI // Foundation import Foundation // Combine (if needed) import Combine // TCA (if using) import ComposableArchitecture // Domain import Domain // Infrastructure import Infrastructure
Quick Reference
SwiftUI Patterns
- •Views:
struct ViewName: View - •ViewModels:
class ViewModelName: ObservableObject - •State:
@State,@StateObject,@ObservedObject - •Binding:
@Binding
Memory Management
- •Weak:
[weak self]in closures that may outlive self - •Unowned:
[unowned self]only if self always exists - •No Force Unwrapping: Use
guard letorif let
Async/Await
- •Async Functions:
func name() async throws -> Type - •Task:
Task { await function() } - •@MainActor: UI updates on main thread
Security
✅ Keychain - Passwords, tokens (NO UserDefaults) ✅ SSL pinning - Prevenir man-in-the-middle ✅ Jailbreak detection - Opcional para apps críticas ✅ App Transport Security (ATS) - HTTPS por defecto ✅ Biometric auth - Face ID, Touch ID (LocalAuthentication) ✅ Secure enclave - Para keys criptográficas ✅ Obfuscation - Strings sensibles en código
Accessibility
✅ VoiceOver - Testear con screen reader ✅ Dynamic Type - Font scaling automático ✅ Accessibility labels - .accessibilityLabel() ✅ Traits - .accessibilityAddTraits(.isButton) ✅ Reduce motion - Respetar preferencias del usuario ✅ Color contrast - WCAG AA mínimo
Localization (i18n)
✅ NSLocalizedString - Strings traducibles ✅ Localizable.strings - Archivos por idioma ✅ Stringsdict - Para plurales ✅ Base internationalization - Base.lproj ✅ RTL support - Right-to-left para árabe, hebreo ✅ NumberFormatter - Formateo de números, monedas ✅ DateFormatter - Fechas localizadas
Performance
✅ Instruments - Time Profiler, Allocations, Leaks ✅ Lazy loading - LazyVStack, on-demand data ✅ Image optimization - Resize, compress, cache ✅ Background threads - No bloquear main thread ✅ Main thread blocking detection - Detecta operaciones síncronas bloqueantes ✅ Watchdog prevention - Previene app kill por watchdog (>5s freeze) ✅ Reuse cells - UITableView/UICollectionView ✅ Memoization - Cachear cálculos costosos
Code Organization
✅ SPM (Swift Package Manager) - Modularización ✅ Feature modules - Orders, Users, Auth como packages ✅ Extensions - Agrupar por funcionalidad, archivos separados ✅ MARK: - - Organizar código dentro de archivos ✅ File naming - PascalCase para tipos, camelCase para archivos
CI/CD
✅ Fastlane - Automatización de builds, tests, deployments ✅ xcodebuild - CLI para builds ✅ TestFlight - Beta distribution ✅ GitHub Actions / Bitrise - CI/CD pipelines
Anti-Patterns to Avoid
❌ Force unwrapping (!) except IBOutlets ❌ Completion handlers in new code ❌ Singletons (use dependency injection) ❌ Business logic in views ❌ Direct API calls in views ❌ Missing error handling ❌ Retain cycles ❌ Massive View Controllers (>300 líneas) ❌ Storyboards grandes (merge conflicts, lentitud) ❌ Magic numbers (usar constantes con nombres) ❌ Ignoring warnings (warnings = errores futuros)
Navigation Guide
| Need to... | Read this |
|---|---|
| Understand architecture | architecture-overview.md |
| Create views | swiftui-patterns.md |
| Implement use cases | use-cases-guide.md |
| Repository pattern | repositories-guide.md |
| Handle errors | error-handling.md |
| Network access | networking-patterns.md |
| Write tests | testing-guide.md |
| See examples | complete-examples.md |
Resource Files
architecture-overview.md
Clean Architecture layers, dependency direction, separation of concerns
swiftui-patterns.md
SwiftUI views, state management, TCA integration
use-cases-guide.md
Business logic orchestration, error handling
repositories-guide.md
Repository protocols, implementations, dependency injection
error-handling.md
Custom Error enums, error propagation
networking-patterns.md
URLSession, async/await, error handling
testing-guide.md
Unit/integration tests, mocking, coverage
complete-examples.md
Full examples, refactoring guide
Related Skills
- •backend-guidelines - Backend development patterns
- •frontend-guidelines - Frontend development patterns
- •android-guidelines - Android development patterns
- •skill-developer - Meta-skill for creating and managing skills
Skill Status: COMPLETE ✅ Line Count: < 500 ✅ Progressive Disclosure: 8 resource files ✅