This is similar to a question I asked yesterday but the answer I got doesn't seem to work in this case.
I'm getting altitude values in meters from Core Location. I want to display these in a localized form. As an example, the altitude where I am right now is 1839m above sea level. This should be displayed as 6033 feet. The best I can do with MeasurementFormatter
is "1.143 mi".
let meters : Double = 1839
let metersMeasurement = Measurement(value: meters, unit: UnitLength.meters)
let measurementFormatter = MeasurementFormatter()
measurementFormatter.locale = Locale(identifier: "en_US")
let localizedString = measurementFormatter.string(from: metersMeasurement)
The .naturalScale
option that answered my previous question doesn't help here. I think this is a limitation of the framework, but I wonder if anyone has a workaround for now.
Some of the most common are millimeters (mm), centimeters (cm), meters (m), and kilometers (km). So, which measurement units should you use? If something is VERY small (less than one centimeter), it makes the most sense to use the smallest unit, millimeters.
It's very important to choose the correct units to use when making a measurement, so that your measurements make sense and can be easily understood by other people. If you always use the appropriate units, then your measurements will be much easier to understand.
When measuring anything, you need to match the measurement unit to the size of the quantity you are trying to measure. In this lesson, learn about common measurement units for length and mass and how to know which one to use.
When measuring the length of something, you can use several different measurement units. Some of the most common are millimeters (mm), centimeters (cm), meters (m), and kilometers (km).
You just need to convert your UnitLength from meters to feet. You can also create a custom US measurement formatter to display it as needed:
extension Measurement where UnitType == UnitLength {
private static let usFormatted: MeasurementFormatter = {
let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "en_US")
formatter.unitOptions = .providedUnit
formatter.numberFormatter.maximumFractionDigits = 0
formatter.unitStyle = .long
return formatter
}()
var usFormatted: String { Measurement.usFormatted.string(from: self) }
}
Playground
let value: Double = 1839
let meters: Measurement<UnitLength> = .init(value: value, unit: .meters)
let feet = meters.converted(to: .feet)
let formatted = feet.usFormatted
print(formatted) // "6,033 feet"\n
I think you are correct there's no way to specify this kind of context. You could do something like:
extension MeasurementFormatter
{
func altitudeString(from measurement: Measurement<UnitLength>) -> String
{
var measurement = measurement
let unitOptions = self.unitOptions
let unitStyle = self.unitStyle
self.unitOptions = .naturalScale
self.unitStyle = .long
var string = self.string(from: measurement)
if string.contains(self.string(from: UnitLength.miles))
{
self.unitStyle = unitStyle
measurement.convert(to: UnitLength.feet)
self.unitOptions = .providedUnit
string = self.string(from: measurement)
}
else if string.contains(self.string(from: UnitLength.kilometers))
{
self.unitStyle = unitStyle
measurement.convert(to: UnitLength.meters)
self.unitOptions = .providedUnit
string = self.string(from: measurement)
}
else
{
self.unitStyle = unitStyle
string = self.string(from: measurement)
}
self.unitOptions = unitOptions
return string
}
}
Maybe there are other culturally specific ways of measuring elevation, but this would seem better than miles and kilometers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With