I\'m building a daemon app for a jailbroken iPhone and followed the guidelines as described in several questions and answers here on stackoverflow and ofcourse Chris Alvares\' w
As I said in my comment, first try to make sure your daemon executable is runnable:
root
, via ssh
/Applications/NoUIDameon.app/NoUIDaemon
at the command lineps -Aef | grep NoUIDaemon
If it's not running, I would check to make sure that your build process is fake code-signing the NoUIDaemon
executable. Jailbroken phones don't require a valid signature, but they still do require a signature. Also, if it doesn't run (or stay running), it might help for you to post the code from your daemon's main program (e.g. main.m):
int main(int argc, char *argv[]) {
// what's in here?
}
If that does work, and it runs when you start it manually (but not automatically), then check:
dmn.NoUIDaemon.plist
?Label
value in your plist should be <string>dmn.NoUIDaemon</string>
, not <string>dmn.NoUIDaemon.plist</string>
. I don't think this would prevent your daemon from running, I think it's just being consistent with the naming convention of system launch daemons./System/Library/LaunchDaemons
is enough to start the daemon. You probably need to either reboot the phone, or manually launch the daemon with launchctl load -w /System/Library/LaunchDaemons/dmn.NoUIDaemon.plist
/System/Library/LaunchDaemons
. Label
and the name of the plist file) are supposed to match the bundle ID specified in your NoUIDaemon-Info.plist file. So, the Info.plist should have: <key>CFBundleExecutable</key>
<string>NoUIDaemon</string>
<key>CFBundleIdentifier</key>
<string>dmn.${PRODUCT_NAME:rfc1034identifier}</string>
or
<key>CFBundleExecutable</key>
<string>NoUIDaemon</string>
<key>CFBundleIdentifier</key>
<string>dmn.NoUIDaemon</string>
Update:
Also, I don't think your daemon's main program should have a call to UIApplicationMain
. It's not supposed to be a UIApplication. It's supposed to be a background process, right? If you look on Page 1 of Chris's blog, it shows an example. Here's an example from one of mine:
int main(int argc, char *argv[]) {
@autoreleasepool {
SignalMonitor* daemon = [[SignalMonitor alloc] init];
// start a timer so that the process does not exit.
NSTimer* timer = [[NSTimer alloc] initWithFireDate: [NSDate date]
interval: 1.0
target: daemon
selector: @selector(setup:)
userInfo: nil
repeats: NO];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer: timer forMode: NSDefaultRunLoopMode];
[runLoop run];
}
return 0;
}
Also, here's a copy of my daemon's plist file (Info.plist), with your daemon name in it:
<?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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>NoUIDaemon</string>
<key>CFBundleIdentifier</key>
<string>dmn.NoUIDaemon</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0-0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSApplicationCategoryType</key>
<string></string>
</dict>
</plist>