I need to do some testing that involves moving the "phone" backwards and forwards through several days. I'd like to do this on the simulator. Is there any available hack that allows the date as seen on the simulator to be changed, without having to change the Mac date?
问题:
回答1:
Looks like it's pretty tough... How about using xcodebuild
to automate building and running the app from a script and using systemsetup -setdate <mm:dd.yy>
to change date in between different runs? Then you wouldn't need to change anything in code.
回答2:
You can use method swizzling to replace the implementation of [NSDate date]
at runtime to return a value of your choosing.
For more info on method swizzling, see http://www.icodeblog.com/2012/08/08/using-method-swizzling-to-help-with-test-driven-development/.
回答3:
I needed to test my app automatically, which required changing the sys time. I did, what Tom suggested: happy hacky method swizzling.
For demonstrative purposes, I only change [NSDate date]
but not [NSDate dateWithTimeIntervalSince1970:]
.
First your need to create your class method that serves as the new [NSDate date]
. I implemented it to simply shift the time by a constant 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]; }
So far, pretty easy. Now comes the fun part. We get the methods from both classes and exchange implementation (it worked for me in the AppDelegate, but not in my UITests class). For this you will need to import 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);
Obviously, make sure that you use non of this in your deployed application. Lastly, I can only agree with the answers before that it is quite questionable why Apple didn't add native support for this.
回答4:
If you are creating an app, just change the date in the app for testing and you can remove it when you publish it.