I was trying to write a function that returns a localized string for a weight measurement - but with the option of skipping the unit substring. As in: return "100,1" instead of "100,1kg" but respecting the user's locale.
First thought was: just specify unitStyle = .none but that is not a valid member.
So I came up with this solution which works for pounds and kilos but there sure are other weight / mass units out there... How do I retrieve the user's preferred unit from locale?
First thought was: just specify unitStyle = .none but that is not a valid member.
So I came up with this solution which works for pounds and kilos but there sure are other weight / mass units out there... How do I retrieve the user's preferred unit from locale?
Code Block func formatWeight(weightInKgs value: Double, skipUnit: Bool = false) -> String { let weightInKgs = Measurement(value: value, unit: UnitMass.kilograms) if !skipUnit { let formatter = MeasurementFormatter() // if skipUnit { // formatter.unitStyle = .none // } else { formatter.unitStyle = .short // } formatter.numberFormatter.maximumFractionDigits = 1 formatter.numberFormatter.minimumFractionDigits = 1 return formatter.string(from: weightInKgs) } else { if Locale.current.usesMetricSystem { let formatter = NumberFormatter() formatter.maximumFractionDigits = 1 formatter.minimumFractionDigits = 1 return formatter.string(from: NSNumber(value: weightInKgs.value))! } else { let weightInLocaleUnit = weightInKgs.converted(to: UnitMass.pounds) //this is not universal let formatter = NumberFormatter() formatter.maximumFractionDigits = 1 formatter.minimumFractionDigits = 1 return formatter.string(from: NSNumber(value: weightInLocaleUnit.value))! } } }
As far as I checked the documentations of Apple, I could not find any APIs to get preferred weight unit.How do I retrieve the user's preferred unit from locale?
There are only three countries where the metric system is not used: the US, Liberia and Myanmar.there sure are other weight / mass units out there
Testing with macOS 11.1 and iOS 14.4 Simulator, only one region "US" uses pounds.
Code Block extension Locale { var measurementSystem: String { (self as NSLocale).object(forKey: NSLocale.Key.measurementSystem) as! String } } func formatWeight(for locale: Locale, weightInKgs: Double) -> String { let mformatter = MeasurementFormatter() mformatter.locale = locale mformatter.unitOptions = .naturalScale mformatter.unitStyle = .medium let weight = Measurement(value: weightInKgs, unit: UnitMass.kilograms) return mformatter.string(from: weight) } let localeIds = ["en_US", "es_US", "en_GB", "en_LR", "my_MM", "ja_JP"] for localId in localeIds { let locale = Locale(identifier: localId) print(locale, locale.measurementSystem) print(locale.regionCode ?? "*region unknown*") print("Uses Metric System: \(locale.usesMetricSystem)") print(formatWeight(for: locale, weightInKgs: 100.1)) }
Output:
Code Block en_US (fixed) U.S. US Uses Metric System: false 220.683 lb es_US (fixed) U.S. US Uses Metric System: false 220.683 lb en_GB (fixed) U.K. GB Uses Metric System: true 100.1 kg en_LR (fixed) U.S. LR Uses Metric System: false 100.1 kg my_MM (fixed) U.S. MM Uses Metric System: false ၁၀၀.၁ kg ja_JP (fixed) Metric JP Uses Metric System: true 100.1 kg
(I'm not sure if kg is really preferred in daily life in the UK, but macOS/iOS uses kg for weight/mass when Locale set to en_GB.)
Seems using UnitMass.pounds is universal enough, practically.