Search code examples
ioslocaleios10

Determine user's "Temperature Unit" setting on iOS 10 (Celsius / Fahrenheit)


iOS 10 adds the ability for the user to set their "Temperature Unit" choice under Settings > General > Language & Region > Temperature Unit.

How can my app programmatically determine this setting so it can display the right temperature unit? I poured through NSLocale.h and didn't see anything relevant.

(Before iOS 10, it was sufficient to test if the locale used metric and assume that metric users want to use Celsius. This is no longer the case.)


Solution

  • There is this article by Alexandre Colucci that I found: http://blog.timac.org/?tag=nslocaletemperatureunit

    First, expose the NSLocaleTemperatureUnit NSLocaleKey:

    FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit;
    

    Then check the unit with this:

    temperatureUnit = [[NSLocale currentLocale] objectForKey:NSLocaleTemperatureUnit]
    

    Or Swift (2.3):

    if let temperatureUnit = NSLocale.currentLocale().objectForKey(NSLocaleTemperatureUnit) {
        ...
    }
    

    It will return a string which is either "Celcius" or "Fahrenheit".

    But there is an issue: it's not backwards compatible with iOS versions earlier than 10. If you run your app on an iOS 9 or earlier device, you'll get an error "dyld: Symbol not found: _NSLocaleTemperatureUnit" during app startup.

    The solution is to use weak linking for the NSLocaleTemperatureUnit variable definition. Like this:

    FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit  __attribute__((weak_import));
    

    This will let the app pass the dyld checks. But now you will have to check for the OS version before using NSLocaleTemperatureUnit, or your app will crash with an exception.

    if #available(iOS 10,*) {
        if let temperatureUnit = NSLocale.currentLocale().objectForKey(NSLocaleTemperatureUnit) {
            ...
        }
    }
    

    EDIT:

    I tried it in my app, but Apple rejected the app for it when I uploaded it to Testflight. So they definitely don't want us to use the setting for our own formatter classes. I find that pretty annoying.