Solution 1: Delegate your application to a subclass of UIApplication. In the implementation section, override sendEvent: method:
-(Void) sendEvent :( UIEvent *) event {
[Super sendEvent: event];
// Only reset idle time at the start or end of touch to reduce unnecessary clock reset actions
NSSet * allTouches = [event allTouches];
If ([allTouches count]> 0 ){
// AllTouchescount seems to be only 1, so anyObject is always available
UITouchPhase phase = (UITouch *) [allTouches anyObject]). phase;
If (phase = UITouchPhaseBegan | phase = UITouchPhaseEnded)
[Self resetIdleTimer];
}
}
-(Void) resetIdleTimer {
If (idleTimer ){
[IdleTimerinvalidate];
[IdleTimerrelease];
}
IdleTimer = [[NSTimer scheduledTimerWithTimeInterval: maxIdleTimetarget: self selector: @ selector (idleTimerExceeded) userInfo: nil repeats: NO] retain];
}
-(Void) idleTimerExceeded {
NSLog (@ "idle time exceeded ");
}
MaxIdleTime and idleTimer are both instance variables.
In addition, you need to modify main. m and tell UIApplicationMain to use your delegate class (in this example, AppDelegate) as the main class:
Int main (int argc, char * argv [])
{
@ Autoreleasepool {
Return UIApplicationMain (argc, argv, NSStringFromClass ([AppDelegateclass]), NSStringFromClass ([AppDelegate class]);
}
}
Solution 2: this solution does not require subclass-based UIApplication. It can take effect on a certain UIViewController subclass, so it is useful for only one ViewController (such as an interactive application or game), or you only want to process user idle time in a View Controller.
Instead of recreating the NSTimer object when the clock is reset, it only modifies the trigger time of the NSTimer object.
In your code, you can call resetIdleTimer to detect various events (such as sudden changes to the accelerator ).
@ Interface MainViewController: UIViewController {
NSTimer * idleTimer;
}
@ End
# Define kMaxIdleTimeSeconds 60.0
@ Implementation MainViewController
# Pragma mark-
# Pragma mark Handling idle timeout
-(Void) resetIdleTimer {
If (! IdleTimer ){
IdleTimer = [[NSTimer scheduledTimerWithTimeInterval: kMaxIdleTimeSeconds target: self selector: @ selector (idleTimerExceeded) userInfo: nil repeats: NO] retain];
}
Else {
If (fabs ([idleTimer. fireDate timeIntervalSinceNow]) <kMaxIdleTimeSeconds-1.0 ){
[IdleTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: kMaxIdleTimeSeconds];
}
}
}
-(Void) idleTimerExceeded {
[IdleTimerrelease];
IdleTimer = nil;
[SelfstartScreenSaverOrSomethingInteresting];
[SelfresetIdleTimer];
}
-(UIResponder *) nextResponder {
[SelfresetIdleTimer];
Return [super nextResponder];
}
-(Void) viewDidLoad {
[SuperviewDidLoad];
[SelfresetIdleTimer];
}
@ End
Memory Management Code is ignored for simplicity.