web-dev-qa-db-fra.com

NSDateFormatter et langue actuelle dans iOS11

Il semble que le comportement par défaut de NSDateFormatter ait été modifié dans iOS11. Ce code fonctionnait et produisait un formateur de date selon la langue iPhone/iPad actuellement sélectionnée avant iOS11:

 _dateFormatterInstance = [[NSDateFormatter alloc] init];
 _dateFormatterInstance.timeZone = [NSTimeZone systemTimeZone];

On dirait que dans iOS11, nous devons explicitement spécifier la propriété locale pour cela:

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

Quelqu'un peut-il confirmer mes conclusions?

24
sha

Ce n'est pas un problème avec NSDateFormatter, c'est un changement dans la façon dont iOS 11 prend en charge la localisation.

Sous iOS 11, [NSLocale currentLocale] renvoie uniquement les langues prises en charge par les localisations de votre application. Si votre application ne prend en charge que l'anglais (comme localisation de base), quelle que soit la langue sélectionnée par l'utilisateur sur l'appareil, currentLocale renverra toujours l'anglais.

Sous iOS 10 et versions antérieures, currentLocale représenterait directement la langue et la région choisies par l'utilisateur, quelles que soient les localisations prises en charge par votre application.

Des classes telles que NSDateFormatter utilisent par défaut NSLocale currentLocale. Donc, quelle que soit la langue prise en charge par votre application par le biais de sa localisation, des classes comme NSDateFormatter afficheraient du texte dans la langue définie sur l'appareil, même si elle était différente de la langue utilisée par votre application.

iOS 11 corrige cette incohérence. Bien que l'on puisse affirmer que ce changement casse de nombreuses applications qui ne prennent en charge qu'une seule (ou seulement quelques) langues, il rend en fait l'application plus cohérente.

Pour clarifier tout cela, considérons un exemple. Vous créez une application de test simple avec une localisation de base en anglais. Si vous exécutez votre application avec iOS 10 et que la langue de l'appareil est définie sur l'anglais, vous voyez évidemment du texte anglais et des dates formatées pour l'anglais. Si vous changez maintenant la langue de l'appareil en français et redémarrez l'application, l'utilisateur voit maintenant le texte anglais dans l'application (car c'est sa seule localisation) mais les dates s'affichent désormais avec les noms français des mois et des jours de la semaine.

Maintenant, exécutez la même application sous iOS 11. Comme avec iOS 10, si la langue de l'appareil est l'anglais, vous voyez tout en anglais. Si vous changez ensuite la langue de l'appareil en français et exécutez l'application, iOS 11 voit que votre application prend uniquement en charge l'anglais et currentLocale renvoie l'anglais, pas le français. Alors maintenant, l'utilisateur voit le texte anglais (en raison de la localisation de l'application) et les dates sont désormais également en anglais.

63
rmaddy

En fait, cela semble être davantage un bogue qu'un changement intentionnel de comportement dans iOS 11. Si vous n'avez qu'un seul ensemble de langues, ce comportement n'est pas présent en tant que Locale.current renvoie toujours la langue et la région correctes même si votre application n'est pas localisée dans cette langue.

Cependant, si vous avez plusieurs langues, telles que le français et l'anglais, iOS 11 semble toujours privilégier l'anglais ou la langue prise en charge la plus proche dans votre application lorsque vous utilisez Locale.current.

Locale.preferredLanguages semble renvoyer les informations de région linguistique correctes, vous pourrez donc peut-être les utiliser à la place.

Voici un exemple montrant la sortie de Locale.current et Locale.preferredLanguages, montrant les incohérences.

Cela a été généré à partir d'une application qui ne supportait que l'anglais. Sur l'appareil, le français a été défini à la fois comme langue principale et comme région, l'anglais (Australie) étant défini comme langue secondaire dans le premier exemple.

(Incorrect) Locale.current avec plusieurs langues - notez comment l'anglais est la langue, alors qu'elle devrait être le français et donc fr_FR

  - identifier : "en_FR"
  - kind : "current"

(Correct) Locale.preferredLanguages avec plusieurs langues

  - 0 : "fr-FR"
  - 1 : "en-AU"

(Correct) Locale.current avec le français comme seule langue

  - 0 : "fr-FR"

(Correct) Locale.preferredLanguages avec le français comme seule langue

  - identifier : "fr_FR"
  - kind : "current"
10
Brenton

Oui, le comportement par défaut est modifié dans iOS11 exactement comme @rmaddy l'a décrit.

Dans mon cas, j'ai un projet avec un langage de développement de base défini sur anglais mais, sur iOS11, lorsque je changeais la langue de l'appareil en une autre langue (par exemple le suédois), les dates restaient affichées, par exemple, Monday 6 November. Cela est dû au fait que mon application ne prend en charge aucune localisation.

La solution était simple: pour que l'application affiche les dates en suédois, je devais simplement ajouter un fichier Strings.strings Vide puis, dans les paramètres des projets, j'ai ajouté la localisation suédoise. Bien que le fichier de chaînes soit vide, l'application s'est ensuite localisée en suédois, donc en changeant la langue, dans Paramètres, en suédois, nous pourrions voir la même date que måndag 6 november, Réalisant ainsi le cas d'utilisation souhaité d'iOS10.

Remarque: si vous faites quelque chose comme ça et que cela ne fonctionne pas pour vous, lorsque vous ajoutez une langue dans les paramètres du projet, assurez-vous d'aller dans "Autre" et choisissez une langue à partir de là (au lieu de simplement choisir un du menu déroulant de premier niveau).

1
jpcarreira