Мне нужно провести некоторое тестирование, которое предполагает перемещение "телефона" назад и вперед через несколько дней. Я бы хотел сделать это на симуляторе. Есть ли доступный хак, который позволяет изменить дату, указанную на симуляторе, без изменения даты Mac?
Есть ли способ изменить дату/время, как показано на симуляторе iOS (кроме изменения настроек Mac)?
Ответ 1
Похоже, это довольно сложно... Как насчет использования xcodebuild
для автоматизации создания и запуска приложения из script и использования systemsetup -setdate <mm:dd.yy>
для изменения даты между разными запусками? Тогда вам не нужно ничего менять в коде.
Ответ 2
Вы можете использовать метод swizzling для замены реализации [NSDate date]
во время выполнения, чтобы вернуть значение по вашему выбору.
Подробнее о методах swizzling см. http://www.icodeblog.com/2012/08/08/using-method-swizzling-to-help-with-test-driven-development/.
Ответ 3
Мне нужно было проверить приложение автоматически, что потребовало изменения времени sys. Я сделал то, что предложил Том: счастливый хакерский метод swizzling.
В демонстрационных целях я меняю только [NSDate date]
, но не [NSDate dateWithTimeIntervalSince1970:]
.
Сначала вам нужно создать свой метод класса, который будет использоваться в качестве нового [NSDate date]
. Я применил его, чтобы просто сдвинуть время на константу 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);
Очевидно, убедитесь, что вы не используете это в развернутом приложении. Наконец, я могу только согласиться с ответами до того, что довольно сомнительно, почему Apple не добавила для этого встроенную поддержку.
Ответ 4
Если вы создаете приложение, просто измените дату в приложении для тестирования, и вы можете удалить его при его публикации.