如何在iPhone模拟器中更改时间和时区?


当前回答

为了截屏,苹果最终通过simctl工具实现了在iOS模拟器的状态栏上覆盖时间的功能(从Xcode 11开始):

xcrun simctl status_bar "iPhone Xs" override --time "21:08"

其他回答

在更改系统日期时间首选项后,我不得不选择硬件>重置所有内容和设置。 只有在10.3版(SimulatorApp-880.5 CoreSimulator-681.5.4)中,我才这样做。

我已经提出了一个自动解决改变时间的问题,包括黑客方法swizzling: https://stackoverflow.com/a/34793193/829338。我想这也适用于相应地改变时区。


我需要自动测试我的应用程序,这需要改变系统时间。我照汤姆的建议去做了:快乐的手工搅拌法。

出于演示目的,我只改变了[NSDate date],而没有改变[NSDate dateWithTimeIntervalSince1970:]。

首先,你需要创建你的类方法,作为新的[NSDate日期]。我实现它只是将时间移动一个常数timeDifference。

int timeDifference = 60*60*24; //shift by one day
NSDate* (* original)(Class,SEL) = nil;

+(NSDate*)date{
    NSDate* date = original([NSDate class], @selector(date));
    return [date dateByAddingTimeInterval:timeDifference];
}

到目前为止,很简单。现在到了有趣的部分。我们从两个类和交换实现中获得方法(它在AppDelegate中对我有效,但在我的UITests类中无效)。为此,你需要导入objc/runtime.h。

Method originalMethod = class_getClassMethod([NSDate class], @selector(date));
Method newMethod = class_getClassMethod([self class], @selector(date));

//save the implementation of NSDate to use it later
original  = (NSDate* (*)(Class,SEL)) [NSDate methodForSelector:@selector(date)];

//happy swapping
method_exchangeImplementations(originalMethod, newMethod);

目前唯一可行的解决方案。XCode提供了为特定应用程序设置时区的选项。

在XCode中,单击应用程序,编辑方案->运行配置->参数选项卡->添加环境变量

创建一个变量,名称:TZ,值:CST(任何其他标准格式。XCode没有明确提到允许的值。但你也可以用America/Chicago)

为了截屏,苹果最终通过simctl工具实现了在iOS模拟器的状态栏上覆盖时间的功能(从Xcode 11开始):

xcrun simctl status_bar "iPhone Xs" override --time "21:08"

我的构建服务器是UTC,我的一些单元测试需要时区是PST。使用NSTimeZone上的一个类别,你可以覆盖苹果的实现来使用你的代码。也适用于swift项目。

//NSTimeZone+DefaultTimeZone.h
#import <Foundation/Foundation.h>

@interface NSTimeZone (DefaultTimeZone)

+(NSTimeZone *)defaultTimeZone;

@end

//NSTimeZone+DefaultTimeZone.m
#import "NSTimeZone+DefaultTimeZone.h"

@implementation NSTimeZone (DefaultTimeZone)

+(NSTimeZone *)defaultTimeZone
{
    return [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];
}

@end