You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:00:16