I need to get the internationalized value of a Measurement.
let speed = Measurement(value: 15, unit: UnitSpeed.kilometersPerHour)
let formatter = MeasurementFormatter()
formatter.string(from: speed) // is "9.32 mph"
speed.converted(to: .milesPerHour).value // this is what I want, but I have to hardcode the unit I am converting to
Can I get the value (9.32
) without manually splitting strings and casting it? For temperatures you can use formatter.unitOptions = .temperatureWithoutUnit
but this will stop the conversion and I would still end up with a string.
Is there anything like speed.converted(to: default).value
to get the value of the localized Measurement?
What I think you are after is the measurement system for the locale. The Mac currently understands three systems: metric, US and UK. The UK uses metric for lengths and weights but still uses miles/mph for road distances and speeds, hence the third option here – the usesMetricSystem
property only supports two options and returns true
for the UK.
To get the measurement system in Swift requires using NSLocale
, this extension will add it to Locale
:
extension Locale
{
var measurementSystem : String?
{
return (self as NSLocale).object(forKey: NSLocale.Key.measurementSystem) as? String
}
}
For added "fun" Apple doesn't actually specify the values of this property, they give examples but not a full definition. You can get the known three values querying the property on three locales known to use them, e.g. you could add the following to the extension:
static let metricMeasurementSystem = Locale(identifier: "fr_FR").measurementSystem!
static let usMeasurementSystem = Locale(identifier: "en_US").measurementSystem!
static let ukMeasurementSystem = Locale(identifier: "en_UK").measurementSystem!
Of course if Swift did support them it would probably define an enum
for the possibilities, you could do that as well.
HTH
BTW: For those who think the UK is being awkward, the "US" system is only used in three countries: US, Myanmar and Liberia.