将 MeasurementFormatter 与派生单位一起使用

Using MeasurementFormatter with Derived unit

当我在 Playground 中 运行 以下代码时,格式化字符串返回为 nil。我在派生的自定义测量 class 中缺少什么?

open class UnitFlowRate : Dimension {
    open override static func baseUnit() -> UnitFlowRate {  return self.metricTonsPerHour }

    static let shortTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("stph", comment: "short tons per hour"), converter: UnitConverterLinear(coefficient: 1))
    static let metricTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("mtph", comment: "metric tons per hour"), converter: UnitConverterLinear(coefficient: 2))
}

var measureCustom = Measurement<UnitFlowRate>(value: 12.31, unit: .shortTonsPerHour)
var measureSystem = Measurement<UnitLength>(value: 12.31, unit: .inches)

var formatter = MeasurementFormatter()
var measureStringCustom = formatter.string(for: measureCustom)
var measureStringSystem = formatter.string(for: measureSystem)
print( measureCustom ) // This works
print( measureSystem ) // This works
print( measureStringCustom ) // This is nil - Why?
print( measureStringSystem ) // This works

输出:

12.31 stph
12.31 in
nil
Optional("0 mi")

您需要更新代码中的一些内容。

首先,您在 Formatter 上使用 string 方法,它采用 Any? 和 returns 一个可选的 String。如果将参数名称更改为 from,您将使用在 MeasurementFormatter 上定义的方法,其中 returns 是一个非可选的:

var measureStringCustom = formatter.string(from: measureCustom)

其次,您使用的 MeasurementFormatterunitOptions 属性 设置为 .naturalScale(默认值)。如果将其更改为 .providedUnit,您将看到现在获得了一些输出。问题是 .naturalScale 将为给定的语言环境使用适当的单位,目前无法设置自定义 Dimension 子类的单位。

所以,实现你的目标的方法是使用 converted 方法和 .providedUnit 格式化程序,如下所示:

let converted = measureCustom.converted(to: .metricTonsPerHour)
var formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
print(formatter.string(from: converted))

最后,您可能仍然没有得到预期的输出。这是因为 baseUnit 返回的 UnitConverterLinearcoefficient 应该是 1。我希望您打算按如下方式定义维度(注意按比例缩小的系数):

open class UnitFlowRate : Dimension {
  open override static func baseUnit() -> UnitFlowRate {  return self.metricTonsPerHour }
  static let shortTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("stph", comment: "short tons per hour"), converter: UnitConverterLinear(coefficient: 0.5))
  static let metricTonsPerHour = UnitFlowRate(symbol: NSLocalizedString("mtph", comment: "metric tons per hour"), converter: UnitConverterLinear(coefficient: 1))
}