iOS11中的NSDateFormatter和当前语言

iOS11中的NSDateFormatter和当前语言,ios,locale,nsdateformatter,ios11,Ios,Locale,Nsdateformatter,Ios11,似乎在iOS11中,NSDateFormatter的默认行为已更改。此代码用于根据iOS11之前当前选择的iPhone/iPad语言工作并生成日期格式化程序: _dateFormatterInstance = [[NSDateFormatter alloc] init]; _dateFormatterInstance.timeZone = [NSTimeZone systemTimeZone]; 看起来在iOS11中,我们必须为其显式指定locale属性: _dateFormatterI

似乎在iOS11中,
NSDateFormatter
的默认行为已更改。此代码用于根据iOS11之前当前选择的iPhone/iPad语言工作并生成日期格式化程序:

 _dateFormatterInstance = [[NSDateFormatter alloc] init];
 _dateFormatterInstance.timeZone = [NSTimeZone systemTimeZone];
看起来在iOS11中,我们必须为其显式指定locale属性:

 _dateFormatterInstance = [[NSDateFormatter alloc] init];
 _dateFormatterInstance.timeZone = [NSTimeZone systemTimeZone];
 _dateFormatterInstance.locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] firstObject]];

有人能证实我的发现吗

这不是NSDateFormatter的问题,而是iOS 11支持本地化的方式的改变

在iOS 11下,
[NSLocale currentLocale]
仅返回应用程序本地化支持的语言。如果您的应用程序只支持英语(作为基本本地化),那么无论用户在设备上选择何种语言,
currentLocale
都将始终返回英语

在iOS 10及更早版本中,
currentLocale
将直接代表用户选择的语言和地区,而不管您的应用程序支持什么本地化

诸如
NSDateFormatter
之类的类默认使用
NSLocale currentLocale
。因此,无论您的应用程序通过本地化实际支持哪种语言,像
NSDateFormatter
这样的类都会以设备上设置的语言显示文本,即使它与您的应用程序使用的语言不同

iOS 11修复了这种不一致性。虽然有人可能会说,这一变化打破了许多只支持一种(或几种)语言的应用程序,但它实际上使应用程序更加一致

为了使所有这些都清楚,请考虑一个例子。您创建了一个简单的测试应用程序,其基本本地化语言为英语。如果您使用iOS 10运行应用程序,并且设备的语言设置为英语,那么您显然会看到英语文本,并且会看到以英语格式化的日期。如果您现在将设备语言更改为法语并重新启动应用程序,用户现在会在应用程序中看到英文文本(因为这是它唯一的本地化版本),但日期现在显示为法语月份和工作日名称


现在在iOS 11下运行相同的应用程序。与iOS 10一样,如果设备的语言是英语,那么您可以看到所有的语言都是英语。如果您随后将设备语言更改为法语并运行应用程序,iOS 11会发现您的应用程序只支持英语,
currentLocale
返回英语,而不是法语。因此,现在用户看到的是英文文本(由于应用程序的本地化),日期现在仍然是英文的。

是的,默认行为在iOS11中的更改与@rmaddy描述的完全相同

在我的例子中,我有一个项目的基本开发语言设置为英语,但在iOS11上,当我将设备的语言更改为任何其他语言(如瑞典语)时,日期仍将显示为,例如,11月6日的
星期一
。这是因为我的应用程序不支持任何本地化

解决方案很简单:为了让应用程序以瑞典语显示日期,我只需添加一个空的
Strings.Strings
文件,然后在项目设置中添加瑞典语本地化。虽然strings文件是空的,但该应用程序随后被本地化为瑞典语,因此通过将设置中的语言更改为瑞典语,我们可以看到与11月6日相同的日期,从而实现理想的iOS10用例


注意:如果你做了这样的事情,但它对你不起作用,那么在项目设置中添加语言时,请确保转到“其他”并从中选择一种语言(而不仅仅是从第一级下拉列表中选择一种)。这实际上看起来更像是一个bug,而不是iOS 11中有意改变的行为。如果您只有一个语言集,则此行为不会显示为
区域设置。即使您的应用程序未本地化为该语言,current
始终返回正确的语言和区域

但是,如果您有多种语言(如法语和英语),那么在使用
Locale.current
时,iOS 11似乎总是倾向于使用英语或应用程序中最受支持的语言

Locale.preferredLanguages
会返回正确的语言区域信息,因此您可以使用该信息

下面的示例显示了
Locale.current
Locale.preferredLanguages
的输出,显示了不一致性

这是从只支持英语的应用程序生成的。在第一个例子中,法语被设置为主要语言和地区,英语(澳大利亚)被设置为次要语言

(不正确)
Locale。当前使用多种语言的
——请注意英语是一种怎样的语言,它应该是法语,因此是法语

  - identifier : "en_FR"
  - kind : "current"
(正确)
Locale。首选语言具有多种语言

  - 0 : "fr-FR"
  - 1 : "en-AU"
(正确)
Locale.当前
,法语为唯一语言

  - 0 : "fr-FR"
  - identifier : "fr_FR"
  - kind : "current"
(正确)
Locale.首选语言
,法语为唯一语言

  - 0 : "fr-FR"
  - identifier : "fr_FR"
  - kind : "current"

你在iOS 11中看到了什么行为?它与iOS 10有何不同?当此代码在设备上运行时,配置为使用法语(例如),日期格式化程序仍然使用英语名称表示周数。在iOS10上,第一个代码将使用法语名称。我很好奇,如果你想使用他们喜欢的语言环境,你可以按照你的指示设置
语言环境
——你还需要设置
日历
和/或
时区
?@Joey我不确定我是否理解。在我的代码中,我确实设置了当前时区。当前日历-我认为它将默认为该日历,但您始终可以设置它以确保它。我认为时区行为保持不变(您不能有不支持特定时区的应用程序)。可能同样的逻辑也适用于日历:)本地语言和受支持的语言似乎与时区和日历完全不同。谢谢!这是非常有用和彻底的。在我的例子中,我实际上更喜欢iOS10的行为,因为我们正在从后端f进行本地化支持