MeasurementFormatter caching too much?

The following code (in a playground) or even if in a project will ultimately fail to work.


let theFormatter = MeasurementFormatter()
theFormatter.locale = Locale(identifier: "en_US")
theFormatter.unitStyle = .medium
theFormatter.numberFormatter.maximumFractionDigits = 2
let theSpeed = Measurement(value: 30, unit: UnitSpeed.milesPerHour)
theFormatter.string(from: theSpeed)
theFormatter.numberFormatter.maximumFractionDigits = 3
theFormatter.string(from: theSpeed)


Basically, it appears that once you have an instance of MeasurementFormatter, and set 'maximumFractionDigits' on its internal number formatter, that setting will be used for all future formatting. Executing the above once may work, but adjusting the values of fraction digits thereafter doesn't change any output.


i.e. attempting to set 'maximumFractionDigits' to something else later is ultimately ignored. It's as if the formatter is lazily building its number formatter and keeping the original instance as-is.


Workaround is to assign a brand new number formatter instance. As my apps only use three different values for fraction digits (0, 1 and 2), I plan on just holding on to three pre-built formatters and assigning them to the measurement formatter as needed.

Replies

I think it's worth a bug report.


I completed a bit the test, to check that maximumFractionDigits is effectively changed, but not taken into account.

I checked with a second string, same issue.


let theFormatter = MeasurementFormatter()
theFormatter.locale = Locale(identifier: "en_US")
theFormatter.unitStyle = .medium
theFormatter.numberFormatter.maximumFractionDigits = 4
print("formatter", theFormatter.numberFormatter.maximumFractionDigits)
let theSpeed = Measurement(value: 30.2222, unit: UnitSpeed.milesPerHour)
print(theFormatter.string(from: theSpeed))
theFormatter.numberFormatter.maximumFractionDigits = 3
print("formatter", theFormatter.numberFormatter.maximumFractionDigits)
let theSpeed2 = Measurement(value: 30.3333, unit: UnitSpeed.milesPerHour)
print(theFormatter.string(from: theSpeed2))


Gets

formatter 4

30.2222 mph

formatter 3

30.3333 mph


The problem does not exist with other formatter properties as alwaysShowsDecimalSeparator which works OK

let theFormatter = MeasurementFormatter()
theFormatter.locale = Locale(identifier: "en_US")
theFormatter.unitStyle = .medium
theFormatter.numberFormatter.alwaysShowsDecimalSeparator = false
let theSpeed = Measurement(value: 302222, unit: UnitSpeed.milesPerHour)
print(theFormatter.string(from: theSpeed))
theFormatter.numberFormatter.alwaysShowsDecimalSeparator = true
let theSpeed2 = Measurement(value: 303333, unit: UnitSpeed.milesPerHour)
print(theFormatter.string(from: theSpeed2))


Gets

302,222 mph

303,333. mph