9

Let's say I need to give the user the ability to choose by a preferences panel whether to use the app as "standard" (with dock icon and menu) or as an agent app (with status bar menu only).

I think I need to programmatically modify the app's "Info.plist" during execution, changing the parameter "Application is agent" to YES/NO.

Is this the right way?

P.S. You can find this behavior in "Sparrow".

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
MatterGoal
  • 16,038
  • 19
  • 109
  • 186

1 Answers1

17

You should not modify your app's Info.plist file (or anything in your app's bundle) at runtime. This is bad practice and will also break your app if it is code signed. This is more important nowadays as all apps on the app store must be code signed.

A better option is to use the Application Services function TransformProcessType() to move your app from a background to a foreground app.

First, set the LSUIElement key in your app's Info.plist to YES and then check a user default at launch to determine if your app should be running as an agent or not:

#import <ApplicationServices/ApplicationServices.h>

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"LaunchAsAgentApp"]) 
    {
        ProcessSerialNumber psn = { 0, kCurrentProcess };
        TransformProcessType(&psn, kProcessTransformToForegroundApplication);
        SetFrontProcess(&psn);
    }
}

@end

Make sure you don't forget to add the Application Services framework to your project.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
  • Plus, changing the `Info.plist` will also fail with insufficient privileges and on read-only volumes (like disk images). – gcbrueckmann Aug 10 '11 at 06:47