Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 案例:扩展 Todo 应用支持离线存储

案例:扩展 Todo 应用支持离线存储

目标

通过集成 Core Data 为现有的 Todo 应用添加离线存储功能,确保数据在应用关闭后仍能持久化,并支持跨设备同步(需结合 iCloud 或其他同步方案)。


实现步骤

1. 配置 Core Data 环境

1.1 创建 Core Data 模型文件

  • 在 Xcode 中新建 Data Model 文件(如 TodoModel.xcdatamodeld)。
  • 定义 TodoItem 实体,包含以下属性:
    • id: UUID(唯一标识)
    • title: String
    • isCompleted: Bool
    • createdAt: Date

1.2 生成 NSManagedObject 子类

@objc(TodoItem)
public class TodoItem: NSManagedObject, Identifiable {
    @NSManaged public var id: UUID
    @NSManaged public var title: String
    @NSManaged public var isCompleted: Bool
    @NSManaged public var createdAt: Date
}

2. 重构 Model 层

2.1 将内存模型迁移至 Core Data

  • 移除原有的 Todo 结构体,改用 TodoItem 实体。
  • 创建 DataController 类管理 Core Data 上下文:
class DataController: ObservableObject {
    let container = NSPersistentContainer(name: "TodoModel")
    
    init() {
        container.loadPersistentStores { _, error in
            if let error = error {
                fatalError("Failed to load Core Data: \(error)")
            }
        }
    }
}

3. 修改 ViewModel 层

3.1 适配 Core Data 操作

  • 在 TodoViewModel 中注入 DataController:
class TodoViewModel: ObservableObject {
    private let dataController: DataController
    @Published var todos: [TodoItem] = []
    
    init(dataController: DataController) {
        self.dataController = dataController
        fetchTodos()
    }
    
    func fetchTodos() {
        let request: NSFetchRequest<TodoItem> = TodoItem.fetchRequest()
        request.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
        todos = (try? dataController.container.viewContext.fetch(request)) ?? []
    }
    
    func addTodo(title: String) {
        let newTodo = TodoItem(context: dataController.container.viewContext)
        newTodo.id = UUID()
        newTodo.title = title
        newTodo.isCompleted = false
        newTodo.createdAt = Date()
        saveContext()
    }
    
    private func saveContext() {
        do {
            try dataController.container.viewContext.save()
            fetchTodos() // 刷新数据
        } catch {
            print("保存失败: \(error)")
        }
    }
}

4. 更新 View 层

4.1 绑定 Core Data 数据源

  • 修改 TodoListView 以响应 @FetchRequest 或 ViewModel 的 @Published 数据:
struct TodoListView: View {
    @EnvironmentObject var viewModel: TodoViewModel
    
    var body: some View {
        List {
            ForEach(viewModel.todos) { todo in
                TodoRow(todo: todo)
            }
            .onDelete(perform: deleteTodo)
        }
    }
    
    private func deleteTodo(at offsets: IndexSet) {
        offsets.forEach { index in
            let todo = viewModel.todos[index]
            viewModel.dataController.container.viewContext.delete(todo)
        }
        viewModel.saveContext()
    }
}

5. 添加 iCloud 同步(可选)

5.1 启用 iCloud 能力

  • 在项目配置中勾选 iCloud 并添加 CloudKit 容器。
  • 修改 NSPersistentContainer 初始化:
container = NSPersistentCloudKitContainer(name: "TodoModel")
container.viewContext.automaticallyMergesChangesFromParent = true

关键注意事项

  1. 线程安全:确保 Core Data 操作在正确的上下文中执行(如 viewContext 主线程)。
  2. 错误处理:对保存失败等场景提供用户反馈。
  3. 数据迁移:若后续修改模型,需设计轻量级迁移方案。

最终效果

  • Todo 数据在应用重启后仍然保留。
  • 支持多设备同步(若启用 iCloud)。
  • 完整代码示例见 GitHub 仓库链接。
Last Updated:: 4/25/25, 8:30 PM