Tutorial: Write a MobileSubstrate plugin to kill SpringBoard's watchdog timer

Even if you override the UIApplication methods to allow your application to run in the background after the home key is pressed, the SpringBoard starts a watchdog timer and kills your application if it is still running after 10 seconds. It only does this for applications deployed to the SDK folder, not ones in /Applications but it still is annoying none the less, because I prefer deploying with Xcode - it's just faster.

The solution to this problem is to create a MobileSubstrate plugin that modifes the SpringBoard by disabling the method that starts the watchdog.

Tweak.mm
#include <substrate.h>
 
@class SBApplication;
 
static void $SBApplication$_startTerminationWatchdogTimer(SBApplication *self, SEL sel)
{
}
 
extern "C" void TweakInitialize() {
    NSLog(@"Watchdog killer is starting up...");
    Class $SBApplication(objc_getClass("SBApplication"));
    MSHookMessage($SBApplication, @selector(_startTerminationWatchdogTimer), (IMP)&$SBApplication$_startTerminationWatchdogTimer, "watchdogkiller_");
    NSLog(@"Watchdog killer has been initialized.");
}
The rest of the code below is for the application you want to work in the background.
BackgroundApp.h
@interface BackgroundApp : UIApplication {
 
}
 
@end
 
BackgroundApp.m
#import "BackgroundApp.h"
 
@implementation BackgroundApp
 
 
- (void)applicationWillSuspend{
 
}
 
- (void)applicationDidResume{
 
}
- (void)applicationWillResignActive:(UIApplication *)application{
 
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
 
}
- (void)applicationSuspend:(id)event{
 
}
 
@end
Then last thing you need is to make the UIApplicationMain start up your own subclass of UIApplication.
#import <UIKit/UIKit.h>
#import "BackgroundApp.h"
 
int main(int argc, char *argv[]) {
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, @"BackgroundApp", nil);
    [pool release];
    return retVal;
}