How to change NSApplication name on the fly?
|
|
Thread rating:  |
Glenn Reid - 22 Jul 2005 19:30 GMT Does anybody know a way to override the name that's baked into an application at runtime?
We have an OEM application that needs to have a different name for each OEM and it's almost impossible to manufacture it with different names using XCode, and I can't find a way to rename the app at runtime either. No matter what the name of the exeuctable *.app wrapper is, the name in the menus is pullled from NSBundle.
I've tried hacks like this in awakeFromNib in NSApplication, to no avail:
NSMenuItem *item = [[myApp mainMenu] itemAtIndex:0]; [item setTitle:@"Testing"];
Help!
Thanks, Glenn Reid
Michael Ash - 22 Jul 2005 20:18 GMT > Does anybody know a way to override the name that's baked into an > application at runtime? [quoted text clipped - 10 lines] > NSMenuItem *item = [[myApp mainMenu] itemAtIndex:0]; > [item setTitle:@"Testing"]; Nothing is "baked in" anywhere. The info you seek is stored in the Info.plist of your application.
Glenn Reid - 22 Jul 2005 20:29 GMT Thanks, Michael. Unfortunately, at runtime that's "baked in" because the app has already launched and read in the Info.plist. The key to this is to change it <b>at runtime</b> after the app has already launched, if possible. I don't think it is possible, unfortunately, which is odd. Why can't I change the menuItem at location 0, for example? It just fails silently.
Michael Ash - 22 Jul 2005 20:54 GMT > Thanks, Michael. Unfortunately, at runtime that's "baked in" because > the app has already launched and read in the Info.plist. The key to > this is to change it <b>at runtime</b> after the app has already > launched, if possible. I don't think it is possible, unfortunately, > which is odd. Why can't I change the menuItem at location 0, for > example? It just fails silently. You didn't say that you had to change it at runtime. You said that you had to change it for different OEM products, and your idea of the proper approach was to change it at runtime. But there's no reason to change it at runtime; just change your Info.plist to say the right thing when you make a build. It's not only the right thing to do, it's also easier. These different products should probably have different bundle identifiers anyway.
Glenn Reid - 22 Jul 2005 21:16 GMT I would prefer to change it at runtime, so that's the question I was asking. I know how to change Info.plist with a 'sed' script and make a whole bunch of nasty build machinery around mkbom but that is NOT an easier or better solution. Why do you say that it is the "right thing to do?" How would you propose automating the builds for, say, 10 OEM's such that when you make a code change you can do the build? I'd like to build one app and have it rename itself at runtime, rather than building 10 apps that are identical except for Info.plist.
Michael Ash - 22 Jul 2005 22:07 GMT > I would prefer to change it at runtime, so that's the question I was > asking. I know how to change Info.plist with a 'sed' script and make a > whole bunch of nasty build machinery around mkbom but that is NOT an > easier or better solution. It's fairly trivial to write a tool which reads in the plist using Apple's plist APIs, makes the change, and writes it back out again, if you think the sed method is ugly.
> Why do you say that it is the "right thing > to do?" A couple of reasons.
One, it means that the name of your app as seen from the outside (by whatever reads the Info.plist to figure out the name of the application, no doubt such things exist) will match the name of your app as seen from the inside.
Two, it goes with the system, instead of fighting it. The system is designed to make the application menu use the name found in the Info.plist. By changing the Info.plist, you use what the system has to offer instead of going against the grain.
Three, your apps ought to have different bundle identifiers, since they are actually different apps, meaning you need to change your Info.plist *anyway*. So while you're at it, you might as well change the name too.
> How would you propose automating the builds for, say, 10 OEM's > such that when you make a code change you can do the build? I'd like > to build one app and have it rename itself at runtime, rather than > building 10 apps that are identical except for Info.plist. How does the app figure out what to call itself? This seems like a rather odd objection. Your app must have something embedded in it somewhere that tells it how to rename itself, so this can't be an added burden.
In any case, I propose to automate the builds by adding a shell script phase to the end of your build process that takes the finished application, duplicates it, and runs your Info.plist modifier on each one. This is not exactly rocket science.
On the subject of doing the right thing, it's standard usenet etiquette to quote the message you're replying to. Not quoting the message makes it difficult to follow the discussion and can make things confusing.
Glenn Reid - 23 Jul 2005 00:09 GMT Thanks for the followup, Michael.
The burden is in having 10 copies of the application that differ only in the Info.plist settings. I'll figure something out.
It still seems as though the application ought to be able to set the menus/visible branding at run-time. If anybod knows how to do that, I'm still looking for that bit of information.
BTW, I'm using groups-beta.google.com to post/reply and it doesn't do the quoting.
Glenn
Uli Kusterer - 23 Jul 2005 09:37 GMT > The burden is in having 10 copies of the application that differ only > in the Info.plist settings. I'll figure something out. Well,
you have several options.
1) Create an installer that your OEMs use to put the app on their disk images (I presume that's how your app is shipped) and have that installer also change the plist.
2) If your app will be downloaded, use some of the available compression/decompression PHP code and write a download script that changes the Info.plist inside the downloaded archive.
3) If your OEM clients will just ship along your app, just write a shell script build phase that makes those 10 copies and mail them off. That's always better than if they get a generic app and happen to find a script file next to it confirming to them that you're also shipping to the competition. Make it look personalized and they won't be as likely to drop you if another programmer makes a similar piece of software.
> It still seems as though the application ought to be able to set the > menus/visible branding at run-time. If anybod knows how to do that, > I'm still looking for that bit of information. It's a Human Interface thing: Ideally, the application file name should correspond to the name in the menu (except if the user renamed it explicitly). That way, a user knows that the application file they just double-clicked really spawned the menus and windows they're now seeing. What you're trying to do will confuse users: <<I double-clicked "Bill's Disk Formatter" and suddenly the "LaCie Disk Formatter" program started? What gives?>>
> BTW, I'm using groups-beta.google.com to post/reply and it doesn't do > the quoting. You know, back in the day on CompuServe us old-time Internetters just copied the text from the old message and enclosed it in >> and << characters...
Cheers, -- Uli Kusterer http://www.zathras.de
Michael Ash - 23 Jul 2005 11:10 GMT > Thanks for the followup, Michael. > > The burden is in having 10 copies of the application that differ only > in the Info.plist settings. I'll figure something out. This is not exactly a hardship.
> It still seems as though the application ought to be able to set the > menus/visible branding at run-time. If anybod knows how to do that, > I'm still looking for that bit of information. It seems to me that an app ought not to be able to do this, because it's not a good thing for an app to do.
> BTW, I'm using groups-beta.google.com to post/reply and it doesn't do > the quoting. Yes it does. Instead of just clicking Reply, click "show options", then click Reply in the thing that appears there. Oh, and write to Google and complain, because not offering quoting through the most obvious Reply mechanism is criminal.
ward mcfarland - 23 Jul 2005 12:48 GMT > > Thanks for the followup, Michael. > > > > The burden is in having 10 copies of the application that differ only > > in the Info.plist settings. I'll figure something out. > > This is not exactly a hardship. I agree. But if the application name in the App Menu is to differ between versions, why should not also the name of the application bundle be unique to each version?
- w
Michael Ash - 23 Jul 2005 17:30 GMT >> > Thanks for the followup, Michael. >> > [quoted text clipped - 6 lines] > between versions, why should not also the name of the application bundle > be unique to each version? On the contrary, it should! This is why I can't understand the OP's reluctance; he has to change filenames and other names as well, so why not this?
Patrick Machielse - 22 Jul 2005 21:03 GMT > Thanks, Michael. Unfortunately, at runtime that's "baked in" because > the app has already launched and read in the Info.plist. The key to > this is to change it <b>at runtime</b> after the app has already > launched, if possible. I don't think it is possible, unfortunately, > which is odd. Why can't I change the menuItem at location 0, for > example? It just fails silently. You are trying to set the title of the Apple menu...
patrick
Glenn Reid - 22 Jul 2005 21:12 GMT But [itemAtIndex:1] gives the first menu to the right of the app menu. There doesn't seem to be a way to get the name of the app menu.
Patrick Machielse - 22 Jul 2005 21:22 GMT > > Thanks, Michael. Unfortunately, at runtime that's "baked in" because > > the app has already launched and read in the Info.plist. The key to [quoted text clipped - 4 lines] > > You are trying to set the title of the Apple menu... Or so I thought...
NSLog()@"%@", [[NSApp mainMenu] itemAtIndex:0]);
spits out:
<MenuItem: 0x34ae60 , submenu: 0x322370 (Apple)>
Which gave me the wrong impression. Sorry...
The (Apple) may mean: don't touch this. I tried [[item submenu] setTitle:] (not a bad idea) and eventually [NSApp setMenu:] to no avail. Even setting the title in the nib doesn't stick.
I'm out of ideas for now.
patrick
Glenn Reid - 22 Jul 2005 21:56 GMT Thanks, Patrick. I am about to conclude the same thing. It can't be done, which is a shame. I looked through NSBundle's mainBundle and bundleIdentifier and there's nothing that seems to do the trick in there either.
Not that many things are "impossible" in Cocoa; I think this may be one of them!
Ironically, in our Windows app, it's this simple:
this->setWindowText ( "New Name" );
Patrick Machielse - 23 Jul 2005 01:17 GMT > Thanks, Patrick. I am about to conclude the same thing. It can't be > done, which is a shame. I looked through NSBundle's mainBundle and [quoted text clipped - 7 lines] > > this->setWindowText ( "New Name" ); OK, here is the OS X solution:
The trick is to change the info keys _before_ your NSApplication instance is created. So we do it in main.m
< quick and dirty >
int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSBundle *mainBundle = [NSBundle mainBundle]; NSString *infoPath = [mainBundle pathForResource:@"InfoPlist" ofType:@"strings"]; NSMutableString *str; str = [NSMutableString stringWithContentsOfFile:infoPath]; [str replaceOccurrencesOfString:@"Old Name" withString:@"Brand X" options:NSLiteralSearch range:NSMakeRange(0, [str length])]; [str writeToFile:infoPath atomically:YES];
[pool release]; return NSApplicationMain(argc, (const char **) argv); }
Note that we manipulate the InfoPlist.strings file in the active localisation. If you know the new title in main() you can use this technique.
Bedtime...
patrick
Reinder Verlinde - 23 Jul 2005 08:04 GMT > > Thanks, Patrick. I am about to conclude the same thing. It can't be > > done, which is a shame. I looked through NSBundle's mainBundle and [quoted text clipped - 31 lines] > localisation. If you know the new title in main() you can use this > technique. Also note that this will not work if the current user does not have write permissions on the property list file. This is reasonably common, for instance in a scenario where an administrator installs the application and a non-administrator runs it.
I also think that, if you nevertheless go this route, you would want to compare the current string with the one you are going to write there, and not write out the file if they match.
Reinder
Patrick Machielse - 23 Jul 2005 10:40 GMT > > int main(int argc, char *argv[]) > > { [quoted text clipped - 24 lines] > for instance in a scenario where an administrator installs the > application and a non-administrator runs it. True. But maybe the administrator could run it once, maybe to activate / register the copy. Assuming the OP needs only one brand on each deployment site and that the administrator's account provides enough information to determine the correct app name...
> I also think that, if you nevertheless go this route, you would want to > compare the current string with the one you are going to write there, > and not write out the file if they match. Well, I did say 'quick and dirty', didn't I? Having slept on it, I think it is better to remove all app name keys from the localized InfoPlist.strings file(s) and instead add it to Info.plist. You can manipulate that file more robustly using NSDictionary.
This is a 'proof of concept'; there _is_ a way to change the displayed name of an application at runtime. I didn't claim it was elegant or without hazard :-)
patrick
Reinder Verlinde - 23 Jul 2005 11:27 GMT In a discussion on on-the-fly changing of the application name shown in the Apple menu ( "Glenn Reid" <gr@fiveacross.com>,article <1122057009.108014.70280@o13g2000cwo.googlegroups.com>), Patrick Machielse (in article <1h05h43.octyjh1bhf53mN%noreply@mail.invalid>) gave a way to do just that by changing the plist file in 'main' before calling 'NSApplicationMain'.
I replied:
> note that this will not work if the current user does not have > write permissions on the property list file. This is reasonably common, > for instance in a scenario where an administrator installs the > application and a non-administrator runs it. Patrick replied:
> True. But maybe the administrator could run it once, maybe to activate / > register the copy. Assuming the OP needs only one brand on each > deployment site and that the administrator's account provides enough > information to determine the correct app name... If one would go that route, the next step would be to have some way to enforce that the administrator ran the application. In that case, an installer would be the more logical route.
I also said:
> I also think that, if you nevertheless go this route, you would want to > compare the current string with the one you are going to write there, > and not write out the file if they match. To which Patrick replied:
> Well, I did say 'quick and dirty', didn't I? > [...] > This is a 'proof of concept'; there _is_ a way to change the displayed > name of an application at runtime. I didn't claim it was elegant or > without hazard :-) I understood that, but wanted to warn the original poster that this is not the route to take.
I still do not understand why Glenn Reid has so much aversion to distributing multiple applications. His original post said:
> We have an OEM application that needs to have a different name for each > OEM and it's almost impossible to manufacture it with different names > using XCode, and I can't find a way to rename the app at runtime > either. There are several solutions to this. The easiest (for his users) one is to ship multiple versions of the application (this might also provide other opportunities for adapting the application to different OEM's, for instance by providing an URL to the OEM's site in the about box, putting their logo in, or whatever)
This possibly also is easiest for the poster. Let us consider the alternative of an application that magically changes the apple menu title: - Glenn Reid builds an app that knows about all his OEM customers. - the application magically sets the name in the apple menu correctly - Glenn Reid distributes a perfect version 1.0 of this app to his clients.
At this stage, all is fine. Suppose that, some time later, Glenn Reid gets a new customer. What does he do? Release a new variant of version 1.0 that also knows about this client, or release version 1.01 just for this simple update? If he does the former, he has two different versions 1.0 out there. If he does the latter, he will find that existing users start hitting his web servers to download the 'new' version 1.01.
Reinder
Patrick Machielse - 23 Jul 2005 13:29 GMT > I still do not understand why Glenn Reid has so much aversion to > distributing multiple applications. His original post said: [quoted text clipped - 9 lines] > instance by providing an URL to the OEM's site in the about box, putting > their logo in, or whatever) I agree that this makes the most sense. However, if the difference is the app name only, I think it does complicate distribution. I suppose Glen has valid reasons to set the name at runtime. And why should it have to be so complicated?
Glenn: If you need this functionality, file a feature request with Apple. -[NSApplication setName:] isn't too much to ask for.
> This possibly also is easiest for the poster. Let us consider the > alternative of an application that magically changes the apple menu [quoted text clipped - 3 lines] > - Glenn Reid distributes a perfect version 1.0 of this app to his > clients. One alternative would be to retreive the app's name from the registration code. If the registration code also contains the customer name you don't have to update the binary for new clients.
patrick
Gregory Weston - 23 Jul 2005 15:58 GMT > > I still do not understand why Glenn Reid has so much aversion to > > distributing multiple applications. His original post said: [quoted text clipped - 14 lines] > Glen has valid reasons to set the name at runtime. And why should it > have to be so complicated? Perhaps because, as others have suggested, it's not the right way to do it? It's complicated because the OP is attempting to break some documented assumptions (assumption in this case being basically synonymous with requirement) made by the libraries.
G
 Signature Goal 2005: Convincing James Hetfield to cover the Strawberry Shortcake "Are You Berry Berry Happy?" song.
Patrick Machielse - 23 Jul 2005 17:08 GMT > > I agree that this makes the most sense. However, if the difference is > > the app name only, I think it does complicate distribution. I suppose [quoted text clipped - 6 lines] > documented assumptions (assumption in this case being basically > synonymous with requirement) made by the libraries. That is what I say: why does Apple make it so complicated (~impossible) to set the displayed app name at runtime?
Often when someone asks for a seemingly easy feature that turns out to be unavailable, he/she gets the reply: 'you shouldn't do it like this', 'Apple doesn't want you to do this'. What ever happened to 'the customer is always right'? If the OP has a genuine need to set the app's name at runtime, why wouldn't there be a way to do so?
patrick
Michael Ash - 23 Jul 2005 17:32 GMT >> > I agree that this makes the most sense. However, if the difference is >> > the app name only, I think it does complicate distribution. I suppose [quoted text clipped - 15 lines] > is always right'? If the OP has a genuine need to set the app's name at > runtime, why wouldn't there be a way to do so? Because he does not have such a genuine need.
An application's name should *never* change while it's running. And if you're going to change it before it runs, you may as well just change its Info.plist like you're supposed to, rather than attempt to change it at runtime.
"The programmer is always right" has never been a tenet of Mac programming. The system actively constricts and encourages programmers to create apps which fit in with the rest of the system, and this is one of the things that makes Mac OS X great.
Patrick Machielse - 23 Jul 2005 19:14 GMT > "The programmer is always right" has never been a tenet of Mac > programming. The system actively constricts and encourages programmers to > create apps which fit in with the rest of the system, and this is one of > the things that makes Mac OS X great. I agree that it is up to Apple to keep the API as lean and focussed as possible. Frivolous extensions should be frowned upon (but they have listend to sensible requests over the years). I like the mechanism in place for naming your app (although localized application names can be confusing). At the same time I find it surprising that there is _no_ API in place to set your apps name. (and why not honor a name set in the nib?) Personally, I would not object to having a programmatic override.
I don't know enough about Glenn's product to assess whether he truly needs this capability or not, but I'm open to the possibility that he might.
patrick
Gregory Weston - 23 Jul 2005 23:19 GMT > > > I agree that this makes the most sense. However, if the difference is > > > the app name only, I think it does complicate distribution. I suppose [quoted text clipped - 14 lines] > 'Apple doesn't want you to do this'. What ever happened to 'the customer > is always right'? What happened to "the customer is always right" is that it's a falsehood. I'd like my computer to cook dinner for me. I plan to achieve it by jamming a potato over the heat sink on the CPU and letting that cook it. Why has Apple made it so difficult for me by not providing enough room in the case?
> If the OP has a genuine need to set the app's name at > runtime, why wouldn't there be a way to do so? Certainly there's a way. It's all software. The question is why isn't it easy, and the answer is that the behavior is not supported and no library vendor is under any obligation to simplify a task they don't support. Part of the reason that you're seeing responses along the lines of "you shouldn't do it like this" is that there are much more robust and supported means to achieve the result the OP actually wants. The OP apparently has decided that those techniques "difficult" and is subsequently willing to go to a great deal of effort to avoid using them.
Now think about that last sentence a bit.
 Signature Goal 2005: Convincing James Hetfield to cover the Strawberry Shortcake "Are You Berry Berry Happy?" song.
Glenn Reid - 27 Jul 2005 02:00 GMT I think it's amazing--and funny--how many arguments there are about whether the "OP" (that's me) should or should not be doing this. I just asked "how" to do it.
I've been building commercial software longer than all of the rest of you put together. I built major Mac applications in 1985. I built major NeXTSTEP applications in 1991. I built major Cocoa applications in 1998-2003. I know what I'm doing, thank you very much.
So please knock of the crap about whether or not I have a justifiable reason to want to change the name of the NSApplication at runtime. I might, or I might not. I was, again, asking simply "how".
And while I'm at it, was posting to Usenet before most of you were in high school, too, back in 1983 when it was all driven through UUCP, so I'm familiar with the etiiquette. Good etiquette generally avoids using words like "not exactly rocket science" or "not exactly a hardship" when you know nothing about the poster, or his requirements.
So anyway, Patrick Machielse is my new personal hero because he tried valiantly, more than once, to answer my actual question. I think I can make your solution work, Patrick, where you change the name before NSApplication is instantiated. Good idea. There's no real need to write the name back to the file, and in fact there are reasons that might not be a good idea anyway.
Thanks for all of your help, to those [few] of you who actually did help. Especially Patrick, who wrote some code and tried some stuff on my behalf. I owe you.
Glenn Reid
Ben Artin - 27 Jul 2005 07:15 GMT > I've been building commercial software longer than all of the rest of > you put together. I built major Mac applications in 1985. I built > major NeXTSTEP applications in 1991. I built major Cocoa applications > in 1998-2003. I know what I'm doing, thank you very much. That doesn't make you infallible; contrariwise, your insistence that, with all that experience, you want to produce an application whose name as displayed in the Finder substantially differs from its name as displayed in its Application menu just tells us that you still have important things to learn. (And I don't mean that as an insult. We all do.)
Ben
 Signature If this message helped you, consider buying an item from my wish list: <http://artins.org/ben/wishlist>
I changed my name: <http://periodic-kingdom.org/People/NameChange.php>
Michael Ash - 27 Jul 2005 11:16 GMT > I think it's amazing--and funny--how many arguments there are about > whether the "OP" (that's me) should or should not be doing this. I [quoted text clipped - 14 lines] > using words like "not exactly rocket science" or "not exactly a > hardship" when you know nothing about the poster, or his requirements. Funny how you can have two decades of Usenet experience and yet still expect everybody else on usenet to act like mindless robots or a paid tech support line.
My usenet experience only goes back about one decade, but I know full well that my chances of getting a single, straightforward answer to a question are fairly low.
And whose fault is it, exactly, that we don't know anything about your requirements?
Oh well, I guess people who whine about how much they know and please just shut up and answer the question are part of the usenet experience too.
Sherm Pendley - 27 Jul 2005 14:38 GMT > And while I'm at it, was posting to Usenet before most of you were in > high school, too, back in 1983 when it was all driven through UUCP Well then gramps, here's a term you're surely familiar with:
*PLONK*
sherm--
 Signature Cocoa programming in Perl: http://camelbones.sourceforge.net Hire me! My resume: http://www.dot-app.org
Jhnny Fvrt (it means "Refrigerate After Opening") - 27 Jul 2005 19:54 GMT > Well then gramps, here's a term you're surely familiar with: > > *PLONK* oh man! i wrote out one of those, too! but i'm trying to be nice these days, so i discarded the message and just plonked him silently.
now i'll try to put a positive spin on this: it's good to let people know when their behavior is having negative consequences for themselves, right? so here's the sound of a dozen killfiles growing by one entry, to discourage that kind of snotty behavior in the future.
Eric Albert - 24 Jul 2005 02:42 GMT > This is a 'proof of concept'; there _is_ a way to change the displayed > name of an application at runtime. I didn't claim it was elegant or > without hazard :-) Well, there are many ways. You could, for example, create a window over the part of the menu bar where the application name appears, copy the menu bar's pattern into it, then draw your new name in there. And creatively handle events on the window to pass them through to the menu bar. Piece of cake.
:) -Eric
 Signature Eric Albert ejalbert@cs.stanford.edu http://outofcheese.org/
|
|
|