在iOS 10(摄氏/华氏)上确定用户的“温度单位”设置

iOS 10增加了用户在“设置”>“常规”>“语言和区域”>“温度单位”下设置“温度单位”选项的function。

我的应用程序如何以编程方式确定此设置,以便它可以显示正确的温度单位? 我倾注了NSLocale.h并没有看到任何相关内容。

(在iOS 10之前,测试区域设置是否使用度量标准并假设度量标准用户想要使用摄氏度就足够了。现在不再是这种情况了。)

Alexandre Colucci撰写的这篇文章我发现: http ://blog.timac.org/?tag = nslocaletemperatureunit

首先,公开NSLocaleTemperatureUnit NSLocaleKey:

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit; 

然后检查单位:

 temperatureUnit = [[NSLocale currentLocale] objectForKey:NSLocaleTemperatureUnit] 

或斯威夫特(2.3):

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

它将返回一个字符串,它是“Celcius”或“Fahrenheit”。

但是存在一个问题:它不能向后兼容早于10的iOS版本。如果您在iOS 9或更早版本的设备上运行您的应用程序,您将在应用启动期间收到错误“dyld:Symbol not found:_NSLocaleTemperatureUnit”。

解决方案是为NSLocaleTemperatureUnit变量定义使用弱链接。 喜欢这个:

 FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit __attribute__((weak_import)); 

这将让应用程序通过dyld检查。 但是现在您必须在使用NSLocaleTemperatureUnit之前检查操作系统版本,否则您的应用程序将因exception而崩溃。

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

编辑:

我在我的应用程序中尝试过,但是当我将它上传到Testflight时Apple拒绝了它的应用程序。 所以他们绝对不希望我们使用我们自己的格式化程序类的设置。 我发现这很烦人。

有一个(NS)MeasurementFormatter类。 它inheritance自(NS)Formatter类。 这是适用于iOS 10+ SDK的新类。

我不确定是否有必要知道用户在他们的偏好中设置了什么单位。

使用Swift 3 设置 Measurement

 let formatter = MeasurementFormatter() let measurement = Measurement(value: 24.5, unit: UnitTemperature.celsius) let temperature = formatter.string(from: measurement) print(temperature) // 76.1°F // this value was computed to Fahrenheit value on my locale/preferences 

检索 Measurement

 print(measurement.unit) // °C - always celsius as it was set as Celsius formatter.unitStyle = .long formatter.locale = Locale.current formatter.string(from: measurement.unit) // degrees Celsius - always an original unit formatter.string(from: measurement) // 76.1 degrees Fahrenheit - regarding locale/settings formatter.locale = Locale.init(identifier: "it_IT") formatter.string(from: measurement.unit) // gradi Celsius - always an original unit formatter.string(from: measurement) // 24,5 gradi Celsius - regarding locale/settings 

系统知道我们设置了什么单位。 它将处理所有值转换工作,因为该值被设置为一对值和一个度量单位

对于手动转换:

 measurement.converted(to: UnitTemperature.kelvin).value // 297.65 

迅速:

https://developer.apple.com/reference/foundation/measurementformatter

Objective-C的:

https://developer.apple.com/reference/foundation/nsmeasurementformatter?language=objc


随意纠正语法。

这似乎是一个迟到的答案,但我在这里的评论中找到了@fábio-oliveira提到的一个简洁的解决方案。

最初的Apple主题: https : //forums.developer.apple.com/thread/70258

我在我的解决方案中尝试做的是具有将开尔文温度(从JSON文件解析并且可以是任何温度)转换为由系统区域设置指示的温度格式或由用户在设置>常规> Langauge&设置的温度格式的function。地区>温度单位 。 但是,我还需要温度在小数分隔符后显示0位数。

所以这是一个Swift 4解决方案(开尔文是输入温度单位):

 func temperatureFormatter(kelvinTemp: Double) -> String{ let mf = MeasurementFormatter() mf.numberFormatter.maximumFractionDigits = 0 let t = Measurement(value: kelvinTemp, unit: UnitTemperature.kelvin) return (String(format:"%@", mf.string(from: t))) } 

在这里你可以调用你的函数来转换值( _currentTemp是你提取的JSON温度值& convertedTemp是你根据上面提到的条件得到的转换温度):

 convertedTemp = temperatureFormatter(kelvinTemp: _currentTemp) 

让我知道如果这个解决方案适合你,它确实对我有用。 谢谢!