设计离线同步系统
问题
如何设计 iOS 端的离线同步系统?
答案
架构
离线队列
struct OfflineOperation: Codable {
let id: UUID
let type: String // "create", "update", "delete"
let endpoint: String
let payload: Data
let createdAt: Date
var retryCount: Int = 0
}
class OfflineQueue {
private let store: UserDefaults // 简单场景用 UserDefaults,复杂用 Core Data
// 入队
func enqueue(_ operation: OfflineOperation) {
var queue = loadQueue()
queue.append(operation)
save(queue)
}
// 网络恢复后按顺序同步
func syncAll() async {
var queue = loadQueue()
var failedOps: [OfflineOperation] = []
for var op in queue {
do {
try await API.execute(endpoint: op.endpoint, payload: op.payload)
} catch {
op.retryCount += 1
if op.retryCount < 3 {
failedOps.append(op)
}
// 超过 3 次标记为失败
}
}
save(failedOps)
}
}
冲突解决策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| Last Write Wins | 最后写入覆盖 | 简单配置 |
| Server Wins | 始终以服务端为准 | 敏感数据 |
| Client Wins | 始终以本地为准 | 草稿 |
| Merge | 字段级合并 | 文档协作 |
| Manual | 提示用户选择 | 冲突不可自动解决 |
网络状态监听
import Network
class NetworkMonitor {
private let monitor = NWPathMonitor()
func start(onRestore: @escaping () -> Void) {
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
onRestore() // 触发离线队列同步
}
}
monitor.start(queue: DispatchQueue.global())
}
}
常见面试问题
Q1: 离线操作顺序很重要吗?
答案:非常重要。比如「创建订单 → 修改订单」,如果乱序同步会导致修改失败(订单还不存在)。离线队列必须 FIFO,遇到依赖关系的操作应阻塞后续执行。