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

如何将CoreData存储的UnitType字符串转为Swift Measurement可用的Unit类型?

解决字符串转Unit类型的问题

你之前的错误在于使用UnitLength(symbol:)初始化单位——这个方法接收的是单位的符号(比如"cm"),而不是你存储的"UnitLength.centimeters"这种类型成员的标识字符串,因此创建的单位实例无效,格式化时出现错误结果。

下面提供两种可行的解决方案:

方案一:字典映射(推荐,性能更优)

提前创建一个字符串到对应Unit实例的映射字典,直接通过存储的字符串查找对应的单位,这种方式高效且可控:

// 提前定义所有需要支持的单位映射
let unitMapping: [String: Unit] = [
    "UnitLength.centimeters": UnitLength.centimeters,
    "UnitLength.inches": UnitLength.inches,
    "UnitLength.feet": UnitLength.feet,
    "UnitLength.meters": UnitLength.meters,
    "UnitMass.kilograms": UnitMass.kilograms,
    "UnitMass.pounds": UnitMass.pounds,
    // 根据业务需求添加更多单位
]

// 使用示例
let personHeight = 190.0
let personHeightUnit = "UnitLength.centimeters"

if let unit = unitMapping[personHeightUnit] as? UnitLength {
    let height = Measurement(value: personHeight, unit: unit)
    let formattedText = height.formatted(
        .measurement(width: .abbreviated, usage: .personHeight)
        .locale(Locale(identifier: "en-US"))
    )
    Text("Height = \(formattedText)") // 输出预期结果:Height = 6 ft, 2.8 in
}

方案二:反射自动匹配

通过Swift的反射机制,解析字符串中的类型和成员名,自动获取对应的Unit实例,无需手动维护字典,适合单位类型较多且频繁新增的场景:

func convertToUnit(from unitString: String) -> Unit? {
    // 拆分字符串为类型名和单位成员名
    let components = unitString.components(separatedBy: ".")
    guard components.count == 2 else { return nil }
    let typeName = components[0]
    let unitMemberName = components[1]
    
    // 匹配对应的Unit类型
    guard let unitType: Any.Type = {
        switch typeName {
        case "UnitLength": return UnitLength.self
        case "UnitMass": return UnitMass.self
        case "UnitTemperature": return UnitTemperature.self
        // 添加其他需要支持的Unit类型
        default: return nil
        }
    }() else {
        return nil
    }
    
    // 反射遍历静态属性,找到匹配的单位实例
    let mirror = Mirror(reflecting: unitType)
    for child in mirror.children {
        if child.label == unitMemberName, let unit = child.value as? Unit {
            return unit
        }
    }
    return nil
}

// 使用示例
let personHeight = 190.0
let personHeightUnit = "UnitLength.centimeters"

if let unit = convertToUnit(from: personHeightUnit) as? UnitLength {
    let height = Measurement(value: personHeight, unit: unit)
    let formattedText = height.formatted(
        .measurement(width: .abbreviated, usage: .personHeight)
        .locale(Locale(identifier: "en-US"))
    )
    Text("Height = \(formattedText)") // 输出预期结果:Height = 6 ft, 2.8 in
}

内容的提问来源于stack exchange,提问作者Peel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:23:13