# 部门课 07:习惯印章簿与轻量持久化 ## 教学目标 - 区分 `@State` 临时状态和跨 App 启动保留的持久化数据。 - 知道不同形态的数据适合不同保存方式,而不是所有内容都使用同一种工具。 - 理解 `@AppStorage` 适合少量、简单、非敏感的设置或偏好。 - 认识 `@AppStorage` 中存储标识、默认值、当前值和界面 Binding 的关系。 - 认识 SwiftData 中 `@Model`、`ModelContainer`、`ModelContext` 和 `@Query` 的基本职责。 - 区分尚未确认的 `@State` 输入草稿和已经插入 SwiftData 的持久记录。 - 能追踪以下两条数据流: ```text 简单设置 → @AppStorage → App 重启后恢复 ``` ```text 输入备注 → 创建 HabitStamp → ModelContext 插入并保存 → @Query 取得记录 → List 更新 → App 重启后恢复 ``` - 知道 SwiftData 模型具有可供列表区分的持久身份,本节不要求手动建立 UUID。 - 能通过彻底终止并重新启动同一个 App,判断数据是否真正保存。 ## 教学内容 授课干部使用“喝水印章簿基础版”作为课堂 Demo,学员课后完成同源的“我的习惯印章簿”。 Demo 包含: - 一个由 `@AppStorage` 保存的习惯名称; - 一个由 `@State` 保存的印章备注草稿; - `HabitStamp` SwiftData 模型,包含简短备注和创建时间; - 一个盖章按钮; - 使用 `@Query` 展示的印章数量和记录列表; - App 重新启动后的数据恢复。 课堂按以下方向讲解: 1. 先使用临时状态保存习惯名称,重新运行后观察数据消失。 2. 改用 `@AppStorage`,认识存储标识和默认值,再次验证跨启动恢复。 3. 说明单一设置与多条记录的区别,引出 SwiftData。 4. 定义包含备注和创建时间的 `HabitStamp` 模型。 5. 为 App 配置相应的模型存储容器。 6. 从 SwiftUI 环境取得 `ModelContext`,使用 `@Query` 取得已有印章。 7. 使用 `@State` 保存尚未确认的备注草稿。 8. 点击按钮后检查空内容、创建印章、插入 context,并清空草稿。 9. 观察 `@Query` 和 `List` 如何随新记录更新。 10. 彻底结束并重新启动同一个 App,确认习惯名称和多条印章记录均被恢复。 本节采用授课干部 Demo 讲解型: - 授课干部提前完成基础版并通过 Build/Run。 - 课堂实际敲写和解释关键数据链路。 - 保留完成版作为现场演示失败时的备用。 - 学员主要观察、预测、追踪数据和讨论,不要求同步跟抄。 - 学员课后参考 Demo、步骤资料或 AI 完成同源作品。 共同内容只使用 SwiftData 的新增和读取能力,不扩展为完整 CRUD。本节不讲: - 编辑、删除、撤销和复杂表单; - 查询筛选、排序原理和关系模型; - 多个习惯、每日唯一打卡、连续天数和漏签判断; - 提醒通知、日历、统计图和云同步; - Schema 迁移、数据库底层原理和架构分层; - 直接操作 `UserDefaults`、Codable 文件或 Keychain; - 敏感信息保存。 `@AppStorage` 基于 `UserDefaults`,适合简单的非敏感设置;SwiftData 通过模型、容器、上下文和查询管理结构化记录。后续细化备课时可参考 Apple 的 [AppStorage](https://developer.apple.com/documentation/swiftui/appstorage)、[UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults) 和 [SwiftData 跨启动保存](https://developer.apple.com/documentation/swiftdata/preserving-your-apps-model-data-across-launches)。 ## 课后作业 作业方向为“我的习惯印章簿”。具体题目、项目目录、分支、Commit、PR 标题和提交期限以后写入独立的课后作业文档。 ### 最低完成标准 - 项目能够 Build/Run。 - 选择一个轻松、非敏感的习惯主题。 - 使用 `@AppStorage` 保存习惯名称,并提供合理默认值。 - 定义包含简短备注和创建时间的 SwiftData 印章模型。 - 正确配置模型容器,并使用 `ModelContext` 插入记录。 - 使用 `@State` 保存尚未提交的备注草稿。 - 空备注不能生成印章。 - 成功盖章后清空输入框。 - 使用 `@Query` 读取记录,并显示印章数量和记录列表。 - 能在一次运行中连续加入多枚印章。 - 彻底结束并重新启动 App 后,习惯名称和已有印章仍然存在。 - 至少完成一处主题文字、图标或配色修改。 达到最低标准即可视为完成,不要求视觉精致度、额外模型或完整数据管理功能。 ### 建议完成标准 鼓励选择一项或多项探索: - 增加空印章簿提示。 - 调整日期的显示形式。 - 让最新印章优先显示。 - 自定义印章图标、颜色或卡片样式。 - 增加第二个由 `@AppStorage` 保存的简单偏好。 - 尝试删除单条印章或清空全部印章,并考虑是否需要确认。 - 使用 AI 解释局部代码、排查错误或完成一处小改造,再自行运行验证。 建议内容不影响基础作业通过,不要求发展成完整习惯管理 App。 ## 验收方式 - 学员通过个人 Fork 和本周作业分支,向部门公开仓库提交完整项目源码 PR。 - 本节需要证明跨启动恢复,可通过约定渠道发送简短运行视频,展示修改习惯名称、添加印章、彻底结束 App、重新启动后数据仍然存在。 - 授课干部也可以取得 PR 源码,在自己的模拟器中完成同样验证。 - 下节课可选择少量作品轻量复习,可以现场运行,也可以围绕以下问题交流: - 哪个值由 `@AppStorage` 保存; - 哪些内容仍然只是 `@State`; - `@Model`、容器、context 和 query 分别承担什么作用; - 为什么重新启动后记录仍然存在。 - 回答不完整用于发现共同问题和安排复习,不用于排名或淘汰。 - 未完成时允许提交 Draft PR,说明当前状态、完整错误和已经尝试的步骤。 验收只判断最低完成标准。建议完成内容不影响基础作业通过,课纲不规定视频编码、文件格式、大小、完整命令或其他操作细节。 源码提交、工具故障时的参与记录和隐私边界按[共同安排](../iOS部2026十课初步规划.md)执行;具体材料与操作细节由授课干部在备课阶段准备。