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

Tim*_*man 10 locale ios ios10

iOS 10增加了用户在"设置">"常规">"语言和区域">"温度单位"下设置"温度单位"选项的功能.

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

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

ped*_*uan 14

有一(NS)MeasurementFormatter节课.它继承自一个(NS)Formatter类.这是适用于iOS 10+ SDK的新类.

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

设定一个Measurement使用斯威夫特3:

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
Run Code Online (Sandbox Code Playgroud)

对于检索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
Run Code Online (Sandbox Code Playgroud)

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

对于手动转换:

measurement.converted(to: UnitTemperature.kelvin).value  // 297.65
Run Code Online (Sandbox Code Playgroud)

迅速:

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

Objective-C的:

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


随意纠正语法.

  • 但这些都不涉及这个问题.`MeasurementFormatter`不会根据iOS 10中的"Temperature Unit"设置更改其输出.它根据不同的区域设置进行格式化. (3认同)
  • 我在运行iOS 10.2的设备上测试了此方法,并且该方法有效。苹果工程师在这里对此进行了描述https://forums.developer.apple.com/thread/70258 (2认同)

Ret*_*epV 6

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

首先,公开NSLocaleTemperatureUnit NSLocaleKey:

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit;
Run Code Online (Sandbox Code Playgroud)

然后使用以下方法检查设备:

temperatureUnit = [[NSLocale currentLocale] objectForKey:NSLocaleTemperatureUnit]
Run Code Online (Sandbox Code Playgroud)

或Swift(2.3):

if let temperatureUnit = NSLocale.currentLocale().objectForKey(NSLocaleTemperatureUnit) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

它将返回字符串“ Celcius”或“ Fahrenheit”。

但是有一个问题:它与10之前的iOS版本不向后兼容。如果在iOS 9或更早版本的设备上运行应用程序,则在应用程序启动期间会出现错误“ dyld:找不到符号:_NSLocaleTemperatureUnit”。

解决方案是对NSLocaleTemperatureUnit变量定义使用弱链接。像这样:

FOUNDATION_EXPORT NSLocaleKey const NSLocaleTemperatureUnit  __attribute__((weak_import));
Run Code Online (Sandbox Code Playgroud)

这将使该应用通过dyld检查。但是现在您必须在使用NSLocaleTemperatureUnit之前检查操作系统的版本,否则您的应用程序将崩溃并发生异常。

if #available(iOS 10,*) {
    if let temperatureUnit = NSLocale.currentLocale().objectForKey(NSLocaleTemperatureUnit) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我在应用程序中尝试过,但是当我将其上传到Testflight时,Apple拒绝了该应用程序。因此,他们绝对不希望我们将设置用于我们自己的格式化程序类。我觉得这很烦人。