Log out depending on user activity
I have been looking for this answer from a while but I could not get find solution. Can any one please tell me how do we calculate time in back ground since user made any interaction with the app. In few websites if you don't interact with the web page for a while you will be logged out. I am looking for开发者_开发问答 this functionality.
I would really appreciate your time. Thanks
I think you can catch events via a UIApplication custom subclass. You can restart your idle timer there without mucking up all of your code. Here's how to do it:
Make your own UIApplication subclass:
@interface MyUIApplication : UIApplication {
NSTimer *idleTimer;
}
@property(nonatomic,retain) NSTimer *idleTimer;
In your main()
int retVal = UIApplicationMain(argc, argv, @"MyUIApplication", nil);
In your application subclass.m, override sendEvent: and sendAction:. See Apple docs here:
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
[self. idleTimer invalidate];
self. idleTimer = [NSTimer scheduledTimerWithTimeInterval:kIDLE_TIME target:self selector:@selector(logout:) userInfo:nil repeats:NO];}
... same for send action. You can put your logout logic in this class, too:
- (void)logout:(NSTimer *)timer {
// do logout
}
You should still logout (and invalidate the timer) in your app delegate when the app resigns:
- (void)applicationWillResignActive:(UIApplication *)application {
[application logout:nil];
}
You save a UNIX timestamp of the last interaction and then you compare it to a current one. If the difference between them is greater than your time limit, you log user out.
I would log the time when - (void)applicationWillEnterForeground:(UIApplication *)application
, and when - (void)applicationWillEnterBackground:(UIApplication *)application
, calculate the different, check if it exceed certain value, log off user from previous session.
// Extend method of UIApplication
- (void)sendEvent:(UIEvent *)event {
[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:NO];
}
}
}
- (void) resetIdleTimer:(BOOL)force {
// Don't bother resetting timer unless it's been at least 5 seconds since the last reset.
// But we need to force a reset if the maxIdleTime value has been changed.
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (force || (now - lastTimerReset) > 5.0) {
// DebugLog(@"Reset idle timeout with value %f.", maxIdleTime);
lastTimerReset = now;
// Assume any time value less than one second is zero which means disable the timer.
// Handle values > one second.
if (maxIdleTime > 1.0) {
// If no timer yet, create one
if (idleTimer == nil) {
// Create a new timer and retain it.
idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimeExceeded) userInfo:nil repeats:NO] retain];
}
// Otherwise reset the existing timer's "fire date".
else {
[idleTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:maxIdleTime]];
}
}
// If maxIdleTime is zero (or < 1 second), disable any active timer.
else {
if (idleTimer) {
[idleTimer invalidate];
[idleTimer release];
idleTimer = nil;
}
}
}
}
- (void) idleTimeExceeded {
NSLog(@"Idle time limit of %f seconds exceeded -- ending application", maxIdleTime);
// Force application to end
// self.dealloc; -- There's a dealloc in StartProcessViewController.m, but I'm not sure we ought to dealloc the UIApplication object.
_Exit(0);
}
One way to archive this is setting a cookie with a login hash that has an expire time of X minutes every time the user request a page. If the cookie isn't present the user is logged out. This could also be a session cookie. Of course that only works if you're talking about a webapp :)
精彩评论