SwiftUI中如何持久化存储用户添加的列表项
基于现有代码实现本地持久化方案
你现在的代码结构完全可以直接改造实现本地持久化,不需要重构现有逻辑。针对你当前仅存储植物名称条目的轻量场景,用UserDefaults做持久化是学习成本最低的选择,改造成本很小,按下面步骤改就行:
- 首先让你的
Item数据模型支持序列化
本地存储需要把模型转成可存储的二进制数据,只要给Item结构体加上Codable协议即可,原有属性不需要改动:// 原有Item模型只要补Codable协议 struct Item: Identifiable, Codable { let id = UUID() let title: String } - 新增存、读数据的两个基础方法
直接在HomePage结构体里加两个私有方法,分别负责把列表数据写入本地、和从本地读取已存的列表数据:// 保存当前列表到本地 private func saveItems() { do { let encodedData = try JSONEncoder().encode(items) UserDefaults.standard.set(encodedData, forKey: "mySavedPlants") } catch { print("保存失败: \(error.localizedDescription)") } } // 启动时读取本地已存的列表 private func loadItems() { guard let savedData = UserDefaults.standard.data(forKey: "mySavedPlants") else { return } do { items = try JSONDecoder().decode([Item].self, from: savedData) } catch { print("读取失败: \(error.localizedDescription)") } } - 在现有逻辑里挂载触发时机
- 页面第一次加载时读取本地数据,给
NavigationView加上onAppear修饰符:.onAppear(perform: loadItems) - 只要列表发生变动(新增、删除、排序、插入)就自动触发保存,不需要在每个操作里单独写保存逻辑,直接给
items状态变量加属性观察者即可,把原来的@State private var items: [Item] = []替换成:@State private var items: [Item] = [] { didSet { saveItems() } }
- 页面第一次加载时读取本地数据,给
小提示:你当前
onAdd方法里用单独的@State变量plantName2中转输入文本的写法有点冗余,后续可以直接在弹窗的回调里把文本传给appendItem方法,能减少状态同步出问题的概率,不过这个不影响持久化功能的正常运行,你可以后续慢慢调整。等你后续需要存储更复杂的数据(比如植物照片、浇水记录、养护提醒这类内容),再考虑换用SwiftData或者Core Data方案即可,当前的方案完全能满足你现在的功能需求。
内容的提问来源于stack exchange,提问作者carogna
相关产品推荐
相关产品推荐

