NSMeasurementFormatter reversed


Gerriet M. Denkmann
 

NSMeasurementFormatter is a magical tool which converts all stuff just into the right form the user wants to see.

But what about the other way round?

I have a TextField labeled “Desired Temperature” the user enters “83.4” - what does the user want?
Boiling hot (using Celsius) or comfortably warm (Fahrenheit)?

So my app does:

if ( NSLocale.currentLocale.usesCelsius ) ….

The problem: I can’t find such a property.

Or:
NSMeasurement *raw = [measurementFormatter measurementFromString: “83.4” for: NSUnitTemperature];
NSMeasurement *m = [raw measurementByConvertingToUnit: NSUnitTemperature.celsius];

No luck either.

So:

NSMeasurement *trySome = [[NSMeasurement alloc] initWithDoubleValue: 83.4 unit: NSUnitTemperature.celsius ];
NSString *trialResult = [measurementFormatter stringFromMeasurement: trySome];

BOOL usesCelsius = …trialResult resembles somehow “83.4” …;
This is rather error prone; what if the actual user-input was 83.399999999 ?

There clearly must be a much better way.

Gerriet.


James Walker
 

On Sep 25, 2018, at 7:05 PM, Gerriet M. Denkmann <g@mdenkmann.de> wrote:

NSMeasurementFormatter is a magical tool which converts all stuff just into the right form the user wants to see.

But what about the other way round?

I have a TextField labeled “Desired Temperature” the user enters “83.4” - what does the user want?
Boiling hot (using Celsius) or comfortably warm (Fahrenheit)?
Typing

defaults find Temperature

at the command line produces

Found 1 keys in domain 'Apple Global Domain': {
AppleTemperatureUnit = Fahrenheit;
}

I’m not sure if you can get that with NSUserDefaults, maybe you have to use CFPreferences.


Gerriet M. Denkmann
 

On 26 Sep 2018, at 22:29, James Walker <list2@jwwalker.com> wrote:



On Sep 25, 2018, at 7:05 PM, Gerriet M. Denkmann <g@mdenkmann.de> wrote:

NSMeasurementFormatter is a magical tool which converts all stuff just into the right form the user wants to see.

But what about the other way round?

I have a TextField labeled “Desired Temperature” the user enters “83.4” - what does the user want?
Boiling hot (using Celsius) or comfortably warm (Fahrenheit)?
Typing

defaults find Temperature

at the command line produces

Found 1 keys in domain 'Apple Global Domain': {
AppleTemperatureUnit = Fahrenheit;
}
Excellent find! Thanks a lot!

There seem to be 3 ways to get this info:

NSString *temp1 = [NSUserDefaults.standardUserDefaults stringForKey: @"AppleTemperatureUnit"];

NSString *temp2 = [ NSLocale.currentLocale objectForKey: @"kCFLocaleTemperatureUnitKey"];

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit;
NSString *temp3 = [ NSLocale.currentLocale objectForKey: NSLocaleTemperatureUnit];

Probably the first one (the one you found) is the best, i.e. most likely to work in future OS versions.

All work on macOS and iOS.
The first one returns nil in the Simulator

Gerriet.


Quincey Morris
 

On Sep 26, 2018, at 09:44 , Gerriet M. Denkmann <g@...> wrote:

NSString *temp1 = [NSUserDefaults.standardUserDefaults stringForKey: @"AppleTemperatureUnit"];

NSString *temp2 = [ NSLocale.currentLocale objectForKey: @"kCFLocaleTemperatureUnitKey"];

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit;
NSString *temp3 = [ NSLocale.currentLocale objectForKey: NSLocaleTemperatureUnit];

Be careful with this. If you look at some of the Stack Overflow posts about this, it seems to be regarded as private API, and a cause for rejection by App Review.

I think the real answer is that getting the region setting for temperature is just not supported. There may not be a good, future-proof mechanism for getting the setting you want.


James Walker
 

On 9/26/18 5:12 PM, Quincey Morris wrote:
On Sep 26, 2018, at 09:44 , Gerriet M. Denkmann <g@...> wrote:

NSString *temp1 = [NSUserDefaults.standardUserDefaults stringForKey: @"AppleTemperatureUnit"];

NSString *temp2 = [ NSLocale.currentLocale objectForKey: @"kCFLocaleTemperatureUnitKey"];

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit;
NSString *temp3 = [ NSLocale.currentLocale objectForKey: NSLocaleTemperatureUnit];

Be careful with this. If you look at some of the Stack Overflow posts about this, it seems to be regarded as private API, and a cause for rejection by App Review.

I think the real answer is that getting the region setting for temperature is just not supported. There may not be a good, future-proof mechanism for getting the setting you want.

The first of those 3 methods does not use a private API.  But you could say that an undocumented default could break in the future.