- (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];
- (void)resetIdleTimer {
    if (idleTimer) {
        [idleTimer invalidate];
        [idleTimer release];
    idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] retain];
- (void)idleTimerExceeded {
    NSLog(@"idle time exceeded");

where maxIdleTime and idleTimer are instance variables.

In order for this to work, you also need to modify your main.m to tell UIApplicationMain to use your delegate class (in this example, AppDelegate) as the principal class:

int retVal = UIApplicationMain(argc, argv, @"AppDelegate", @"AppDelegate");