CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
SwiftUI 开发入门/课时/MVVM 与架构
RawBlame
课时目录12 节

SwiftUI 开发入门

  1. 01Swift 与 SwiftUI 概览
  2. 02基础语法与类型
  3. 03控制流
  4. 04函数与闭包
  5. 05结构体、类与协议
  6. 06SwiftUI 视图
  7. 07状态管理
  8. 08导航与生命周期
  9. 09并发与 async/await
  10. 10数据持久化
  11. 11MVVM 与架构
  12. 12综合练习

MVVM 与架构

Clean Architecture、依赖注入。

30 分钟

MVVM 与架构

SwiftUI 项目推荐 MVVM + Repository:View 薄、ViewModel 编排业务、Repository 抽象数据源。对照 /roadmaps/swift-ui「架构」节点,清晰分层便于测试与扩展。

学习目标

  • 理解 MVVM 在 SwiftUI 中的职责划分
  • 用 Protocol 定义 Repository,支持依赖注入
  • 了解 Clean Architecture 分层思想
  • 组织可维护的项目目录结构

核心概念

MVVM 分层

// Model
struct Track: Identifiable, Codable, Equatable {
    let id: Int
    var title: String
    var lessonCount: Int
}

// Repository 协议
protocol TrackRepositoryProtocol {
    func fetchAll() async throws -> [Track]
}

// 实现:可替换为网络 / 本地
final class TrackRepository: TrackRepositoryProtocol {
    func fetchAll() async throws -> [Track] {
        try await Task.sleep(nanoseconds: 300_000_000)
        return [
            Track(id: 1, title: "SwiftUI 入门", lessonCount: 12),
            Track(id: 2, title: "React 对照", lessonCount: 10),
        ]
    }
}

// ViewModel
@MainActor
final class TrackListViewModel: ObservableObject {
    @Published var tracks: [Track] = []
    @Published var isLoading = false
    @Published var errorMessage: String?

    private let repository: TrackRepositoryProtocol

    init(repository: TrackRepositoryProtocol = TrackRepository()) {
        self.repository = repository
    }

    func load() async {
        isLoading = true
        errorMessage = nil
        do {
            tracks = try await repository.fetchAll()
        } catch {
            errorMessage = error.localizedDescription
        }
        isLoading = false
    }
}

// View:只负责 UI
struct TrackListScreen: View {
    @StateObject private var viewModel = TrackListViewModel()

    var body: some View {
        Group {
            if viewModel.isLoading {
                ProgressView()
            } else {
                List(viewModel.tracks) { track in
                    Text("\(track.title)(\(track.lessonCount) 课)")
                }
            }
        }
        .task { await viewModel.load() }
        .alert("错误", isPresented: .constant(viewModel.errorMessage != nil)) {
            Button("确定") { viewModel.errorMessage = nil }
        } message: {
            Text(viewModel.errorMessage ?? "")
        }
    }
}

View 不含业务逻辑;ViewModel 通过 Protocol 注入 Repository,单元测试可传入 Mock。

项目结构

SwiftUIApp/
├── App/
│   └── SwiftUIAppApp.swift
├── Models/
│   └── Track.swift
├── ViewModels/
│   └── TrackListViewModel.swift
├── Views/
│   └── TrackListScreen.swift
├── Services/
│   └── TrackRepository.swift
└── Tests/
    └── TrackListViewModelTests.swift

Clean Architecture 可进一步分 Domain(用例)与 Data 层;中小 SwiftUI 项目 MVVM + Repository 通常足够。

与 React/SwiftUI 对照

SwiftUI MVVMReact 架构职责
View组件 JSX渲染 UI
ViewModelCustom Hook / Zustand状态与编排
RepositoryAPI module / React Query数据获取
ProtocolTypeScript interface抽象依赖
@StateObjectuseState(store)持有 ViewModel
Coordinator(可选)React Router导航解耦

React 常把 ViewModel 逻辑放在 Custom Hook(如 useTrackList);SwiftUI 用 ObservableObject class 承载同等职责。

练习

  • 为 Track 列表实现 MVVM 三层,View 不超过 30 行逻辑
  • 编写 MockTrackRepository 供 Preview 与测试使用
  • 画 View → ViewModel → Repository 数据流图
  • 对照 react-essentials Hook 模式比较异同

小结

View 薄 + ViewModel 编排 + Repository 抽象数据源 = 可测 SwiftUI 架构。 下一课综合练习。见 swift-ui-essentials。

加载本节练习…
← 上一课数据持久化下一课 →综合练习