SwiftUI单位转换应用中如何存储Dimension并实现持久化?
存储SwiftUI中Dimension类型数据的持久化方案
针对你需要存储UnitMass.kilograms这类Dimension实例的需求,可以通过以下两种简洁方式实现持久化:
方法一:手动使用UserDefaults(基础版)
存储数据
当用户切换单位时,将选中单位的唯一字符串标识identifier存入UserDefaults:
// 假设inUnit是当前选中的Dimension实例 UserDefaults.standard.set(inUnit.identifier, forKey: "selectedInputUnit")
读取数据
在视图初始化或App启动时,从UserDefaults读取标识并还原对应的Unit实例:
@State private var inUnit: Dimension = { if let savedIdentifier = UserDefaults.standard.string(forKey: "selectedInputUnit"), let savedUnit = UnitMass.unit(withIdentifier: savedIdentifier) as? Dimension { return savedUnit } // 未找到存储数据时使用默认值 return UnitMass.kilograms }()
方法二:扩展@AppStorage支持Dimension(便捷版)
通过让Dimension遵循RawRepresentable协议,就能直接用@AppStorage自动处理持久化,无需手动操作UserDefaults:
extension Dimension: RawRepresentable { public typealias RawValue = String public init?(rawValue: RawValue) { // 仅针对质量单位的实现,若需支持长度、温度等其他类型,可添加对应Unit子类的判断逻辑 if let massUnit = UnitMass.unit(withIdentifier: rawValue) as? Self { self = massUnit } else { return nil } } public var rawValue: RawValue { identifier } }
之后直接用@AppStorage替代@State即可:
@AppStorage("selectedInputUnit") private var inUnit: Dimension = UnitMass.kilograms
注意事项
- 如果应用需要支持多种类型的Dimension,可在
init?(rawValue:)中扩展判断逻辑,依次尝试不同Unit子类的unit(withIdentifier:)方法。 identifier是每个Unit实例的唯一标识,不会重复,适合作为存储的键值。
内容的提问来源于stack exchange,提问作者JasonK
相关产品推荐
相关产品推荐

