iOS 的修炼之道
轻记账的 Android 版上线后,老板看到后台数据:iPhone 用户占了四成——「iOS 必须做!」小哲刚学完 Android(第十七本)和 Windows(第十八本),正好全程对照学:Swift 对 Kotlin、SwiftUI 对 Compose、App Store 对应用商店。周师傅说:iOS 是个「围墙花园」——技术不难,规矩特别多。这一本,从系统架构讲到上架审核。
苹果生态的入场券
iOS 开发全景:语言 + 框架 + 生态规则师傅!老板要看 iPhone 用户的数据——四成!「iOS 必须做!」我刚学完 Android,Swift 和 Kotlin 像不像?能不能直接上手?
好消息:iOS 和 Android 的「骨架」几乎一一对应——Swift ≈ Kotlin、SwiftUI ≈ Compose、MVVM 两边同款。你学 Android 的功夫全能用上。
但 iOS 有「三件新东西」必须重新学:
- 苹果生态:沙箱、App 生命周期、Scene——系统规则不同。
- 开发工具链:Xcode(只能在 Mac 上开发!)、TestFlight、证书签名。
- App Store 规矩:审核、抽成、隐私标签——苹果的「法律」特别严。
来,十站路线——
记住一句话:iOS 开发 = 技术(Swift/SwiftUI,Android 兄弟)+ 生态(沙箱/生命周期)+ 规矩(审核/隐私/抽成)。走,第一站,看看 iPhone 的「内部构造」。
平台架构:系统怎么组织
Darwin/XNU · Cocoa Touch · 沙箱 · App 状态机iOS 系统怎么组织?App 怎么被「关起来」?和 Android 的 Linux 内核 + 沙箱比,苹果的「围墙」更严密——这直接决定了开发方式。
iOS 平台四层:
- Darwin 内核(XNU):BSD Unix 血统的微内核——进程/内存管理(和 Android 的 Linux 内核「同源不同派」)。
- 系统服务层:Core Foundation、文件系统、安全服务——底层能力。
- 媒体/图形层:Core Animation、Core Graphics——流畅动画的引擎。
- Cocoa Touch 层:开发者用的框架——UIKit/SwiftUI、Foundation、相机/定位(≈ Android 的应用框架层)。
关键认知:沙箱(Sandbox)——每个 App 只能访问自己的目录和权限内的系统服务,比 Android 更严(iPhone 不开源 + 单渠道分发 = 更封闭也更安全)。
┌────────────────────────────────────┐
│ Cocoa Touch:UIKit/SwiftUI 框架 │ ← 开发者在这(≈ Android 框架层)
├────────────────────────────────────┤
│ 媒体层:Core Animation/Graphics │ ← 流畅动画
├────────────────────────────────────┤
│ 系统服务:Core Foundation/文件/安全 │
├────────────────────────────────────┤
│ Darwin(XNU 内核) │ ← BSD Unix 血统(≈ Linux 内核)
└────────────────────────────────────┘
【沙箱(比 Android 更严)】
每个 App 独立目录(Documents/Library/tmp)
只能访问自己沙箱 + 用户授权的资源(相册/定位)
后台能力受限(后台任务有时间限制)
【App 状态机(iOS 13+ Scene 版)】
NotRunning(没启动)
→ Inactive(前台但无交互:来电/通知)
→ Active(前台可交互)
→ Background(后台:保留内存但受限)
→ Suspended(挂起:内存还在,随时可能被清)
→ 系统内存紧张 → 杀 Suspended 进程(和 Android 同款命运!)
【对比 Android(第十七本)】
iOS:沙箱更严 + 单渠道(App Store)+ 不开源
Android:沙箱 + 多渠道 + 开源
→ 开发逻辑相通,生态规则不同(第10站)
【开发硬性前提】
必须 Mac 电脑 + Xcode!(Windows 装虚拟机也不行——苹果强制)
iPhone 真机调试 + 开发者账号($99/年)
平台术语
- Darwin / XNU:BSD Unix 血统内核——iOS 的地基。
- Cocoa Touch:开发者框架层——UIKit/SwiftUI 的舞台。
- 沙箱(Sandbox):App 目录隔离 + 权限受限——比 Android 更严。
- App 状态机:Active/Background/Suspended——后台被清是常态。
- Scene(场景):iOS 13+ 多窗口生命周期模型。
- Xcode 独占:必须 Mac + Xcode 开发——硬性门槛。
- 开发者账号:$99/年——上架必备。
本站收获:平台认知 = Darwin 内核 + Cocoa Touch + 严沙箱 + App 状态机。和 Android 同构但更封闭——「进程会被清」的宿命两边一样,所以状态保存都是必修课。
Swift:现代语言
可选类型 · 协议导向 · struct · 闭包 · 与 Kotlin 对照Swift 是苹果 2014 年推出的现代语言——如果你会 Kotlin(第十七本),Swift 就像「表兄弟」:空安全、函数式、简洁,几乎处处对应。
Swift 五大看点(全程对照 Kotlin):
- 可选类型(Optional):`String?` + 解包语法——和 Kotlin 空安全一模一样(`?`/`!`/`??`)。
- struct 是主角:值类型(拷贝传递)优先于 class——Swift 里 struct 也能有方法(和 Kotlin 的 data class/Java record 同思路,但更彻底)。
- 协议导向(Protocol):接口即协议 + 扩展(extension 加默认实现)——比 Java 接口更灵活。
- 闭包(Closure):函数一等公民——map/filter/reduce(全系列老朋友)。
- Swift 与 Objective-C:老代码是 OC——现代新代码全用 Swift,两者能互调(和 Kotlin/Java 互操作同款)。
// 可选类型:空安全(Kotlin 同款)
var name: String? = nil
let display = name ?? "匿名用户" // Elvis 运算符(?: 的 Swift 版)
print(display)
// struct:值类型 + 方法(比 Kotlin data class 更常用)
struct User {
var id: Int
var name: String
var phone: String?
}
// 协议 + 扩展:接口 + 默认实现
protocol Payable { func pay(amount: Double) }
extension Payable {
func pay(amount: Double) { print("支付 \(amount) 元") } // 默认实现
}
struct Card: Payable {} // 零代码继承默认实现
// 闭包:函数式(map/filter/reduce)
let adults = users
.filter { $0.age >= 18 }
.map { $0.name }
.sorted()
// async/await(第6站主角)
func loadData() async throws -> [Order] {
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode([Order].self, from: data)
}
【Swift vs Kotlin(表兄弟对照)】
可选类型 String? ≈ Kotlin String?
结构体 struct ≈ data class(但 Swift 更常用)
协议 protocol ≈ interface + 扩展函数
闭包 { $0.x } ≈ lambda { it.x }
async/await ≈ suspend/协程
→ 会 Kotlin 的人,Swift 两天上手!
【Playground 练手】
Xcode 里的「游乐场」——边写边看结果(类似 Jupyter)
Swift 术语
- 可选类型(Optional):`?`/`!`/`??`——空安全三件套(Kotlin 同款)。
- struct vs class:值类型 vs 引用类型——Swift 里 struct 是主角。
- 协议(Protocol):接口 + extension 默认实现——协议导向开发。
- 闭包(Closure):函数一等公民——{ $0 } 简洁语法。
- 泛型 / Result / enum 关联值:高级语法——类型安全专家。
- Objective-C 互操作:老代码桥接——Swift 兼容 OC。
- Playground:Xcode 游乐场——边写边看。
本站收获:Swift = Kotlin 的表兄弟——空安全、协议、闭包、async/await 处处对应。会 Kotlin/Java 的你,Swift 上手极快——真正的门槛在框架不在语言。
UI 开发:SwiftUI 与 UIKit
SwiftUI(声明式)· UIKit(命令式)· @State · MVVMiOS 的 UI 有「两代人」:老一代 UIKit(命令式),新一代 SwiftUI(声明式)——学过 Android Compose 的你,SwiftUI 就是「苹果版 Compose」。
两代 UI 对比:
- UIKit(老):命令式——代码创建控件、手动约束布局(Auto Layout)、手动更新界面。存量 App 的大头,维护会碰到。
- SwiftUI(新):声明式——界面 = f(状态),状态变界面自动更新(2019 年推出,苹果力推的新方向)。
SwiftUI 核心:@State(局部状态)、@Binding(父子传值)、@ObservedObject/@Published(跨界面状态)——和 Compose 的 remember/state 一一对应。
布局系统:VStack/HStack(纵向/横向)、List(列表)、NavigationStack(导航)——Compose 的 Column/Row/LazyColumn 亲戚。
import SwiftUI
struct OrderListView: View {
@StateObject private var vm = OrderViewModel() // 状态(≈ ViewModel)
var body: some View {
NavigationStack {
List(vm.orders) { order in // 列表(≈ LazyColumn)
HStack {
VStack(alignment: .leading) {
Text(order.title).font(.headline)
Text("¥\(order.amount)").foregroundStyle(.blue)
}
Spacer()
Image(systemName: "checkmark.circle")
}
}
.navigationTitle("我的账单")
.toolbar {
Button("刷新") { vm.refresh() } // 命令绑定
}
}
}
}
// 状态驱动:点一下,界面自动更新(≈ mutableStateOf)
struct CounterView: View {
@State private var count = 0
var body: some View {
Button("点击了 \(count) 次") { count += 1 }
}
}
【SwiftUI vs Compose(完全对照)】
@State / @StateObject ≈ mutableStateOf / ViewModel
List / HStack/VStack ≈ LazyColumn / Row / Column
NavigationStack ≈ NavHost
.foregroundStyle(.blue)≈ Modifier.color(Blue)
body: some View ≈ @Composable fun
→ 声明式 UI 的哲学完全一致!
【UIKit 老项目要点(维护会碰到)】
Storyboard(可视化布局)/ Auto Layout(约束)
UITableView / UIViewController
→ 新代码用 SwiftUI,老项目 UIKit——两边都要能读
UI 术语
- SwiftUI:声明式 UI 框架——2019 年推出,新方向。
- UIKit:命令式 UI 框架——存量 App 的大头。
- @State / @StateObject:状态管理——界面自动更新。
- @Published:可观察属性——跨界面状态。
- List / HStack / VStack:列表 / 横排 / 竖排——布局积木。
- NavigationStack:导航容器——页面跳转。
- SwiftUI ≈ Compose:声明式哲学完全一致——Android 兄弟直接迁移。
本站收获:SwiftUI = 苹果版 Compose——声明式 + 状态驱动 + @State。会 Compose 的你直接迁移;老项目遇到 UIKit 能读懂即可——「新写 SwiftUI,老读 UIKit」。
生命周期:App 的活法
App/Scene 生命周期 · View 生命周期 · 状态恢复iOS App 的「生死簿」:前台/后台/挂起/被杀——和 Android 一样,系统随时可能回收进程。所以「保存状态」是 iOS 开发的基本功。
iOS 有两层生命周期要懂:
- App/Scene 生命周期:iOS 13+ 用 Scene——Active(前台可交互)→ Background(后台)→ Suspended(挂起)→ 可能被杀。切后台前要「存状态」。
- View 生命周期:SwiftUI 用 `onAppear/onDisappear`(出现/消失回调);UIKit 的 ViewController 有 viewDidLoad/viewWillAppear 等(和 Android Activity 生命周期同思路)。
状态恢复:App 被系统杀掉再回来——用 Scene 状态恢复(scenePhase 判断 + 保存数据),让用户「感觉没离开过」。
// Scene 生命周期监听(@Environment scenePhase)
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
Text("你好,iOS")
.onAppear { loadData() } // 界面出现:加载数据
.onDisappear { cleanup() } // 界面消失:清理
.onChange(of: scenePhase) { _, phase in
switch phase {
case .active: refresh() // 回前台:刷新
case .background: saveState() // 切后台:保存状态!
default: break
}
}
}
}
// UIKit ViewController 生命周期(老项目)
// viewDidLoad(创建)→ viewWillAppear(即将出现)
// → viewDidAppear → viewWillDisappear → viewDidDisappear
// ≈ Android Activity 的 onCreate → onResume → onPause
【为什么状态保存重要】
切后台 → 系统可能杀进程 → 用户回来 → 要恢复
保存:UserDefaults / 文件 / Core Data(第5站)
恢复:scenePhase 判断 + 读取保存的数据
【前台 vs 后台能力(iOS 严格限制)】
后台任务:有窗口期(几分钟)——长任务用 BGTask
后台音乐/定位:要申请特殊权限(Background Modes)
→ 比 Android 的后台限制更严(苹果省电哲学)
生命周期术语
- Scene 生命周期:Active/Background/Suspended——iOS 13+ 的模型。
- scenePhase:SwiftUI 生命周期环境值——前台/后台判断。
- onAppear / onDisappear:界面出现/消失回调。
- ViewController 生命周期:viewDidLoad 等——UIKit 老代码。
- 状态恢复:被杀后回来——保存 + 读取。
- Background Modes:特殊后台能力(音乐/定位)——要申请。
- 后台窗口期:后台任务有时间限制——比 Android 严。
本站收获:生命周期 = Scene(App 生死)+ onAppear(View 出现)+ scenePhase(前后台判断)。核心心法和 Android 一样:随时准备「被系统杀掉」,所以永远先保存状态。
数据层:网络与存储
URLSession · Codable · Core Data/SwiftData · UserDefaultsiOS 的数据层和 Android 几乎同构:网络(URLSession ≈ Retrofit)、JSON(Codable ≈ Gson)、数据库(Core Data ≈ Room)、偏好(UserDefaults ≈ DataStore)。
数据层四件套:
- URLSession:系统网络库——async/await 直接支持(Retrofit 的 iOS 原生版,够用不引三方)。
- Codable:JSON 编解码协议——struct 声明 + 自动互转(Gson 的 Swift 版,编译期安全)。
- Core Data / SwiftData:本地数据库 ORM——SwiftData 是 2023 新框架(Room 的 iOS 版)。
- UserDefaults:轻量键值存储——设置/偏好(DataStore 的 iOS 版)。
沙箱目录:Documents(用户数据)/ Library(配置/缓存)/ tmp(临时)——数据住哪要守规矩(第 1 站沙箱)。
// ① Codable:JSON 自动互转(Gson 的 Swift 版)
struct Order: Codable, Identifiable {
let id: Int
let title: String
let amount: Double
}
// ② URLSession:网络请求(Retrofit 的 iOS 版)
func fetchOrders() async throws -> [Order] {
let url = URL(string: "https://api.ledger.com/orders")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode([Order].self, from: data)
}
// ③ SwiftData:本地数据库(Room 的 iOS 版)
@Model
final class OrderModel {
var id: Int
var title: String
var amount: Double
}
// ④ UserDefaults:偏好存储(DataStore 的 iOS 版)
UserDefaults.standard.set("paid", forKey: "user_tier")
let tier = UserDefaults.standard.string(forKey: "user_tier")
【Repository 模式(第十六本老朋友)】
网络 + 本地 + 缓存统一入口 → ViewModel 调用
→ 和 Android/后端完全同构!
【沙箱目录规矩】
Documents:用户数据(备份到 iCloud/电脑)
Library/Caches:缓存(系统可清)
Library/Preferences:UserDefaults 存这
tmp:临时文件(用完即删)
【选择建议】
小数据/设置 → UserDefaults
结构化数据 → SwiftData(新)/ Core Data(老)
文件/图片 → 沙箱文件目录 + FileManager
数据层术语
- URLSession:系统网络库——async/await 原生支持。
- Codable:JSON 自动编解码——编译期安全。
- SwiftData / Core Data:本地数据库 ORM——新/老两代。
- UserDefaults:轻量偏好存储。
- 沙箱目录:Documents / Library / tmp——数据住哪的规矩。
- Repository 模式:数据统一入口——全平台同构。
- FileManager:文件读写——沙箱文件操作。
本站收获:数据层 = URLSession 拉网络 + Codable 解 JSON + SwiftData 存本地 + UserDefaults 放偏好 + Repository 统一入口。和 Android/后端/桌面完全同构——换平台只换 API 名,架构不变。
并发:异步方案
GCD · async/await · MainActor · ActoriOS 的异步有两代:老一代 GCD(派发队列),新一代 async/await(Swift 5.5+)——学过 Kotlin 协程/第十八本 async/await 的你,直接「平移」。
三代异步:
- GCD(Grand Central Dispatch):老牌并发库——DispatchQueue.main(主线程)/global(后台)——手动切队列(代码啰嗦)。
- async/await(新):Swift 5.5+ 原生——`async` 函数 + `await` 挂起——写起来像同步(Kotlin 协程/第十八本 C# 完全同思路)。
- MainActor:主线程隔离标注——标记的代码自动在主线程跑,UI 更新安全(Kotlin 的 Main dispatcher)。
进阶:Actor——数据竞争保护(隔离状态的并发安全类型,Kotlin 没有直接对应,比锁更优雅);Task——异步任务单元(结构化并发,第十八本 Task 同款)。
// ✅ 新一代:async/await(推荐)
struct OrderService {
func loadOrders() async throws -> [Order] {
// await 挂起:不阻塞主线程
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode([Order].self, from: data)
}
}
// MainActor:UI 更新自动回主线程
@MainActor
final class OrderViewModel: ObservableObject {
@Published var orders: [Order] = []
func refresh() async {
do {
orders = try await service.loadOrders() // 自动主线程更新
} catch {
errorMessage = "加载失败:\(error.localizedDescription)"
}
}
}
// ❌ 老一代 GCD(维护老代码会看到)
DispatchQueue.global().async {
let data = loadData() // 后台干活
DispatchQueue.main.async { // 手动回主线程
self.orders = data
}
}
// Actor:并发安全的数据类型(无锁竞争)
actor Counter {
private var value = 0
func increment() -> Int { value += 1 }
}
let c = Counter()
let n = await c.increment() // 自动串行访问
【async/await 心法(第十八本同款)】
await 挂起 → 不占线程 → 完成后继续
@MainActor 保证 UI 更新在主线程——告别手动切队列
Task { } 创建异步任务;TaskGroup 并行多个
【对比三平台(你会哪个都不亏)】
Swift async/await ≈ Kotlin 协程 ≈ C# async/await
MainActor ≈ Dispatchers.Main ≈ UI 同步上下文
→ 一套思想,三套语法!
并发术语
- GCD:老牌并发库——DispatchQueue.main/global。
- async/await:Swift 5.5+ 原生异步——挂起不阻塞。
- @MainActor:主线程隔离——UI 更新安全。
- Actor:隔离并发类型——无锁数据竞争保护。
- Task / TaskGroup:异步任务 / 并行任务组。
- @Published:可观察状态——界面自动更新。
- 结构化并发:任务父子管理——自动取消不泄漏。
本站收获:并发 = async/await 挂起 + @MainActor 保主线程 + Actor 防竞争。一套思想三套语法(Kotlin/C#/Swift)——会任何一个,其他都是「换皮」。
架构:MVVM 与依赖
MVVM + Combine · SPM · 协议驱动开发iOS 的架构组织和 Android 一样:MVVM + 响应式 + 依赖管理——唯一区别是「工具名」不同:Combine(响应式)和 SPM(包管理)。
架构四件套:
- MVVM:View(SwiftUI)+ ViewModel(@MainActor 状态)+ Model——第十七本同款架构。
- Combine:响应式框架——@Published + sink 订阅(Flow 的 iOS 版;苹果也在推新的 Swift Observation)。
- SPM(Swift Package Manager):官方包管理——依赖声明 + 自动下载(Maven/NuGet 的 Swift 版)。
- 协议驱动开发:用 protocol 定义依赖接口 → 实现注入——测试换 Mock 方便(DI 的 Swift 哲学)。
// ① 协议:依赖接口(测试可换 Mock)
protocol OrderServicing {
func loadOrders() async throws -> [Order]
}
struct OrderService: OrderServicing { ... } // 真实现
struct MockOrderService: OrderServicing { ... } // 测试用假货
// ② ViewModel:状态 + 逻辑(MVVM)
@MainActor
final class OrderViewModel: ObservableObject {
@Published var orders: [Order] = []
@Published var isLoading = false
private let service: OrderServicing
init(service: OrderServicing) { self.service = service } // 注入
func refresh() async {
isLoading = true
defer { isLoading = false }
orders = (try? await service.loadOrders()) ?? []
}
}
// ③ View:SwiftUI 消费状态(第3站)
struct OrderListView: View {
@StateObject private var vm = OrderViewModel(service: OrderService())
var body: some View { List(vm.orders) { ... } }
}
【SPM 依赖(官方包管理)】
Package.swift 声明依赖:
dependencies: [ .package(url: "https://github.com/...", from: "1.0.0") ]
→ Xcode 自动拉取(Maven/NuGet 同款)
【Combine vs 新 Observation】
Combine:@Published + sink(iOS 13+,成熟)
@Observable:iOS 17+ 新宏——更简洁(新项目可选)
【对比 Android(第十七本)】
MVVM 一模一样
Combine ≈ Flow
SPM ≈ Gradle 依赖
协议注入 ≈ 接口 + Hilt
→ 架构完全同构,换个名字而已
架构术语
- MVVM:View + ViewModel + Model——全平台同款。
- Combine:响应式框架——@Published + sink。
- @Observable:iOS 17+ 新状态宏——更简洁。
- SPM:官方包管理——Package.swift。
- 协议驱动开发:protocol 定义接口——DI 的 Swift 哲学。
- 依赖注入:构造注入——测试换 Mock。
- ObservableObject:可观察对象——界面订阅状态。
本站收获:架构 = MVVM(同款)+ Combine 响应式(≈Flow)+ SPM 管依赖(≈Gradle)+ 协议注入(≈接口 DI)。iOS 架构和 Android 完全同构——你的架构思维直接平移,只换语法。
工程化:Xcode 与上架
Xcode · 证书签名 · TestFlight · App StoreiOS 的工程化门槛比 Android 高:只能在 Mac 的 Xcode 上开发、证书签名体系复杂、上架要过 App Store 审核。这一站,把「苹果的流程」讲透。
工程化五件事:
- Xcode:唯一 IDE——编辑器 + 模拟器 + 可视化设计 + 调试器(只能在 Mac 上)。
- 证书与签名:Development/Release 证书 + Provisioning Profile——苹果的「信任链」(签名错 = 装不上/上不了架)。
- TestFlight:官方内测通道——上传构建 → 邀请测试员 → 真机安装测试(Android 的分发测试平台同款)。
- App Store Connect:上架管理后台——提交构建、填元数据、审核、发布。
- CI/CD:Xcode Cloud / GitHub Actions——自动构建测试上传(第二本老朋友)。
【从源码到 App Store 的完整流程】
① Mac + Xcode 开发(模拟器调试)
② 真机调试:开发者证书 + Provisioning Profile(绑定设备)
③ 测试:XCTest 单元测试 + XCUITest UI 测试(第9站)
④ 打包:Xcode Archive(归档)→ 上传 App Store Connect
⑤ TestFlight 内测:邀请测试员 → 真机试用(必经流程)
⑥ 提交审核:App Store Review → 等 1~3 天
⑦ 发布:通过后上架(可定时发布)
→ 整个流程 3~7 天,审核被拒就打回重来(第10站)
【证书体系(重点,Android 没有这么复杂)】
开发证书:真机调试用(开发者账号 $99/年)
发布证书:上架用(.p12 + 密钥,丢了要撤销重建)
Provisioning Profile:证书 + 设备 + App ID 的「通行证」
→ Xcode 自动管理(Signing & Capabilities 面板)
【TestFlight 好处】
100 名内部测试员 + 1 万外部测试员
真机验证、收集反馈、审核前「排雷」
→ 上架前的必经一步
【CI/CD(自动化)】
Xcode Cloud(官方)/ GitHub Actions + fastlane
fastlane:自动签名/打包/上传/截图——iOS 自动化神器
工程化术语
- Xcode:唯一 IDE——Mac 独占。
- 证书签名:开发/发布证书 + Profile——信任链。
- Archive:归档打包——上架前的构建产物。
- TestFlight:官方内测通道——真机验证必经路。
- App Store Connect:上架管理后台。
- fastlane:iOS 自动化工具——签名/打包/上传一条龙。
- CI/CD:Xcode Cloud / GitHub Actions——自动构建测试。
本站收获:工程化 = Xcode 开发(Mac 独占)+ 证书签名(信任链)+ TestFlight 内测 + App Store 审核发布。iOS 的流程比 Android 重——但「审核严格」也意味着「用户信任度高」。
测试质量:让 App 稳
XCTest · XCUITest · Instruments · 崩溃监控 · 启动优化iOS 的质量保障和 Android 同款配方:单元测试 + UI 测试 + 性能分析 + 崩溃监控——但工具名不同,规矩更严(审核前崩溃 = 直接打回)。
质量四件套:
- XCTest:单元测试框架——测 ViewModel/业务逻辑(JUnit 的 iOS 版)。
- XCUITest:UI 测试——模拟点击/断言界面(Compose Test/Espresso 的 iOS 版)。
- Instruments:性能分析工具——Time Profiler(时间)、Leaks(内存泄漏)、Allocations(内存)——Xcode 内置的「体检仪」。
- 崩溃监控:Crashlytics(Firebase)/ 自建——崩溃上报 + 堆栈定位(Android 同款)。
iOS 特有性能指标:启动时间(冷启动 < 2 秒,审核也关注)、卡顿(掉帧)、内存峰值(iPhone 内存小,OOM 是常态杀手)。
// ① XCTest:单元测试(JUnit 同款)
import XCTest
final class OrderViewModelTests: XCTestCase {
func test_金额格式化() {
let vm = OrderViewModel(service: MockOrderService())
XCTAssertEqual(vm.formatAmount(1299.00), "¥1,299.00")
}
}
// ② XCUITest:UI 测试(点按钮断言界面)
func test_点击刷新_列表更新() throws {
let app = XCUIApplication()
app.launch()
app.buttons["刷新"].tap()
XCTAssertTrue(app.staticTexts["订单 #1"].waitForExistence(timeout: 5))
}
// ③ Instruments:性能体检(Xcode 内置)
// Time Profiler:找出最耗时的函数(cProfile 同款)
// Leaks:内存泄漏检测(LeakCanary 同款)
// Allocations:内存占用分析(OOM 排查)
【崩溃监控(Crashlytics)】
集成 SDK → 崩溃自动上报 → 堆栈 + 设备 + 版本
发布后盯 48 小时:崩溃率 > 0.5% 紧急处理
→ 和 Android 第十七本同款流程
【iOS 特有性能坑】
内存:iPhone 内存紧张——大图/大列表容易 OOM
优化:图片压缩/懒加载/缓存策略
启动:冷启动 < 2 秒——启动任务异步化
卡顿:主线程别干重活(第6站 async 的用武之地)
【发布质量门槛】
XCTest 核心逻辑 100% 覆盖
Instruments 无泄漏告警
TestFlight 测试 3~7 天无崩溃
启动 < 2 秒 / 不掉帧
质量术语
- XCTest:单元测试——JUnit 的 iOS 版。
- XCUITest:UI 测试——点按钮断言界面。
- Instruments:性能分析——Time Profiler/Leaks/Allocations。
- Crashlytics:崩溃监控——上报 + 定位。
- 启动优化:冷启动 < 2 秒——第一印象。
- OOM 风险:iPhone 内存小——大图/列表是杀手。
- 掉帧 / 卡顿:主线程重活——async 解决。
本站收获:质量 = XCTest 单测 + XCUITest UI 测 + Instruments 体检 + Crashlytics 盯崩。iOS 的规矩更严——审核前崩溃会被打回,所以「测试先行」是 iOS 的生存法则。
生态规则:苹果的规矩
App Store 审核 · 隐私标签 · 权限 · IAP · 适配iOS 最独特的不是技术,是「生态规矩」——审核、抽成、隐私、权限。这一站,把苹果的「法律」讲清楚,让你一次过审。
生态规矩五件事:
- App Store 审核:人工 + 自动双重审核——功能完整、无 bug、内容合规;被拒常见理由:崩溃、UI 太丑、隐私问题、功能不符描述。
- 隐私合规(最严):隐私政策 + 隐私标签(声明收集哪些数据)+ 权限说明(Info.plist 里写清用途,比如「需要相机权限用于扫码」)——个保法的苹果版执行(第八本老朋友)。
- 权限弹窗:相机/定位/相册——必须说明用途,用户拒绝要优雅降级(第十七本 Android 同款)。
- IAP(内购):虚拟商品必须走苹果内购,苹果抽成 30%(数字内容);实体商品/线下服务不受限——「苹果税」的由来。
- 机型适配:iPhone SE ~ Pro Max 屏尺寸、灵动岛、深色模式、动态字体——Safe Area + 自适应布局(第十七本适配的 iOS 版)。
【过审 Checklist】
□ App 能跑:无崩溃、无卡死(第9站质量门槛)
□ 功能完整:每个按钮都能用(半成品=拒)
□ 隐私:隐私政策 + 隐私标签 + 权限用途说明
□ 内容合规:无违规内容/无仿冒
□ UI 规范:遵循 Apple 设计规范(HIG)
□ 内购正确:虚拟商品走 IAP(别偷偷用微信/支付宝!)
【权限说明(Info.plist)】
NSCameraUsageDescription: "用于扫描账单二维码"
NSLocationWhenInUseUsageDescription: "用于记账时自动定位"
→ 用途必须真实具体,苹果会抽查!
【隐私标签(隐私营养表)】
声明:收集哪些数据(联系信息/位置/使用数据…)
用途:是否用于追踪/广告
→ 用户下载前就能看到——「诚实是最好策略」
【IAP 规则(苹果税)】
虚拟商品(会员/金币/订阅)→ IAP,抽成 30%
实体商品/线下服务(外卖/打车/实物)→ 不受限
→ 设计付费时先想清楚:数字内容还是实体服务!
【适配要点(第17本 Android 同款思路)】
Safe Area:刘海/灵动岛避让(SafeAreaInsets)
深色模式:颜色语义化(系统自动适配)
动态字体:文本自适应大字体(无障碍)
机型矩阵:SE(小屏)~ Pro Max(大屏)+ 折叠屏
轻记账 iOS 第一版被拒:理由「2.1 崩溃 + 5.1.1 隐私」。整改:① 修复一个空数据崩溃 → ② 补隐私标签(声明收集账单分类)→ ③ 相机权限用途写清楚 → ④ TestFlight 再测 3 天零崩溃 → 重新提交 → 通过。苹果审核像「体检」——把病治好,它就会放行。
生态术语
- App Review:审核——功能完整 + 隐私合规 + 无崩溃。
- 隐私标签:声明收集数据的「营养表」。
- 权限说明(Info.plist):用途必须真实具体。
- IAP(内购):虚拟商品走苹果内购——抽成 30%。
- HIG:Apple 设计规范——UI 合规的参考书。
- Safe Area / 深色模式 / 动态字体:适配三件套。
- 苹果税:内购抽成——数字内容付费的规则。
本站收获:规矩 = 审核过质量关 + 隐私过合规关 + IAP 守商业规则 + 适配覆盖全机型。iOS 的「围墙花园」——门关得严,但里面用户质量高、付费意愿强——规矩是成本也是护城河。
知识点速查 + 面试高频题
面试/上架前最后一页iOS 知识全景表
| 领域 | 核心知识点 | 一句话人话 |
|---|---|---|
| 平台架构 | Darwin、Cocoa Touch、沙箱、App 状态机 | 系统怎么组织 |
| Swift | 可选类型、协议、struct、闭包、async | 现代语言(Kotlin 表兄弟) |
| UI | SwiftUI(声明式)、UIKit、@State、List | 苹果版 Compose |
| 生命周期 | Scene、scenePhase、onAppear、状态恢复 | App 的活法 |
| 数据层 | URLSession、Codable、SwiftData、UserDefaults | 网络 + 本地存储 |
| 并发 | async/await、@MainActor、Actor、GCD | 异步不卡 UI |
| 架构 | MVVM、Combine、SPM、协议驱动 | 和 Android 同构 |
| 工程化 | Xcode、证书签名、TestFlight、App Store | 从源码到上架 |
| 测试质量 | XCTest、XCUITest、Instruments、Crashlytics | 让 App 稳 |
| 生态规则 | 审核、隐私标签、IAP、权限、适配 | 苹果的规矩 |
面试高频题速记
- Swift 和 Kotlin 区别?→ 表兄弟——可选类型/闭包/协议对应,语法略不同。
- SwiftUI 和 UIKit 区别?→ 声明式 vs 命令式——新写 SwiftUI,老读 UIKit。
- @State 和 @StateObject 区别?→ 局部状态 vs 跨界面可观察对象。
- async/await 怎么不卡 UI?→ await 挂起 + @MainActor 回主线程。
- 为什么 iOS App 被系统杀掉?→ 内存紧张杀 Suspended 进程——要保存状态。
- 沙箱是什么?→ App 目录隔离 + 权限受限——比 Android 更严。
- App Store 审核注意什么?→ 无崩溃 + 隐私合规 + 权限用途说明 + IAP 正确。
- 证书/Profile 是什么?→ 信任链——签名错装不上、上不了架。
- 什么是苹果税?→ 虚拟商品走 IAP 抽成 30%——实体服务不受限。
- 如何适配不同 iPhone?→ Safe Area + 自适应布局 + 深色模式 + 动态字体。
技术不难,因为和 Android 同构;
真正的门槛是规矩:审核、隐私、IAP——
守住规矩,苹果的生态就会回馈你。