如何在Xcode Swift中按邮箱登录永久保存用户独立输入数据
分邮箱用户独立存储数据的解决方案
你当前的问题根源是所有用户的数据都存在同一个UserDefaults键名(currentGraphTableDataSix)下,导致切换邮箱后会读取到其他用户的历史数据。解决核心是给每个用户分配独立的存储键,用当前登录用户的邮箱作为键的唯一标识。
具体实现步骤
1. 维护当前登录用户的邮箱
先在代码中保留一个当前登录用户的邮箱变量(实际开发中,这个值要从你的登录逻辑里获取,比如登录成功后赋值):
var currentUserEmail: String?
2. 修改存储/读取逻辑,加入用户邮箱作为键的一部分
把原来固定的键名,改成"currentGraphTableDataSix_用户邮箱"的形式,确保每个用户的存储键唯一。
修改后的按钮点击方法:
@IBAction func savebtn(_ sender: Any) { // 先检查当前是否有登录用户的邮箱 guard let userEmail = currentUserEmail, !userEmail.isEmpty else { // 未登录时的处理,比如提示用户先登录 return } let data = GraphDataIngo6(date: lblfirst.text ?? "", target: lblsecond.text ?? "", amount: lblAmount.text ?? "") let newData = SVGraphInfoTable6() newData.date = lblfirst.text ?? "" newData.target = lblsecond.text ?? "" newData.amount = lblAmount.text ?? "" // 读取当前用户的历史数据 var oldArray = getCurrentTableData(forUser: userEmail) oldArray.append(newData) // 保存当前用户的数据 self.saveCurrentTableData(dic: oldArray, forUser: userEmail) delegate?.onGraphReady(dataGraph: data) self.navigationController?.popViewController(animated: true) }
修改后的读取/保存核心函数:
// 根据用户邮箱读取对应的数据 func getCurrentTableData(forUser email: String) -> [SVGraphInfoTable6] { let uniqueKey = "currentGraphTableDataSix_\(email)" guard let data = UserDefaults.standard.data(forKey: uniqueKey) else { return [] } // 使用更安全的归档方式(iOS 12+支持) guard let userDataArray = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [SVGraphInfoTable6] else { return [] } return userDataArray } // 保存数据到当前用户的专属键下 func saveCurrentTableData(dic: [SVGraphInfoTable6], forUser email: String) { let uniqueKey = "currentGraphTableDataSix_\(email)" guard let archivedData = try? NSKeyedArchiver.archivedData(withRootObject: dic, requiringSecureCoding: false) else { return } UserDefaults.standard.set(archivedData, forKey: uniqueKey) UserDefaults.standard.synchronize() }
3. 确保SVGraphInfoTable6遵守NSCoding协议
因为你用了归档/解归档,这个类必须实现NSCoding的两个方法,否则会操作失败:
class SVGraphInfoTable6: NSObject, NSCoding { var date: String = "" var target: String = "" var amount: String = "" override init() { super.init() } // 解归档方法:从编码中恢复数据 required init?(coder: NSCoder) { date = coder.decodeObject(forKey: "date") as? String ?? "" target = coder.decodeObject(forKey: "target") as? String ?? "" amount = coder.decodeObject(forKey: "amount") as? String ?? "" } // 归档方法:把数据编码保存 func encode(with coder: NSCoder) { coder.encode(date, forKey: "date") coder.encode(target, forKey: "target") coder.encode(amount, forKey: "amount") } }
额外注意事项
- 登出处理:用户登出时,记得把
currentUserEmail置为nil,避免后续操作错误使用旧用户的键。 - 旧数据迁移(可选):如果之前已经存储了不分用户的旧数据,可以写个迁移逻辑,把旧键下的数据转移到当前登录用户的新键下,然后删除旧键的数据。
内容的提问来源于stack exchange,提问作者Guintolli
相关产品推荐
相关产品推荐

