There are times where our app may crash from a bug or who knows why 🙂
One of the aditions that we would like to add is a launchd plist that allows the app to restart in the event of a crash or whenever it is closed incorrectly,
So far this is what I have for the launchd file creation and usage.
- (void)installMainAppResourceIfNeeded:(NSString *)resourceIdentifier asRoot:(BOOL)asRoot {
NSString *resourceName = [resourceIdentifier pathExtension];
NSDictionary *launchAgentPlist = [NSDictionary dictionaryWithObjectsAndKeys:
resourceIdentifier, @"Label",
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:TRUE], @"AfterInitialDemand", [NSNumber numberWithBool:TRUE], @"Crashed", [NSNumber numberWithBool:FALSE], @"SuccessfulExit", nil],
@"KeepAlive",@"Aqua",@"LimitLoadToSessionType",
[NSArray arrayWithObjects:
@"open",@"-W",@"/Applications/myapp.app", nil], @"ProgramArguments",
nil];
NSString *tempPlistPath = [@"/tmp/XXXXXX" stringByGeneratingTempPath];
NSString *plistDestinationPath;
if (!asRoot) {
plistDestinationPath = [self installPathForResourcePlist:resourceIdentifier asRoot:asRoot];
} else {
plistDestinationPath = [self installPathForRootResourcePlist:resourceIdentifier];
}
[launchAgentPlist writeToFile:tempPlistPath atomically:NO];
NSFileManager *fm = [NSFileManager defaultManager];
if (
[fm contentsEqualAtPath:tempPlistPath andPath:plistDestinationPath]) {
[fm removeItemAtPath:tempPlistPath error:NULL];
if (![self isDaemonLoaded:resourceIdentifier]) {
[self startDaemonForIdentifier:resourceIdentifier asRoot:asRoot];
}
return;
}
[fm removeItemAtPath:tempPlistPath error:NULL];
[self stopDaemonForIdentifier:resourceIdentifier asRoot:asRoot];
[launchAgentPlist writeToFile:plistDestinationPath atomically:NO];
[self startDaemonForIdentifier:resourceIdentifier asRoot:asRoot];
}
This results in a plist in users Library LaunchAgents folder that looks like this
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<dict>
<key>AfterInitialDemand</key>
<true/>
<key>Crashed</key>
<true/>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>Label</key>
<string>com.mycompany.myapp</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>ProgramArguments</key>
<array>
<string>open</string>
<string>-W</string>
<string>/Applications/myapp.app</string>
</array>
</dict>
</plist>
We want the code to basically restart the app anytime there is a crash or its closed incorrectly.
Lets say this code is correct, how do I verify it ?
So far the only thing I tried is to run the following in the terminal
kill -SEGV PID#
This created a crash report but app does not restart.
Any input ?
Also does AfterInitialDemand need a BOOL statement like True or False ?