Reputation: 551
When I run the following code in a Playground the formatted string comes back as nil. What am I missing in the derived custom Measurement 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
Output:
12.31 stph
12.31 in
nil
Optional("0 mi")
Upvotes: 1
Views: 1063
Reputation: 2614
You need to update a few things in your code.
Firstly, you are using the string
method on Formatter
which takes Any?
and returns an optional String
. If you change the parameter name to from
, you will use the method defined on MeasurementFormatter
which returns a non-optional:
var measureStringCustom = formatter.string(from: measureCustom)
Secondly, you are using a MeasurementFormatter
which has the unitOptions
property set to .naturalScale
(the default). If you change this to, .providedUnit
, you'll see that you now get some output. The problem is that .naturalScale
will use the appropriate unit for the given locale and there is currently no way to set what that is for custom Dimension
subclasses.
So, the way to achieve what you what is to use the converted
method along with a .providedUnit
formatter, like so:
let converted = measureCustom.converted(to: .metricTonsPerHour)
var formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
print(formatter.string(from: converted))
Finally, you are probably still not getting the output you expect. This is because the coefficient
for the UnitConverterLinear
which is returned by baseUnit
should be 1
. I expect you intended to define your dimension as follows (notice the scaled-down coefficients):
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))
}
Upvotes: 2