AgentSkillsCN

ios-architecture

采用分层隔离与依赖规则的 iOS 清洁架构模式。

SKILL.md
--- frontmatter
name: ios-architecture
description: Clean Architecture patterns for iOS with layer separation and dependency rules

iOS Architecture Skill

Overview

This skill covers Clean Architecture implementation for iOS applications with proper layer separation, dependency injection, and SOLID principles.

Architecture Layers

code
┌─────────────────────────────────────────────┐
│           Presentation Layer                 │
│  Views (SwiftUI) ←→ ViewModels (MVVM)       │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│              Domain Layer                    │
│  Use Cases, Repositories, Business Logic    │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│               Core Layer                     │
│  Stores (Actors), Networking, Persistence   │
└─────────────────────────────────────────────┘

Dependency Rule

Dependencies point inward. Outer layers depend on inner layers, never the reverse.

code
UI → Domain → Core
     (not the other way)

Layer Responsibilities

Core Layer (Core/)

  • Stores: Thread-safe state containers (Actors)
  • Networking: HTTP client abstraction
  • Persistence: Database operations
  • NO business logic

Domain Layer (CartDomain/, Auth/)

  • Repositories: Coordinate stores + API
  • Use Cases: Single-purpose business operations
  • Business Rules: Validation, transformation
  • Protocol definitions for external dependencies

Presentation Layer (UI/)

  • Views: SwiftUI declarative UI
  • ViewModels: Presentation logic, state binding
  • NO direct store access - use repositories

Protocol-Based Abstractions

swift
// Define protocol in Domain layer
public protocol HTTPClient: Actor {
    func execute(_ request: HTTPRequest) async throws -> HTTPResponse
}

// Implement in Core layer
public actor URLSessionHTTPClient: HTTPClient {
    public func execute(_ request: HTTPRequest) async throws -> HTTPResponse {
        // Implementation
    }
}

Composition Root Pattern

All dependencies wired in one place:

swift
@main
struct App: App {
    init() {
        // Create dependencies
        let session = SessionStore()
        let cartStore = CartStore()
        let httpClient = URLSessionHTTPClient()
        
        // Wire domain
        let cartRepo = CartRepository(
            store: cartStore,
            outbox: OutboxStore(),
            api: CartBackendClient(http: httpClient)
        )
        
        // Start services
        CartSyncWorker(outbox: outbox, repo: cartRepo).start()
    }
}

File Organization

code
Project/
├── Core/           # Foundation (no business logic)
│   ├── CoreNetworking.swift
│   ├── CoreSession.swift
│   └── CoreDatabase.swift
│
├── CartDomain/     # Business logic
│   ├── CartRepository.swift
│   └── CartSyncWorker.swift
│
├── CartData/       # External integrations
│   └── CartBackendClient.swift
│
└── UI/             # Presentation
    ├── Views.swift
    └── ViewModels.swift

Anti-Patterns to Avoid

Anti-PatternCorrect Approach
View calls API directlyView → ViewModel → Repository
Repository imports UIKitDomain layer is UI-agnostic
Concrete dependenciesProtocol-based abstractions
God ViewModelSingle responsibility ViewModels