Last active
March 12, 2020 04:01
-
-
Save ole/8f38c29746fefa21bb9e53aee21c36ef to your computer and use it in GitHub Desktop.
Paste into a playground.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// Playing around with MeasurementFormatter.string(from: Unit) | |
let f = MeasurementFormatter() | |
f.locale = Locale(identifier: "de_DE") | |
f.unitOptions = .naturalScale | |
f.unitStyle = .long | |
f.string(from: UnitSpeed.milesPerHour) | |
f.string(from: UnitTemperature.celsius) | |
// NSLocale exposes measurement system (Locale doesn't) | |
Locale(identifier: "de_DE").usesMetricSystem | |
NSLocale(localeIdentifier: "de_DE").object(forKey: .measurementSystem) | |
NSLocale(localeIdentifier: "en_GB").object(forKey: .measurementSystem) | |
NSLocale(localeIdentifier: "en_US").object(forKey: .measurementSystem) | |
enum MeasurementSystem: String { | |
case metric = "Metric" | |
case us = "U.S." | |
case uk = "U.K." | |
} | |
extension Locale { | |
/// Type-safe variant of NSLocale.object(forKey: .measurementSystem) | |
/// Returns .metric by default if an unknown measurement system is returned. | |
var measurementSystem: MeasurementSystem { | |
let ns = (self as NSLocale).object(forKey: .measurementSystem) | |
guard let s = ns as? String, let m = MeasurementSystem(rawValue: s) else { | |
assertionFailure("Locale \(self) has unknown measurement system: \(ns as Any)") | |
return .metric | |
} | |
return m | |
} | |
} | |
extension UnitTemperature { | |
static func preferredUnits(for locale: Locale) -> [UnitTemperature] { | |
switch locale.measurementSystem { | |
case .metric, .uk: | |
return [.celsius] | |
case .us: | |
return [.fahrenheit] | |
} | |
} | |
} | |
UnitTemperature.preferredUnits(for: Locale(identifier: "de_DE")).first?.symbol | |
UnitTemperature.preferredUnits(for: Locale(identifier: "en_US")).first?.symbol | |
// I'd like to have a protocol-based version of the method, e.g.: | |
// | |
// protocol LocalizableUnit where Self: Unit { | |
// static func preferredUnits(for locale: Locale) -> [Self] | |
// } | |
// | |
// But that isn't compatible with Foundation's non-final unit classes. Pity. | |
extension UnitLength { | |
static func preferredUnits(for locale: Locale) -> [UnitLength] { | |
switch locale.measurementSystem { | |
case .metric: | |
return [.meters, .kilometers, .centimeters, .millimeters] | |
case .us, .uk: | |
return [.feet, .yards, .miles, .inches] | |
} | |
} | |
} | |
let locales = [ | |
Locale(identifier: "de_DE"), | |
Locale(identifier: "dk_DK"), | |
Locale(identifier: "fr_FR"), | |
Locale(identifier: "en_US") | |
] | |
let unitsPerLocale = locales.map { locale -> [String] in | |
let units = UnitLength.preferredUnits(for: locale) | |
let formatter = MeasurementFormatter() | |
formatter.locale = locale | |
formatter.unitStyle = .long | |
return units.map(formatter.string(from:)) | |
} | |
print(unitsPerLocale) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment