How do I know which is the default measure system (imperial or metric) on iOS?
Asked Answered
C

7

61

How do I know which is the default measure system (imperial or metric) on iOS ?

How do I get this preference from the device settings, so I know what to display in my app ?

thanks

Confidence answered 14/9, 2011 at 8:8 Comment(0)
Z
86

The NSLocale can tell you:

NSLocale *locale = [NSLocale currentLocale]; 
BOOL isMetric = [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue];

Only three countries do not use the metric system: the US, Liberia and Myanmar. The later uses its own system, the former two use Imperial Units.

Apples documentation says (emphasis mine):

NSLocaleUsesMetricSystem

The key for the flag that indicates whether the locale uses the metric system. The corresponding value is a Boolean NSNumber object. If the value is NO, you can typically assume American measurement units (for example, the statute mile).

Available in iOS 2.0 and later.

Zayas answered 14/9, 2011 at 8:56 Comment(4)
NB: The UK uses a combination of metric and imperial. Weights tend to be measured in kg, but distance (especially on the roads) is still in miles.Lacefield
@Zayas Thanks, it was a solution indeed. My only problem now is how to update the settings in my app if the user changes the locale setting from iPad preferences, while running my app in multitasking. I can only thing to check for it in viewDidAppear but is there a better solution ?Confidence
@Patrick: Check in the applicationDidBecomeActive: method of UIApplicationDelegate (or subscribe to the corresponding notification, UIApplicationDidBecomeActiveNotification) and/or subscribe to the NSCurrentLocaleDidChangeNotification.Zayas
@JamesWebster For weighing people in particular many Brits still use stones, which as far as I know is not actively used anywhere else in the worldAilanthus
D
42

@DarkDust answer for swift3

//User region setting return
let locale = Locale.current //NSLocale.current

//Returns true if the locale uses the metric system 
let isMetric = locale.usesMetricSystem
Droshky answered 12/11, 2016 at 6:45 Comment(0)
O
14

here's a swift version

var locale = NSLocale.currentLocale()
let isMetric = locale.objectForKey(NSLocaleUsesMetricSystem) as! Bool
Odyssey answered 30/6, 2015 at 18:14 Comment(1)
Thanks! For Swift 2 will be: let locale = NSLocale.currentLocale()Archaean
C
14

For swift 3

    let locale = NSLocale.current
    let isMetric = locale.usesMetricSystem
Commemorate answered 14/9, 2016 at 14:28 Comment(2)
But only for iOS 10+; not clear to me how you'd do this in a Swift 3 app targeting iOS 9.Exurbanite
Locale.current.usesMetricSystem works fine in iOS 9.Fibrinous
U
6

As others mentioned before, the UK uses a mix of metric and imperial units.

I would recommend using the new MeassurementFormatter introduced in iOS 10 which handles most of these discrepancies:

import Foundation

let locale = Locale(identifier: "EN_UK")
locale.usesMetricSystem // true!
var formatter = MeasurementFormatter()
formatter.locale = locale
formatter.string(from: Measurement(value: 1000, unit: UnitLength.meters)) // 0.621 mi

To render a distance as a string in local, natural unit, use:

let distanceInMeters: CLLocationDistance = 1000
let formatter = MeasurementFormatter()
formatter.string(from: Measurement(value: distanceInMeters, unit: UnitLength.meters)) // 0.621 mi

Official documentation: https://developer.apple.com/documentation/foundation/measurementformatter

Univocal answered 21/3, 2018 at 20:4 Comment(0)
P
6
// Before iOS 16
Locale.current.usesMetricSystem

// iOS 16 and up
Locale.current.measurementSystem == .metric

usesMetricSystem is deprecated on iOS 16

Pelletier answered 26/4, 2023 at 13:36 Comment(0)
O
4

You should probably just have a setting in your app and let your users choose -- this is what Apple does in the Weather app.

If you want to choose a sensible default you could look at the locale. If it's US, pick imperial otherwise choose metric. It is a heuristic, it will be wrong sometimes, but it's just a default that can be changed.

Osithe answered 14/9, 2011 at 8:23 Comment(1)
I'm trying to do exactly that. I have a view controller that is supposed to show the unit system (cm / ft&inch) and convert between the two. I have made a settings bundle with a toggle switch (off: metric / on: imperial, default: off). that works when i start the app for the first time. however, if i change to imperial, that change goes through but a change back to off (-> metric) doesn't have any effect whatsoever. ideas?Zoophyte

© 2022 - 2024 — McMap. All rights reserved.