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

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
aneuryzm
  • 63,052
  • 100
  • 273
  • 488

7 Answers7

85

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.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • 7
    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. – James Webster Sep 14 '11 at 08:59
  • @DarkDust 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 ? – aneuryzm Sep 14 '11 at 20:32
  • 1
    @Patrick: Check in the `applicationDidBecomeActive:` method of `UIApplicationDelegate` (or subscribe to the corresponding notification, `UIApplicationDidBecomeActiveNotification`) and/or subscribe to the `NSCurrentLocaleDidChangeNotification`. – DarkDust Sep 15 '11 at 06:24
  • @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 world – lewis Aug 03 '21 at 09:12
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
Nazmul Hasan
  • 10,130
  • 7
  • 50
  • 73
14

here's a swift version

var locale = NSLocale.currentLocale()
let isMetric = locale.objectForKey(NSLocaleUsesMetricSystem) as! Bool
nibty
  • 359
  • 2
  • 6
14

For swift 3

    let locale = NSLocale.current
    let isMetric = locale.usesMetricSystem
GIJOW
  • 2,307
  • 1
  • 17
  • 37
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

Eneko Alonso
  • 18,884
  • 9
  • 62
  • 84
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.

Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152
  • 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? – coernel Feb 20 '15 at 11:31
3
// Before iOS 16
Locale.current.usesMetricSystem

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

usesMetricSystem is deprecated on iOS 16

DamjanDabo
  • 97
  • 3