第11章:离线支持与同步策略
处理网络连接变化与数据同步
网络状态监测基础
使用
Network框架检测连接状态import Network let monitor = NWPathMonitor() monitor.pathUpdateHandler = { path in if path.status == .satisfied { // 网络可用,触发同步逻辑 } else { // 进入离线模式 } } monitor.start(queue: DispatchQueue.global())SwiftUI中的状态绑定
通过@State或EnvironmentObject传递网络状态:@StateObject private var networkMonitor = NetworkMonitor()
数据同步策略设计
| 策略类型 | 适用场景 | 实现要点 |
|---|---|---|
| 立即同步 | 实时性要求高的应用(如聊天) | 使用Combine的Debounce避免频繁请求 |
| 批量同步 | 资源受限场景 | 本地缓存修改记录,定时批量提交 |
| 手动同步 | 用户控制型应用 | 提供显式同步按钮和进度反馈 |
冲突解决机制
时间戳优先
为每个模型添加lastModified字段:@Model class Note { var lastModified: Date //... }版本向量(Vector Clocks)
适用于多设备同步场景:struct VersionVector: Codable { var deviceID: UUID var counter: Int }
代码实现示例
// 同步管理器协议
protocol SyncManager {
func syncPendingChanges() async throws
func resolveConflict(local: Note, remote: Note) -> Note
}
// 具体实现
class CloudKitSyncManager: SyncManager {
private let context: ModelContext
init(context: ModelContext) {
self.context = context
}
func syncPendingChanges() async throws {
guard NetworkMonitor.shared.isConnected else { return }
let unsyncedNotes = try context.fetch(
FetchDescriptor<Note>(
predicate: #Predicate { $0.isSynced == false }
)
)
for note in unsyncedNotes {
try await uploadToCloudKit(note)
note.isSynced = true
}
try context.save()
}
}
用户体验优化
视觉反馈
- 在工具栏显示同步状态图标(云朵+箭头)
- 使用
ProgressView显示同步进度
错误恢复
.alert("同步失败", isPresented: $showSyncError) { Button("重试") { retrySync() } Button("稍后", role: .cancel) {} } message: { Text("最后同步失败:\(lastError?.localizedDescription ?? "")") }
调试技巧
模拟网络延迟
在Xcode Scheme中添加环境变量:-com.apple.CoreData.ConcurrencyDebug 1 -com.apple.CoreData.SQLDebug 3强制触发离线模式
使用Network Link Conditioner工具模拟差网络环境
最佳实践:始终在本地保留完整的操作日志,使用
Operation队列管理同步任务,确保操作的可重试性和幂等性。
