Re: How to correctly load the bundle of a screen saver (was: How to change the product name with command line builds?)
Re: How to correctly load the bundle of a screen saver (was: How to change the product name with command line builds?)
- Subject: Re: How to correctly load the bundle of a screen saver (was: How to change the product name with command line builds?)
- From: Ken Thomases <email@hidden>
- Date: Mon, 17 Jan 2011 13:33:16 -0600
On Jan 17, 2011, at 12:06 PM, Gabriel Zachmann wrote:
>> On Jan 16, 2011, at 7:59 AM, Ken Thomases wrote:
>
>> xcodebuild -target Foo -configuration Release build PRODUCT_NAME=Foo2
>
> Thanks a lot for your response.
You're welcome.
> The executable I am working on is a screen saver.
> My Info.plist looks like this:
>
> <key>CFBundleName</key>
> <string>${PRODUCT_NAME}</string>
> <key>CFBundleExecutable</key>
> <string>${EXECUTABLE_NAME}</string>
> <key>CFBundleIdentifier</key>
> <string>de.zach.${PRODUCT_NAME:rfc1034identifier}</string>
>
> In the final packages, the variables are correctly replaced by the correct executable names, i.e., "Foo" and "Foo2".
>
> However, when I run the screen savers (in System Preferences), the name of my screen saver, i.e., the value of CFBundleName is the same, whichever screen saver I use. It happens to be the one of the screen saver that got started first in SystemPreferences.
I think that System Preferences, since it's loading plug-ins, requires that your classes have unique names. Otherwise, when it loads the plug-ins, the names conflict in the Objective-C runtime.
The CFBundleName is not really the same. It's just that the second screen saver loaded isn't really loaded. It's finding the classes of the first one.
> Here is how I load the bundle and determine the name of the screen saver running:
>
> NSBundle * bundle = [NSBundle bundleForClass:[self class]];
Yeah, again, you would need to unique-ify the class names for this to work.
> exec_name_ = [[bundle infoDictionary] objectForKey:@"CFBundleName"];
>
> I tried
> NSBundle * bundle = [NSBundle mainBundle];
> but that loads the bundle of SystemPreferences!
That's expected.
> I was considering to use [NSBundle bundleWithIdentifier: @"de.zach.Foo"] but I can't hard-code the identifier, since I don't know which screensaver it will be.
>
> Is there something like preprocessor macro expansion in Obj-C? Something like
>
> @"de.zach." ## PRODUCT_NAME
> (that is C++ syntax, where PRODUCT_NAME is a preprocessor token, which can be set on the command line of gcc).
>
> Does anyone know how to do this properly?
You can configure the Preprocessor Macro Definitions build setting and base some of its values on other build settings. That can effectively "import" build settings into the source. By the way, the correct C syntax would be:
@"de.zach." #PRODUCT_NAME
That is, you don't want token pasting, you want stringifying (and rely on the fact that C concatenates adjacent string literals). You _would_ want token pasting if you were to incorporate a macro into a class name.
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden