Ho bisogno di fare alcuni test che comportano lo spostamento del "telefono" avanti e indietro per diversi giorni. Mi piacerebbe farlo sul simulatore. C'è qualche trucco disponibile che permetta di cambiare la data vista sul simulatore, senza dover cambiare la data del Mac?C'è un modo per cambiare la data/ora come visto sul simulatore iOS (oltre a cambiare le impostazioni del Mac)?
risposta
Se si sta creando un'app, è sufficiente modificare la data nell'app per il test e rimuoverla quando la si pubblica.
Tranne se è necessario testare in 20 diversi date che devi ricompilare 20 volte diverse. (Anche se suppongo che si possa inserire la data in un plist.) E si può avere '[data NSDate]' o equivalente in diversi punti del codice, o in un modulo per il quale non si controlla la fonte. –
sembra che sia piuttosto difficile ... Come sull'utilizzo xcodebuild
per automatizzare la costruzione e la gestione l'applicazione da uno script e l'utilizzo di systemsetup -setdate <mm:dd.yy>
per modificare la data in tra diverse esecuzioni? Quindi non è necessario modificare nulla nel codice.
I downvotes senza commenti sono abbastanza inutili. – JOM
È possibile utilizzare il metodo di swizzling per sostituire l'implementazione di [NSDate date]
in fase di runtime per restituire un valore di propria scelta.
Per ulteriori informazioni sul metodo di swizzling, vedere http://www.icodeblog.com/2012/08/08/using-method-swizzling-to-help-with-test-driven-development/.
grazie per quell'idea! L'ho implementato (vedi risposta sotto) –
Avevo bisogno di testare automaticamente la mia app, che richiedeva la modifica del tempo del sistema. L'ho fatto, quello che Tom ha suggerito: il metodo hacky felice sta girando.
A scopo dimostrativo, cambio solo [NSDate date]
ma non [NSDate dateWithTimeIntervalSince1970:]
.
Per prima cosa è necessario creare il metodo di classe che funge da nuovo [NSDate date]
. L'ho implementato per spostare semplicemente il tempo da un costante 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];
}
Finora, abbastanza facile. Ora arriva la parte divertente. Otteniamo i metodi da entrambe le classi e l'implementazione dello scambio (ha funzionato per me in AppDelegate, ma non nella mia classe UITests). Per questo è necessario importare 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);
Ovviamente, assicurarsi di non utilizzare questo nell'applicazione distribuita. Infine, posso solo essere d'accordo con le risposte precedenti che è abbastanza discutibile il motivo per cui Apple non ha aggiunto il supporto nativo per questo.
Mi è piaciuta la tua risposta ma non capisco come farlo. Puoi approfondirlo in dettaglio? Dove scrivere questo metodo di classe data personalizzato + (NSDate *)? Nella categoria (estensione)? Si prega di indicare dove scrivere questo metodo nel codice sorgente e come utilizzare quindi l'implementazione di questa soluzione. Questo sarà molto utile anche per gli altri che hanno la stessa confusione di me. Grazie in anticipo. –
@NiteshBorad Vorrei solo aggiungere tutto in un file e quindi chiamarlo, se la tua applicazione è stata lanciata in modalità DEBUG (potrebbe essere fatta in 'main.m' o nel tuo AppDelegate). Ecco un esempio di implementazione: https://gist.github.com/Sebastian-Hojas/01a23ccb5b1a0051997715ee5ec4862f –
Ho trovato questo il più semplice: http://stackoverflow.com/questions/1699671/how-to-change-time-and-timezone-in-iphone-simulator – Hahnemann