I'm (like all others) using
NSLocalizedString(@"Abort", @"Cancel action")
NSLocalizedString(@"Cancel", @"Cancel action")
// In strings.h
#define NSLS_COMMON_CANCEL NSLocalizedString(@"Cancel", nil)
// Somewhere else
NSLocalizedString has a few limitations, but it is so central to Cocoa that it's unreasonable to write custom code to handle localization, meaning you will have to use it. That said, a little tooling can help, here is how I proceed:
genstrings overwrites your string files, discarding all your previous translations.
I wrote update_strings.py to parse the old strings file, run
genstrings and fill in the blanks so that you don't have to manually restore your existing translations.
The script tries to match the existing string files as closely as possible to avoid having too big a diff when updating them.
If you use
NSLocalizedString as advertised:
NSLocalizedString(@"Cancel or continue?", @"Cancel notice message when a download takes too long to proceed");
You may end up defining the same string in another part of your code, which may conflict as the same english term may have different meaning in different contexts (
Cancel come to mind).
That is why I always use a meaningless all-caps string with a module-specific prefix, and a very precise description:
NSLocalizedString(@"DOWNLOAD_CANCEL_OR_CONTINUE", @"Cancel notice window title when a download takes too long to proceed");
If you use the same string multiple times, you can either use a macro as you did, or cache it as an instance variable in your view controller or your data source. This way you won't have to repeat the description which may get stale and get inconsistent among instances of the same localization, which is always confusing. As instance variables are symbols, you will be able to use auto-completion on these most common translations, and use "manual" strings for the specific ones, which would only occur once anyway.
I hope you'll be more productive with Cocoa localization with these tips!