iOS 开发进阶之路:从能跑到能维护

iOS 开发进阶之路:从能跑到能维护

写一个能跑的 App 只需要三天,写一个三年后还能改的 App,需要的不止是代码。

一、选对语言,事半功倍

iOS 开发现在两条主线:

语言 框架 适用场景 特点
Swift SwiftUI 新项目、iOS 16+ 声明式、跨平台(iOS/macOS/watchOS)、代码量少
Swift UIKit 需要精细控制、兼容旧版本 命令式、成熟稳定、生态丰富
Objective-C UIKit 老项目维护、底层桥接 逐步退出历史舞台

建议:2025 年以后的新项目,直接 Swift + SwiftUI 起步。UIKit 不需要全会,但要能读能改------太多存量项目了。

二、架构不是玄学,是经验压缩

从 MVC → MVVM → TCA,经历了什么?

MVC (Massive View Controller)

复制代码
┌─────────────────────────────────┐
│         ViewController          │
│  ┌──────────┐  ┌─────────────┐  │
│  │   View   │  │  Networking  │  │
│  ├──────────┤  ├─────────────┤  │
│  │  Model   │  │   Storage    │  │
│  ├──────────┤  ├─────────────┤  │
│  │ Delegate │  │   Routing    │  │
│  └──────────┘  └─────────────┘  │
│        一个 VC 干了所有事          │
└─────────────────────────────────┘

一个 ViewController 动辄 2000 行,改个颜色要翻半小时------这就是 MVC 的日常。

MVVM --- 把逻辑抽出来

swift 复制代码
// ViewModel 不 import UIKit,纯逻辑层
class ProfileViewModel: ObservableObject {
    @Published var user: User?
    @Published var isLoading = false
    @Published var errorMessage: String?

    private let userService: UserServiceProtocol

    func loadProfile() async {
        isLoading = true
        defer { isLoading = false }
        do {
            user = try await userService.fetchProfile()
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}

关键约束:

  • ViewModel 不引用 UIKit,可纯 Swift 测试
  • View 只做展示和交互转发,不做业务判断
  • 依赖注入走 Protocol,不直接 URLSession.shared

TCA (The Composable Architecture) 适合复杂状态管理,但学习曲线陡峭。中小团队 MVVM 完全够用,别为了用而用。

我推荐的轻量架构方案

复制代码
View (SwiftUI)          ←  只管画
    ↓ @StateObject / @ObservedObject
ViewModel               ←  业务逻辑,纯 Swift
    ↓ Protocol
Service Layer           ←  网络、数据库、缓存
    ↓
Data Layer              ←  Core Data / SwiftData / Realm

三层够用,别搞成六层地狱。

三、你一定会踩的五个坑

1. 内存泄漏 --- 闭包循环引用

swift 复制代码
// ❌ 经典错误 ------ 闭包强引用了 self
viewModel.onDataLoaded = { data in
    self?.tableView.reloadData()
}

// ✅ 正确姿势
viewModel.onDataLoaded = { [weak self] data in
    guard let self = self else { return }
    self.tableView.reloadData()
}

工具:Xcode → Debug Memory Graph,定期检查,养成习惯。

2. 线程 --- UI 更新必须在主线程

swift 复制代码
// ❌ 后台线程更新 UI → 随机崩溃
Task {
    let data = await fetchData()
    label.text = data.title  // 💥 必崩
}

// ✅ 方案一:MainActor.run
Task {
    let data = await fetchData()
    await MainActor.run { label.text = data.title }
}

// ✅ 方案二:标记整个方法
@MainActor
func updateUI(with data: MyData) {
    label.text = data.title
}

3. App 生命周期 --- SceneDelegate 的变化

iOS 13 之后引入了 SceneDelegate 支持多窗口,很多老教程还是 AppDelegate 单窗口模式。

swift 复制代码
// SwiftUI 直接用 @main App 结构体
@main
struct MyApp: App {
    @Environment(\.scenePhase) var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onChange(of: scenePhase) { newPhase in
                    switch newPhase {
                    case .active:      print("回前台了")
                    case .inactive:    break
                    case .background:  print("存数据,快!")
                    }
                }
        }
    }
}

4. 包管理 --- 别乱加依赖

SPM(Swift Package Manager)很好用,但:

  • 能自己写的别加库:200 行工具类不值得一个外部依赖
  • Star 多 ≠ 维护好:看 commit 频率和 issue 响应速度
  • 锁版本Package.resolved 必须提交到 Git
  • 依赖审计:定期检查还有哪些库在更新、哪些已经死了

5. App Store 审核 --- 血的教训

  • 隐私清单(Privacy Manifest)必须完整,第三方 SDK 的也要加
  • 权限描述别写"需要使用相册",写成"用于上传头像和分享图片"
  • 内购统一走 StoreKit 2,别自己搞支付
  • Guideline 4.3(马甲包)现在查得非常严,别心存侥幸

四、写测试,不是可选项

swift 复制代码
// 测试 ViewModel,不需要启动 App
func testLoadProfile_Success() async {
    let mockService = MockUserService()
    mockService.mockUser = User(name: "测试用户")

    let vm = ProfileViewModel(userService: mockService)
    await vm.loadProfile()

    XCTAssertEqual(vm.user?.name, "测试用户")
    XCTAssertFalse(vm.isLoading)
    XCTAssertNil(vm.errorMessage)
}

核心原则:

  • ViewModel 层必须可测试(走协议注入,Mock 驱动)
  • UI 层可以不测(变化太快,投入产出比低)
  • 关键业务逻辑必须有测试(支付流程、数据转换、权限校验)

五、持续学习路线图

复制代码
阶段一(0-3月)     Swift 基础 → SwiftUI 入门 → 简单 Todo App
阶段二(3-6月)     UIKit 补齐 → 网络层 → 数据库 → 完整上线项目
阶段三(6-12月)    架构设计 → 单元测试 → CI/CD → App Store 上架
阶段四(1年+)      性能优化 → 底层原理 → 开源贡献 → 技术选型决策

每个阶段的关键产出物要能跑、能展示、能写到简历里。

六、好用的工具和资源

调试工具

工具 用途
Charles / Proxyman HTTP/HTTPS 抓包,排查接口问题
Reveal 3D 视图层级调试,找出布局问题
Instruments 性能分析(内存、CPU、能耗)

代码质量

工具 用途
SwiftLint 代码风格统一,自动检查规范
Periphery 找出未使用的代码,清理死代码
SwiftFormat 自动格式化代码

CI/CD

工具 特点
Xcode Cloud Apple 官方,无缝集成
Fastlane 最灵活的自动化工具
GitHub Actions 免费额度够用,社区 Action 丰富

学习资源

  • Hacking with Swift --- 最好的免费教程,没有之一
  • Swift By Sundell --- 深度文章和工作坊
  • Kavsoft --- SwiftUI 动效和复杂交互示例
  • iOS Dev Weekly --- 每周精选,保持信息不落后
  • SwiftLee --- 实战技巧,每周更新

七、一个真实项目的目录结构参考

复制代码
MyApp/
├── App/
│   └── MyApp.swift                    # @main 入口
├── Features/
│   ├── Home/
│   │   ├── HomeView.swift
│   │   └── HomeViewModel.swift
│   ├── Profile/
│   │   ├── ProfileView.swift
│   │   └── ProfileViewModel.swift
│   └── Settings/
│       ├── SettingsView.swift
│       └── SettingsViewModel.swift
├── Core/
│   ├── Network/
│   │   ├── APIClient.swift
│   │   └── Endpoint.swift
│   ├── Storage/
│   │   └── UserDefaultsManager.swift
│   └── Extensions/
│       └── View+Extensions.swift
├── Models/
│   ├── User.swift
│   └── Post.swift
├── Resources/
│   ├── Assets.xcassets
│   └── Localizable.strings
└── Tests/
    ├── HomeViewModelTests.swift
    └── APIClientTests.swift

按 Feature 而不是按类型分------这样加新功能时不用在十几个文件夹之间跳。

写在最后

iOS 开发生态跟五年前完全不同了。Swift 从青涩走向成熟,SwiftUI 从玩具变成生产力,Vision Pro 和 Apple Watch 让跨 Apple 平台开发成了真实的日常需求。

但不管技术怎么变,有几件事永远不会过时:

  1. 写能改的代码,而不是能跑的代码。
  2. 理解 Apple 的设计哲学,比背 API 重要一百倍。
  3. 保持小步迭代,别追求一次完美。

本文适合有半年以上 iOS 开发经验、希望系统提升工程能力的开发者阅读。如果你是纯新手,建议先从 Hacking with Swift 的 100 Days of SwiftUI 开始。

相关推荐
QuestLab1 小时前
【第23期】2026年4月26日 AI日报
人工智能
AIminminHu2 小时前
((AI篇)OpenGL渲染与几何内核那点事-(二-1-(10):从“搜个大概”到“读懂图纸”:一个 CAD 开发者眼中的 RAG 进化简史)
人工智能·agent·opengl·智能体
SmartBrain2 小时前
AI技术演进与实战路径洞察
人工智能·架构·aigc
冰西瓜6002 小时前
深度学习的数学原理(三十一)—— Transformer前馈网络FFN(为什么要先升维再降维)
人工智能·深度学习·transformer
szxinmai主板定制专家2 小时前
基于ZYNQ MPSOC多通道声音振动采集方案,替代NI9234和B&K
arm开发·人工智能·嵌入式硬件·fpga开发
ZGi.ai2 小时前
ZGI四层能力架构:一个企业AI底座的设计逻辑
人工智能·架构
AI 赋能2 小时前
深入探讨OpenAI ChatGPT 4o图像API的运用与操作
人工智能·chatgpt
MonkeyKing2 小时前
iOS 音频会话 AVAudioSession 完整机制:分类、模式、激活策略
ios·音视频开发
格林威2 小时前
面阵相机 vs 线阵相机:堡盟与海康相机选型差异全解析 附Python实战演示
开发语言·人工智能·python·数码相机·计算机视觉·视觉检测·工业相机