Reputation: 124
I want to check if the application is idle (user doesn't take any action for the last 30 minutes) and log out the user.
For that I have an event manager that resets a timer.
- (void)sendEvent:(UIEvent *)event {
if(event == nil) {
[self resetIdleTimer];
} else {
[super sendEvent:event];
// Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
NSSet *allTouches = [event allTouches];
if ([allTouches count] > 0) {
// allTouches count only ever seems to be 1, so anyObject works here.
UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
[self resetIdleTimer];
}
}
}
- (void)resetIdleTimer {
if (self.idleTimer) {
[self.idleTimer invalidate];
self.idleTimer = nil;
}
NSInteger maxTime = 60*30; //30 minutes
self.idleTimer = [NSTimer scheduledTimerWithTimeInterval:maxTime target:self selector:@selector(checkIfIdleTimerExceeded) userInfo:nil repeats:NO];
}
- (void)checkIfIdleTimerExceeded {
theProfileManager = [[ProfileManager alloc] init];
theProfile = [theProfileManager getProfile];
if( ! [[theProfile getStatus]isEqualToString:@"u1"]) {
if( ! [[theProfile getTheUser] isUnlimitedLogin]) {
theProfile = nil;
theUserManager = [[UserManager alloc] init];
[theUserManager setCurrentUser:[theProfile getTheUser]];
[theUserManager setCurrentUserAccount:[[theProfile getTheUser] getTheUserAccount]];
[theUserManager setCurrentUserSettings:[[theProfile getTheUser] getTheUserSettings]];
[theUserManager logoutCurrentUser];
[[MenuItemDataManager alloc] deleteJsonData];
NSNotification *msg = [NSNotification notificationWithName:@"leftPanelMsg" object:[[NSString alloc] initWithFormat:@"Home"]];
[[NSNotificationCenter defaultCenter] postNotification:msg];
[self performSelector:@selector(loadHomeView:) withObject:nil afterDelay:0.5f];
}
}
[self resetIdleTimer];
}
The checkIfIdleTimerExceeded
does the log out process.
Problem: After 15 minutes I touch the screen, the resetIdleTime
is called and should restart a new NSTimer
. But after 15 minutes the application logs the user out.
Thanks for your help.
André.
Upvotes: 0
Views: 518
Reputation: 24041
I'm not sure which one of your other methods can be called beside the –resetIdleTimer
in your workflow when you touch the screen, but that solution works to me as you have described to like getting it worked:
I'm seeing in the log console the –resetTimer:
will called if I tap a button within 7 secs, it resets the timer properly and creates a new 7 secs timer.
the logout method will call only if I don't touch my button on the screen in 7 secs time, and the timer finally invokes the –logout:
method.
- (void)resetTimer:(NSTimer *)timer {
NSLog(@"reset time...");
if (timer.isValid) [timer invalidate], _timer = nil;
_timer = [NSTimer scheduledTimerWithTimeInterval:7.f target:self selector:@selector(logout:) userInfo:nil repeats:NO];
}
//
- (void)buttonTouchedUpInside:(UIButton *)sender {
NSLog(@"touched...");
[self resetTimer:_timer];
}
//
- (void)logout:(NSTimer *)timer {
NSLog(@"logout...");
if (timer.isValid) [timer invalidate], _timer = nil;
// logout ...
}
Upvotes: 0
Reputation: 2189
As per your requirement of the Touches event. You should do this:
NSSet *allTouchEvents = [event allTouches];
if ([allTouchEvents count] > 0) {
// allTouchEvents count only ever seems to be 1, so anyObject works here.
UITouchPhase phase = ((UITouch *)[allTouchEvents anyObject]).phase;
if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
[self resetIdleTimer];
}
And in the resetIdleTimer, The
self.idleTimer = [NSTimer scheduledTimerWithTimeInterval:maxTime target:self selector:@selector(checkIfIdleTimerExceeded) userInfo:nil repeats:NO];
should be like
self.idleTimer = [NSTimer scheduledTimerWithTimeInterval:maxTime target:self selector:@selector(checkIfIdleTimerExceeded:) userInfo:nil repeats:NO];
And checkIfIdleTimerExceeded
should be like:
-(void) checkIfIdleTimerExceeded :(NSTimer*)timer
{
//Do your all process and invalidate after completion
[timer invalidate];
}
Upvotes: 1