在运行时更改iOS模拟器的当前区域设置

前端之家收集整理的这篇文章主要介绍了在运行时更改iOS模拟器的当前区域设置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在开发一组日期计算和将数值和日期转换为字符串的语言规则时,我正在编写一个断言字符串格式化方法的结果的测试.一个虚构的断言可能如下所示:
NSAssert([dateString isEqualToString:@"Three days,until 6:00 PM"],@"Date string should match expectation");

然而,由于应用程序是针对多种语言进行本地化的,同时我的开发人员也来自不同的地区,我的设备或模拟器可能会被设置为与测试所写的不同的区域设置.在这样的场景中,dateString的内容可能是这样的:

@"Drie dagen,tot 18:00" // the assertion fails
@"Drei Tage,bis 18 Uhr" // the assertion also fails

这可能是也可能不是这些区域设置的正确日期符号,但是我的问题所在的部分是如何在底层代码使用Apple API时能够对特定区域进行测试.

[NSDateFormatter localizedStringFromDate:date 
                 dateStyle:NSDateFormatterNoStyle 
                 timeStyle:NSDateFormatterShortStyle];

我很乐意在我的断言中用两种或更多种语言来覆盖,这样的东西:

[NSSomething actionToSetTheLocaleTo:@"en_US"];
dateString = ...; // the formatting
NSAssert([dateString isEqualToString:@"Three days,@"match en_US");

[NSSomething actionToSetTheLocaleTo:@"nl_NL"];
dateString = ...; // the formatting
NSAssert([dateString isEqualToString:@"Drie dagen,tot 18:00"],@"match nl_NL");

谁知道如何达到这个效果

笔记:

>改变首选语言并不会削减它,还需要影响NSDateFormatter和NSNumberFormatter行为.
>因为这只是为了单元测试的目的,所以我会使用私有API来满足.然而,为了让其他人绊倒这个职位,公共API是首选.
>将自定义语言环境传递给每个日期或数字格式API可能是最后的考虑因素,但我发布了这个问题,希望避免回到这些极端措施.如果你知道这是唯一的解决方案,请提供一些参考,我将不再浪费时间

链接主题

> Nice article by Ray Lillywhite on i18n and l10n
> NSHipster article on NSLocale

解决方法

@Desmond指出了一个工作的解决方案.在他把这个信息放在这里之前,让我总结一下我最后做的一些代码.

事实证明,解决方案与类方法内部使用的“一样简单”为swizzling the methods

beforeEach(^{
    [NSBundle ttt_overrideLanguage:@"nl"];
    [NSLocale ttt_overrideRuntimeLocale:[NSLocale localeWithLocaleIdentifier:@"nl_NL"]];
});

afterEach(^{
    [NSLocale ttt_resetRuntimeLocale];
    [NSBundle ttt_resetLanguage];
});

上面看到的ttt _…方法使用NSObject,NSLocale和NSBundle上的类别来检查运行时是否应该使用原始方法或返回其他内容.在编写测试时,这种方法无瑕疵,尽管技术上不使用任何私有API,但我强烈建议您仅在测试设置中使用此功能,而不是您提交给App Store进行审阅的任何内容.

In this gist you’ll find the Objective-C categories添加到我的应用程序的测试目标来实现所需的行为.

原文链接:https://www.f2er.com/iOS/329060.html

猜你在找的iOS相关文章