跳到主要内容
知仓学习社ZHICANG

architecture-spec

Generates technical architecture specification from PRD. Covers architecture pattern, tech stack, data models, and app structure. Use when creating …

不碰外部(只输出文字)无严重或高危命中rshankras/claude-code-apple-skills

它会碰到什么

扫了多少1 个文本文件,35 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Architecture Spec Skill

Generate technical architecture specification for iOS/macOS app.

Metadata

  • Name: architecture-spec
  • Version: 1.0.0
  • Role: iOS/macOS Architect
  • Author: ProductAgent Team

When This Skill Activates

This skill activates when the user says:

  • "generate architecture"
  • "create technical spec"
  • "write architecture document"
  • "generate architecture spec"
  • "design technical architecture"
  • "create ARCHITECTURE.md"

Description

You are an iOS/macOS Architect AI agent specializing in Apple platform app architecture. Your job is to design a comprehensive technical architecture based on the Product Requirements Document (PRD) and make opinionated technology stack decisions following Apple best practices.

Prerequisites

Before activating this skill, ensure:

  1. PRD exists at docs/PRD.md
  2. User has reviewed and approved the PRD
  3. MVP scope is clear (from product-agent output or PRD)

Input Sources

Read and extract information from:

  1. docs/PRD.md
  • Core features and their complexity
  • Non-functional requirements
  • Data model hints
  • Platform requirements
  • Technical considerations
  1. Product development plan (if available)
  • MVP scope with technical requirements
  • Third-party dependencies mentioned
  • Platform and timeline constraints
  1. User preferences (ask if needed):
  • SwiftUI vs UIKit preference
  • Third-party library preferences
  • Architecture pattern preference (if strong opinion)
  • Backend API availability (determines data strategy)

Output

Generate docs/ARCHITECTURE.md with the following structure:

# Technical Architecture: [App Name]

**Version**: 1.0.0
**Last Updated**: [Date]
**Status**: Draft / In Review / Approved
**Owner**: Technical Architect
**Platform**: iOS [version]+ / macOS [version]+

---

## 1. Architecture Overview

### 1.1 Architecture Pattern

**Selected Pattern**: MVVM (Model-View-ViewModel) with SwiftUI
*or* Clean Architecture *or* TCA (The Composable Architecture)

**Reasoning**:
[Explain why this pattern was chosen based on app complexity]

**Characteristics**:
- **Layers**: [Describe the architectural layers]
- **Data Flow**: [Unidirectional / Bidirectional]
- **State Management**: [@Observable, Combine, TCA Store, etc.]
- **Testability**: [How architecture supports testing]

### 1.2 High-Level Component Diagram

┌─────────────────────────────────────────────────┐

│ Presentation Layer │

│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │

│ │ Views │ │ViewModels│ │ Models │ │

│ │ (SwiftUI)│←→│(@Observ.)│←→│ (Data) │ │

│ └──────────┘ └──────────┘ └──────────┘ │

└────────────────────┬────────────────────────────┘

┌────────────────────┴────────────────────────────┐

│ Business Logic Layer │

│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │

│ │ Services │ │ Use │ │Repository│ │

│ │ │ │ Cases │ │ Pattern │ │

│ └──────────┘ └──────────┘ └──────────┘ │

└────────────────────┬────────────────────────────┘

┌────────────────────┴────────────────────────────┐

│ Data Layer │

│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │

│ │SwiftData │ │ Network │ │ Keychain │ │

│ │ / Core │ │ Client │ │ Storage │ │

│ │ Data │ │ (URLSess)│ │ │ │

│ └──────────┘ └──────────┘ └──────────┘ │

└─────────────────────────────────────────────────┘


### 1.3 Key Architectural Decisions

| Decision | Choice | Alternative Considered | Rationale |
|----------|--------|----------------------|-----------|
| UI Framework | SwiftUI | UIKit | Modern, declarative, iOS 17+ target allows it |
| Data Persistence | SwiftData | Core Data | Simpler API, better SwiftUI integration |
| Architecture Pattern | MVVM | VIPER, TCA | Balanced complexity vs maintainability |
| Networking | URLSession | Alamofire | No third-party dependency needed |
| State Management | @Observable | Combine, TCA | iOS 17+ Observation framework |
| Navigation | NavigationStack | Coordinator | SwiftUI native, simpler for MVP |

---

## 2. Technology Stack

### 2.1 Apple Frameworks

**UI & Presentation**:
- **SwiftUI** (primary) - Declarative UI framework
  - Minimum iOS 17.0 for @Observable, ContentUnavailableView, etc.
  - Navigation: NavigationStack, NavigationPath
  - Data binding: @State, @Binding, @Environment

**Data Persistence**:
- **SwiftData** (iOS 17+) - Data modeling and persistence
  - @Model macro for model classes
  - ModelContainer for database configuration
  - ModelContext for CRUD operations
  - @Query property wrapper for automatic observation

**Networking & Concurrency**:
- **URLSession** - HTTP networking
- **async/await** - Concurrency
- **Actors** - Thread-safe state management
- **Codable** - JSON serialization/deserialization

**Security**:
- **Keychain Services** - Secure credential storage
- **CryptoKit** - Encryption (if needed)
- **LocalAuthentication** - Biometric authentication (if needed)

**Other**:
- [List any other frameworks based on features]
  - MapKit (if maps needed)
  - Vision (if image recognition)
  - CoreML (if ML features)
  - StoreKit (if IAP)
  - CloudKit (if iCloud sync)

### 2.2 Third-Party Dependencies

**Via Swift Package Manager**:

1. **[Package Name]** (if needed)
   - **Repository**: https://github.com/[org]/[repo]
   - **Version**: ~> X.X.X
   - **Purpose**: [Why this is needed]
   - **Alternative Considered**: [Why not chosen]
   - **License**: [MIT, Apache, etc.]

*Note*: Keep dependencies minimal. Only add if:
- Provides significant value not available in Apple frameworks
- Well-maintained and trusted
- No suitable alternative

**Decision**: Start with zero third-party dependencies for MVP. Add only if needed.

### 2.3 Development Tools

- **Xcode**: [Latest stable version]
- **iOS Deployment Target**: iOS 26.0 (adjust lower for broader reach — iOS 17+ retains `@Observable` and SwiftData support)
- **Swift Version**: Swift 6+
- **Package Manager**: Swift Package Manager (SPM)
- **CI/CD**: Xcode Cloud / GitHub Actions (to be determined)

---

## 3. App Structure

### 3.1 Module Breakdown

[AppName]/

├── App/

│ ├── [AppName]App.swift # App entry point (@main)

│ ├── ContentView.swift # Root view

│ └── AppState.swift # Global app state (if needed)

├── Features/ # Feature-based modules

│ ├── Home/

│ │ ├── Views/

│ │ │ ├── HomeView.swift

│ │ │ ├── HomeCardView.swift

│ │ │ └── HomeEmptyStateView.swift

│ │ ├── ViewModels/

│ │ │ └── HomeViewModel.swift

│ │ └── Models/

│ │ └── HomeItem.swift (if feature-specific)

│ │

│ ├── [Feature2]/

│ │ ├── Views/

│ │ ├── ViewModels/

│ │ └── Models/

│ │

│ └── [Feature3]/

│ └── ...

├── Core/ # Shared core functionality

│ ├── Networking/

│ │ ├── APIClient.swift # HTTP client

│ │ ├── APIEndpoint.swift # Endpoint definitions

│ │ ├── APIError.swift # Error types

│ │ └── RequestModels/ # API request DTOs

│ │ └── ...

│ │

│ ├── Storage/

│ │ ├── DataManager.swift # SwiftData container wrapper

│ │ └── KeychainManager.swift # Keychain operations

│ │

│ ├── Extensions/

│ │ ├── View+Extensions.swift # SwiftUI View extensions

│ │ ├── Color+Extensions.swift # Color palette

│ │ ├── Font+Extensions.swift # Typography

│ │ └── Date+Extensions.swift # Date utilities

│ │

│ └── Utilities/

│ ├── Logger.swift # Logging utility

│ ├── Validator.swift # Input validation

│ └── Constants.swift # App constants

├── Models/ # Domain models (shared)

│ ├── User.swift # @Model classes

│ ├── [Entity2].swift

│ └── ResponseModels/ # API response DTOs

│ └── ...

├── Services/ # Business logic services

│ ├── AuthenticationService.swift

│ ├── [Feature]Service.swift

│ └── SyncService.swift (if background sync)

├── Resources/

│ ├── Assets.xcassets # Images, colors

│ ├── Localizable.xcstrings # Translations

│ └── PrivacyInfo.xcprivacy # Privacy manifest

└── Tests/

├── UnitTests/

│ ├── ViewModelTests/

│ ├── ServiceTests/

│ └── ModelTests/

└── UITests/

└── ...


**Organizational Principles**:
- **Feature-based organization**: Each major feature in its own folder
- **Vertical slicing**: Feature folder contains Views, ViewModels, and feature-specific Models
- **Core for shared**: Reusable components go in Core/
- **Models for domain**: Shared domain models (SwiftData @Model classes)
- **Services for business logic**: Business logic that spans features

### 3.2 Data Models

Based on PRD requirements, core entities are:

#### [Entity 1]: User

import Foundation

import SwiftData

@Model

final class User {

// Identity

@Attribute(.unique) var id: UUID

var email: String

var name: String

var createdAt: Date

var updatedAt: Date

// Relationships

@Relationship(deleteRule: .cascade)

var [relatedEntities]: [RelatedEntity]

// Computed Properties

var displayName: String {

name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty

? email

: name

}

// Validation

var isValid: Bool {

!email.isEmpty && email.contains("@") && !name.isEmpty

}

init(email: String, name: String) {

self.id = UUID()

self.email = email

self.name = name

self.createdAt = Date()

self.updatedAt = Date()

}

}


#### [Entity 2]: [Name]

@Model

final class [Entity2] {

@Attribute(.unique) var id: UUID

var [property1]: String

var [property2]: Date

// Relationships

@Relationship(inverse: \User.[relatedEntities])

var owner: User?

init(...) {

// Initialization

}

}


**Entity Relationships**:
- User has many [Entity2] (one-to-many)
- [Entity2] belongs to User (many-to-one)
- [Add other relationships as per PRD]

**SwiftData Considerations**:
- Use @Attribute(.unique) for identifiers
- Define deleteRule for relationships (cascade, nullify, deny, noAction)
- Keep models simple - complex logic goes in ViewModels/Services
- Use @Transient for computed properties that shouldn't persist
- Consider privacy: Mark sensitive fields appropriately

### 3.3 Navigation Architecture

**Pattern**: NavigationStack (SwiftUI native)

**Primary Navigation**:
- **TabView** for main app sections (if 3-5 top-level sections)
- **NavigationStack** for drill-down navigation within tabs

**Navigation State**:

// In each feature's root view

@State private var navigationPath = NavigationPath()

NavigationStack(path: $navigationPath) {

ListView()

.navigationDestination(for: Item.self) { item in

DetailView(item: item)

}

.navigationDestination(for: EditMode.self) { _ in

EditView()

}

}


**Deep Linking**:
- Handle URL schemes: `[appname]://[route]/[id]`
- Use `.onOpenURL` modifier at app root
- Parse URL and manipulate NavigationPath

**Modal Presentation**:
- Use `.sheet` for full-screen modal forms
- Use `.alert` for simple confirmations
- Use `.confirmationDialog` for action sheets

---

## 4. Data Flow

### 4.1 State Management

**Pattern**: @Observable (iOS 17+ Observation framework)

**State Layers**:

1. **View State** (@State)
   - Local to view
   - Examples: isLoading, showError, selectedItem
   - Transient, not persisted

2. **ViewModel State** (@Observable)
   - Shared across view hierarchy
   - Examples: Business logic, API state, validation
   - Passed as @Environment or direct reference

3. **Persistent State** (SwiftData @Query)
   - Automatically observed by SwiftUI
   - Database-backed
   - Examples: User data, items list

**Example ViewModel**:

import Foundation

import Observation

@Observable

final class HomeViewModel {

// Published state

var items: [Item] = []

var isLoading = false

var errorMessage: String?

var showError = false

// Dependencies (injected)

private let apiClient: APIClient

private let dataManager: DataManager

init(apiClient: APIClient = .shared,

dataManager: DataManager = .shared) {

self.apiClient = apiClient

self.dataManager = dataManager

}

// Actions

@MainActor

func loadItems() async {

isLoading = true

defer { isLoading = false }

do {

let fetchedItems = try await apiClient.fetchItems()

items = fetchedItems

// Persist to SwiftData

try dataManager.saveItems(fetchedItems)

} catch {

errorMessage = error.localizedDescription

showError = true

}

}

}


**Data Flow Diagram**:

User Action (Tap Button)

View calls ViewModel method

ViewModel calls Service/APIClient

Service makes API call

Response updates ViewModel @Observable properties

SwiftUI automatically updates View

(Optional) Persist to SwiftData


### 4.2 Data Persistence

**Strategy**: Local-first with optional sync

**Local Storage**:
- **SwiftData** for structured data (models)
- **UserDefaults** for simple preferences
- **Keychain** for sensitive data (tokens, passwords)
- **FileManager** for large files (images, documents)

**SwiftData Setup**:

// In App struct

@main

struct [AppName]App: App {

let container: ModelContainer

init() {

do {

let schema = Schema([User.self, Item.self, ...])

let config = ModelConfiguration(

schema: schema,

isStoredInMemoryOnly: false

)

container = try ModelContainer(

for: schema,

configurations: config

)

} catch {

fatalError("Failed to create ModelContainer: \(error)")

}

}

var body: some Scene {

WindowGroup {

ContentView()

}

.modelContainer(container)

}

}


**Data Migration**:
- SwiftData handles migrations automatically for simple changes
- For complex migrations, use VersionedSchema and MigrationPlan
- Test migrations thoroughly before releases

**Backup & Sync** (if needed):
- **iCloud CloudKit**: For user data sync across devices
- **File-based**: For documents (UIDocument + iCloud Drive)
- Implementation: Phase 2 (post-MVP unless critical)

### 4.3 Networking Layer

**Architecture**: Protocol-oriented with async/await

**APIClient Design**:

actor APIClient {

static let shared = APIClient()

private let baseURL = URL(string: "https://api.example.com/v1")!

private let session: URLSession

private var authToken: String?

init() {

let config = URLSessionConfiguration.default

config.timeoutIntervalForRequest = 30

config.waitsForConnectivity = true

self.session = URLSession(configuration: config)

}

// Generic request method

func request<T: Decodable>(

_ endpoint: APIEndpoint,

responseType: T.Type

) async throws -> T {

var request = URLRequest(url: baseURL.appendingPathComponent(endpoint.path))

request.httpMethod = endpoint.method.rawValue

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

// Add auth token if available

if let token = authToken {

request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")

}

// Add body for POST/PUT

if let body = endpoint.body {

request.httpBody = try JSONEncoder().encode(body)

}

// Perform request

let (data, response) = try await session.data(for: request)

// Validate response

guard let httpResponse = response as? HTTPURLResponse else {

throw APIError.invalidResponse

}

guard (200...299).contains(httpResponse.statusCode) else {

throw APIError.httpError(statusCode: httpResponse.statusCode, data: data)

}

// Decode

let decoder = JSONDecoder()

decoder.keyDecodingStrategy = .convertFromSnakeCase

decoder.dateDecodingStrategy = .iso8601

return try decoder.decode(T.self, from: data)

}

}

// Endpoint definition

struct APIEndpoint {

let path: String

let method: HTTPMethod

let body: (any Encodable)?

enum HTTPMethod: String {

case get = "GET"

case post = "POST"

case put = "PUT"

case delete = "DELETE"

case patch = "PATCH"

}

}

// Error handling

enum APIError: LocalizedError {

case invalidResponse

case httpError(statusCode: Int, data: Data?)

case decodingError(Error)

case networkError(Error)

var errorDescription: String? {

switch self {

case .invalidResponse:

return "Invalid response from server"

case .httpError(let code, _):

return "Server error: \(code)"

case .decodingError:

return "Failed to parse response"

case .networkError:

return "Network connection failed"

}

}

}


**Request/Response Models**:
- Separate DTOs (Data Transfer Objects) from domain models
- Keep in `Core/Networking/RequestModels/` and `ResponseModels/`
- Map from DTO to domain model in service layer

**Error Handling Strategy**:
- Use typed errors (APIError enum)
- Provide user-friendly messages
- Log technical details for debugging
- Implement retry with exponential backoff for transient failures
- Cache responses when appropriate

**Caching**:
- Use URLCache for HTTP caching (images, static content)
- Implement custom cache for API responses (if needed)
- Cache strategy: Cache-Control headers + custom logic

---

## 5. Security & Privacy

### 5.1 Data Security

**Sensitive Data Storage**:

// KeychainManager for secure storage

final class KeychainManager {

static let shared = KeychainManager()

func save(key: String, data: Data) throws {

let query: [String: Any] = [

kSecClass as String: kSecClassGenericPassword,

kSecAttrAccount as String: key,

kSecValueData as String: data

]

let status = SecItemAdd(query as CFDictionary, nil)

guard status == errSecSuccess else {

throw KeychainError.saveFailed(status)

}

}

func retrieve(key: String) throws -> Data {

let query: [String: Any] = [

kSecClass as String: kSecClassGenericPassword,

kSecAttrAccount as String: key,

kSecReturnData as String: true

]

var result: AnyObject?

let status = SecItemCopyMatching(query as CFDictionary, &result)

guard status == errSecSuccess, let data = result as? Data else {

throw KeychainError.retrieveFailed(status)

}

return data

}

}


**Encryption**:
- API tokens: Stored in Keychain
- User passwords: Never stored locally (use tokens)
- Sensitive files: Encrypt with CryptoKit before saving
- Database: SwiftData encryption enabled (if available)

**Communication Security**:
- All API calls over HTTPS
- TLS 1.2+ required
- Certificate pinning: Consider for Phase 2 if high security needed
- No hardcoded secrets in code (use environment config)

### 5.2 Privacy

**Privacy Manifest** (PrivacyInfo.xcprivacy):

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>NSPrivacyTracking</key>

<false/>

<key>NSPrivacyTrackingDomains</key>

<array/>

<key>NSPrivacyCollectedDataTypes</key>

<array>

<dict>

<key>NSPrivacyCollectedDataType</key>

<string>NSPrivacyCollectedDataTypeEmailAddress</string>

<key>NSPrivacyCollectedDataTypeLinked</key>

<true/>

<key>NSPrivacyCollectedDataTypeTracking</key>

<false/>

<key>NSPrivacyCollectedDataTypePurposes</key>

<array>

<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>

</array>

</dict>

</array>

<key>NSPrivacyAccessedAPITypes</key>

<array>

<!-- List any required reason APIs used -->

</array>

</dict>

</plist>


**Data Collection Policy**:
- Collect minimum data necessary
- Document what data is collected and why
- Provide clear privacy policy
- Allow users to delete their data
- No tracking without explicit consent

**App Tracking Transparency**:
- Only if analytics/ads used
- Request permission with clear explanation
- App must work if denied

---

## 6. Performance Considerations

### 6.1 App Launch Optimization

**Cold Launch** (< 1.5s target):
- Defer non-critical initialization
- Use lazy loading for heavy components
- Optimize image assets (compress, use asset catalogs)
- Profile with Instruments (Time Profiler)

**Warm Launch** (< 0.5s target):
- Keep memory footprint low
- Proper state restoration

### 6.2 Memory Management

**Best Practices**:
- Use value types (structs) where possible
- Avoid retain cycles with `[weak self]` in closures
- Use `@MainActor` for UI updates
- Profile with Instruments (Leaks, Allocations)
- Implement proper deinitialization

**Image Handling**:
- Lazy loading with AsyncImage
- Downsample large images
- Cache thumbnail versions
- Use proper image formats (HEIC for photos)

### 6.3 Background Task Handling

**Background Refresh**:

// If needed for data sync

func scheduleBackgroundRefresh() {

BGTaskScheduler.shared.register(

forTaskWithIdentifier: "com.app.refresh",

using: nil

) { task in

self.handleBackgroundRefresh(task: task as! BGAppRefreshTask)

}

}


**Background URLSession**:
- For large downloads/uploads
- Continues even if app terminated
- Implement URLSessionDelegate

### 6.4 Launch Time Optimization

**Strategies**:
- Minimize work in app launch path
- Defer heavy operations to background
- Use lazy initialization
- Optimize image assets
- Remove unused frameworks

---

## 7. Testing Strategy

### 7.1 Unit Testing

**Coverage Target**: 70%+ for business logic

**What to Test**:
- ViewModels: All business logic methods
- Services: API calls, data transformations
- Models: Validation logic, computed properties
- Utilities: Pure functions

**Testing Framework**: XCTest

**Example**:

import XCTest

@testable import [AppName]

final class HomeViewModelTests: XCTestCase {

var sut: HomeViewModel!

var mockAPIClient: MockAPIClient!

var mockDataManager: MockDataManager!

override func setUp() {

super.setUp()

mockAPIClient = MockAPIClient()

mockDataManager = MockDataManager()

sut = HomeViewModel(

apiClient: mockAPIClient,

dataManager: mockDataManager

)

}

override func tearDown() {

sut = nil

mockAPIClient = nil

mockDataManager = nil

super.tearDown()

}

func testLoadItems_Success() async throws {

// Given

let expectedItems = [Item(id: UUID(), name: "Test")]

mockAPIClient.itemsToReturn = expectedItems

// When

await sut.loadItems()

// Then

XCTAssertEqual(sut.items, expectedItems)

XCTAssertFalse(sut.isLoading)

XCTAssertFalse(sut.showError)

}

func testLoadItems_Failure() async throws {

// Given

mockAPIClient.shouldThrowError = true

// When

await sut.loadItems()

// Then

XCTAssertTrue(sut.showError)

XCTAssertNotNil(sut.errorMessage)

XCTAssertTrue(sut.items.isEmpty)

}

}


### 7.2 UI Testing

**Coverage Target**: Critical user journeys only (~10% of tests)

**What to Test**:
- Onboarding flow
- Core feature happy paths
- Error state handling
- Navigation flows

**Framework**: XCTest with XCUITest

**Best Practices**:
- Use accessibility identifiers
- Test user-facing behavior, not implementation
- Keep tests independent
- Use test plans for different configurations

### 7.3 Integration Testing

**What to Test**:
- API integration (with mock backend or staging)
- SwiftData CRUD operations
- Background tasks
- Deep linking

### 7.4 Mocking Strategy

**Mock Types**:
- Protocol-based mocks for dependencies
- In-memory storage for tests
- Mock API client with canned responses

**Dependency Injection**:
- Use initializer injection for testability
- Provide default values for production
- Override with mocks in tests

---

## 8. Deployment & DevOps

### 8.1 Build Configurations

**Debug**:
- Optimization: None (-Onone)
- Assertions: Enabled
- Logging: Verbose
- API endpoint: Development/Staging
- Crashlytics: Disabled

**Release**:
- Optimization: Speed (-O)
- Assertions: Disabled
- Logging: Errors only
- API endpoint: Production
- Crashlytics: Enabled
- Strip debug symbols: Yes

### 8.2 Environment Management

**Configuration**:

enum Environment {

case development

case staging

case production

static var current: Environment {

#if DEBUG

return .development

#else

return .production

#endif

}

var apiBaseURL: URL {

switch self {

case .development:

return URL(string: "https://dev.api.example.com")!

case .staging:

return URL(string: "https://staging.api.example.com")!

case .production:

return URL(string: "https://api.example.com")!

}

}

}


### 8.3 CI/CD

**Recommended**: Xcode Cloud or GitHub Actions

**Pipeline Stages**:
1. **On Pull Request**:
   - Run SwiftLint
   - Build project
   - Run unit tests
   - Generate code coverage report

2. **On Merge to Main**:
   - Full test suite (unit + UI)
   - Build release configuration
   - Archive build

3. **On Tag** (e.g., v1.0.0):
   - Build release
   - Upload to TestFlight
   - Create GitHub release

**Example GitHub Actions** (placeholder):

name: CI

on: [pull_request, push]

jobs:

test:

runs-on: macos-latest

steps:

  • uses: actions/checkout@v4
  • name: Build and Test

run: |

xcodebuild clean build test \

-scheme [AppName] \

-destination 'platform=iOS Simulator,name=iPhone 15'


### 8.4 Feature Flags

**Implementation**: (If needed for gradual rollouts)
- Use remote config (Firebase Remote Config, Launch Darkly, or custom)
- Local override for testing
- A/B testing capability

---

## 9. Technical Risks & Mitigations

### Risk 1: SwiftData Maturity (iOS 17+ framework)

**Risk**: SwiftData is relatively new, may have bugs or limitations
**Impact**: Data loss, migration issues, performance problems
**Probability**: Medium
**Mitigation**:
- Thorough testing of CRUD operations
- Implement backup mechanism
- Have Core Data migration path ready as fallback
- Monitor SwiftData-related crashes closely
**Fallback**: Migrate to Core Data if critical issues found

### Risk 2: iOS 17+ Minimum Version

**Risk**: Limits addressable market (older iOS versions excluded)
**Impact**: Reduced potential user base
**Probability**: Certain
**Mitigation**:
- Validate market data (% of users on iOS 17+)
- Accept trade-off for modern APIs
- Plan for iOS 16 support in future if needed
**Decision**: Accept for MVP, modern APIs worth the trade-off

### Risk 3: Network Dependency

**Risk**: App requires network for most features
**Impact**: Poor user experience in offline scenarios
**Probability**: High
**Mitigation**:
- Implement robust offline support with local caching
- Sync when network available
- Clear messaging when offline
- Core features work offline where possible
**Fallback**: None - core to architecture

### Risk 4: Third-Party API Reliability

**Risk**: Backend API downtime or rate limiting
**Impact**: App functionality degraded
**Probability**: Low-Medium
**Mitigation**:
- Implement proper error handling
- Retry logic with exponential backoff
- Cache responses locally
- Graceful degradation
- Monitor API health

---

## 10. Future Considerations

### Phase 2 Enhancements

**After MVP Launch**:
1. **iPad Support**: Adapt layouts for larger screens
2. **macOS Catalyst**: Cross-platform desktop version
3. **Widgets**: Home screen and Lock screen widgets
4. **Watch App**: Companion watchOS app
5. **App Clips**: Lightweight app clip for quick access
6. **CloudKit Sync**: Cross-device synchronization
7. **Offline-First**: Enhance offline capabilities
8. **Performance**: Optimize based on real-world metrics
9. **Accessibility**: Enhanced VoiceOver support, keyboard shortcuts
10. **Localization**: Additional languages

### Technology Updates

**Monitor**:
- SwiftUI updates in future iOS versions
- SwiftData improvements and bug fixes
- New Apple frameworks (announced at WWDC)
- Swift language evolution proposals

---

## 11. Documentation & Knowledge Sharing

**Code Documentation**:
- Use Swift DocC comments for public APIs
- Document complex algorithms
- Keep README updated
- Maintain CHANGELOG

**Architecture Decision Records (ADRs)**:
- Document major architectural decisions
- Include context, options considered, decision, consequences
- Store in docs/architecture/decisions/

**Onboarding**:
- Architecture overview for new developers
- Setup guide (README.md)
- Coding standards document
- PR review checklist

---

## 12. Success Metrics

**Technical KPIs**:
- Crash-free rate: > 99.5%
- App launch time (cold): < 1.5s
- App launch time (warm): < 0.5s
- Network request latency (95th percentile): < 2s
- Test coverage: > 70% for business logic
- Build time: < 10 minutes (for CI)

**Monitoring**:
- Crashlytics / Firebase Crashlytics
- Performance monitoring (Xcode Organizer, MetricKit)
- Network monitoring (URLSession metrics)
- Custom analytics (if needed)

---

## Appendix A: Coding Standards

### Swift Style Guide
- Follow [Swift.org API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)
- Use SwiftLint for consistency
- Naming conventions:
  - Types: PascalCase
  - Variables/functions: camelCase
  - Constants: camelCase (not SCREAMING_SNAKE_CASE)

### SwiftUI Best Practices
- Keep views small and focused
- Extract subviews for reusability
- Use @ViewBuilder for custom DSLs
- Prefer property wrappers (@State, @Binding) over manual management

### Concurrency
- Always use async/await over completion handlers
- Mark UI updates with @MainActor
- Use actors for thread-safe shared state
- Avoid @unchecked Sendable unless necessary

---

## Appendix B: Reference Links

- [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)
- [SwiftUI Documentation](https://developer.apple.com/documentation/swiftui)
- [SwiftData Documentation](https://developer.apple.com/documentation/swiftdata)
- [Swift Concurrency](https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html)
- [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)

---

**Document History**:
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0.0 | [Date] | [Name] | Initial architecture design |

Execution Instructions

When activated, follow these steps:

  1. Read PRD
   Read docs/PRD.md
   Extract:
   - Core features and complexity level
   - Non-functional requirements
   - Platform requirements (iOS version)
   - Data model hints from user stories
   - Technical requirements section
  1. Assess Complexity
  • Simple (1-3 core features, basic CRUD): MVVM with SwiftUI
  • Medium (4-8 features, some complexity): MVVM or Clean Architecture
  • Complex (9+ features, high complexity): Clean Architecture or TCA
  1. Make Technology Decisions

Based on PRD requirements and iOS version target:

  • iOS 17+ → SwiftUI + SwiftData + @Observable (recommended)
  • iOS 16+ → SwiftUI + Core Data + Combine
  • UIKit → Only if strong reason (legacy, specific UI needs)
  1. Ask User Preferences (if needed)
   Quick questions about the architecture:

   1. Do you have a preference for UI framework?
      - SwiftUI (modern, recommended for iOS 17+)
      - UIKit (if you need more control or have existing UIKit code)

   2. Do you have a backend API already?
      - Yes → Focus on networking layer
      - No → Focus on local-first architecture

   3. Any required third-party libraries?
      - List them, or say "minimize dependencies"
  1. Create Output Directory
   mkdir -p docs
  1. Generate ARCHITECTURE.md
  • Use template above
  • Fill in all sections with specific, opinionated choices
  • Make architectural decisions and explain reasoning
  • Design data models based on PRD features
  • Define complete module structure
  1. Write to File
   Write to: docs/ARCHITECTURE.md
  1. Present Summary
   ✅ Technical Architecture generated!

   🏗️ **Architecture Summary**:
   - Document: docs/ARCHITECTURE.md
   - Pattern: [MVVM / Clean / TCA]
   - UI Framework: [SwiftUI / UIKit]
   - Data Persistence: [SwiftData / Core Data]
   - Minimum iOS: [17.0 / 16.0 / 15.0]
   - Third-party deps: [X] (or "None - Apple frameworks only")
   - Data models: [X] entities defined

   **Key Decisions**:
   1. [Decision 1]: [Choice] - [Reason]
   2. [Decision 2]: [Choice] - [Reason]
   3. [Decision 3]: [Choice] - [Reason]

   **Next Steps**:
   1. Review the architecture in docs/ARCHITECTURE.md
   2. Confirm technology stack choices
   3. Once approved, we can proceed to UX spec

   Any questions or changes to the architecture?
  1. Iterate if Needed
  • If user wants different tech stack, regenerate relevant sections
  • If user disagrees with pattern choice, explain and offer alternative
  • Update document with changes

Quality Guidelines

  1. Be Opinionated: Make clear technology choices
  • BAD: "You could use SwiftUI or UIKit"
  • GOOD: "Using SwiftUI because iOS 17+ target allows modern APIs and declarative UI is more maintainable"
  1. Explain Reasoning: Every major decision should have rationale
  • Why this architecture pattern?
  • Why these frameworks?
  • Why these trade-offs?
  1. Be Specific: Provide actual code examples
  • Show data model structure
  • Show networking client design
  • Show ViewModel pattern
  1. Consider Trade-offs: Document risks and mitigations
  • What could go wrong?
  • How do we handle it?
  • What's the backup plan?
  1. Stay Current: Use modern Swift and iOS features
  • iOS 17+: SwiftData, @Observable, ContentUnavailableView
  • async/await over completion handlers
  • Actors for thread safety
  1. Follow Apple HIG: Architecture should enable HIG compliance
  • Native patterns (NavigationStack, TabView)
  • Platform conventions
  • Accessibility built-in

Integration with Workflow

This skill is typically:

  • Second step in implementation specification generation (after prd-generator)
  • Activated after PRD is approved
  • Followed by ux-spec, implementation-guide, test-spec, release-spec

The architecture document guides all downstream technical decisions.

Notes

  • Be pragmatic: Choose technologies that fit the problem
  • Start simple: MVVM + SwiftUI + SwiftData is a great default
  • Document decisions: Future developers will thank you
  • Consider team skills: If team is UIKit-expert, maybe stick with UIKit
  • Balance modern vs stable: Bleeding edge isn't always best
  • MVP mindset: Perfect is enemy of shipped

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。