Choosing units with MeasurementFormatter

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.


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