Feeds

String theory and the OS X AppKit

Colorful language

Combat fraud and increase customer satisfaction

Mac Secrets Much of the time, we're off exploring some framework such as GraphKit or the media browser. This time it's the turn of AppKit itself, the framework that's guaranteed to be used by every self-respecting Cocoa app. Strange as it may seem, there are plenty of undocumented goodies here, too.

Let's start with localization, This is the process whereby you build a Cocoa application in such a way that it will display any needed text strings in the default language set by the user. Ordinarily, this is done through judicious use of macros such as NSLocalizedString, the various foreign language strings being located inside the appropriate ".lproj" directory.

However, for those who are lazy and like to live dangerously AppKit provides a routine which provides effort-free localization, provided that the string you want to localize is one of the ones provided. First, you need to define the routine, _NXKitString, like this:

extern NSString * _NXKitString (NSString * tableName, NSString * keyName);

Because _NXKitString (note the underscore) is part of AppKit, there's no need to link with any other libraries or frameworks. The routine takes two parameters, the name of a string table, and an identifying key within the table. It returns an autoreleased string, localized for the current language. You'd use it like this:

NSString * cancelString = _NXKitString (@"Preferences", @"Cancel");

Thus, you'll get back "Cancel" where English is the default, "Annuler" in French, and so on. Of course, this will only work as long as the string you want is contained in one of AppKit's internal string tables. To see what's there, navigate to the following location:

/System/Library/Frameworks/AppKit.framework/Versions/C/Resources/

From there, you can navigate into the English.lproj directory, for example, where you'll see a list of string table files, all of which have the suffix "strings". These represent the allowable table names that you pass to _NXKitString. So, "Preferences" maps to Preferences.strings and so on.

If you examine the contents of each string table file - they're just plain-vanilla text files - you'll see the available keys for each table.

If your application has a very simple, restricted interface, you may be able to get by with just the available strings. It would be nice if "Yes" and "No" were included somewhere, but I haven't found them yet. One particularly useful table is "FunctionKeyNames". Here, you'll find many keystroke reference strings.

App Kit Calls

The _NXKitString mechanism is used widely in AppKit when displaying localized strings

Color Conversions are a hot topic and an oft-repeated plea amongst novice Cocoa developers is a way of converting from an NSColor to a CGColorRef. At least, if you Google for it, you'll see this question popping up everywhere.

It turns out that converting an NSColor object to the equivalent CGColorRef is deliciously simple - if you're in the know. I found an internal AppKit routine that pretty much does this job for you. Unfortunately, you can't call it directly from Cocoa-land because it's not a public symbol exported by the AppKit framework. However, what the routine does is very straightforward: it works by calling an undocumented method on the NSColor class.

If you were to come up with an equivalent routine of your own, it might look something like this:

CGColorRef CGColorFromNSColor (NSColor * color)
{
        CGColorRef result = nil;
        if ([color respondsToSelector: @selector (_createCGColorWithAlpha:)])           result = [color _createCGColorWithAlpha: [color alphaComponent]];
        return result;
}

As you can see, this code is very straightforward: we just check the presence of the undocumented selector, returning nil if the passed-in NSColor instance doesn't respond to it. In order to prevent the compiler from generating warnings, you'll also need to convince it that NSColor responds to the undocumented selector, providing an interface declaration like this:

@interface NSColor()
- (CGColorRef) _createCGColorWithAlpha: (float) alpha;
@end

You might wonder why the respondsToSelector: check is necessary? Well, for starters, it's wise to build such checks into your code when using undocumented routines. Also, it just so happens that NSColor is an example of a class cluster. In case you're unfamiliar with this term, a class cluster is a group of inter-related private classes, all of which descend from a public abstract class, in this case, NSColor.

Other examples of class clusters include NSArray, NSData and NSString. It might surprise you to know that NSColor is an abstract class, but in a real sense it is. For example:

[NSColor blueColor];                    // returns NSCachedRGBColor
[NSColor _blueControlTintColor];                // returns NSCachedDeviceRGBColor
[NSColor toolTipColor]                  // returns NSDynamicSystemColor

The point here is that all the class names mentioned on the right are descendants of NSColor; you will get different descendant classes returned to you depending on what type of color you request.

NSColor does not, itself, implement _createCGColorWithAlpha: which is one of the reasons it's, in effect, an abstract class. As far as I can see, all the descendant classes do implement it - but please don't quote me! ®

High performance access to file storage

More from The Register

next story
Android engineer: We DIDN'T copy Apple OR follow Samsung's orders
Veep testifies for Samsung during Apple patent trial
This time it's 'Personal': new Office 365 sub covers just two devices
Redmond also brings Office into Google's back yard
Batten down the hatches, Ubuntu 14.04 LTS due in TWO DAYS
Admins dab straining server brows in advance of Trusty Tahr's long-term support landing
Microsoft lobs pre-release Windows Phone 8.1 at devs who dare
App makers can load it before anyone else, but if they do they're stuck with it
Half of Twitter's 'active users' are SILENT STALKERS
Nearly 50% have NEVER tweeted a word
Windows XP still has 27 per cent market share on its deathbed
Windows 7 making some gains on XP Death Day
Internet-of-stuff startup dumps NoSQL for ... SQL?
NoSQL taste great at first but lacks proper nutrients, says startup cloud whiz
Windows 8.1, which you probably haven't upgraded to yet, ALREADY OBSOLETE
Pre-Update versions of new Windows version will no longer support patches
Microsoft TIER SMEAR changes app prices whether devs ask or not
Some go up, some go down, Redmond goes silent
Red Hat to ship RHEL 7 release candidate with a taste of container tech
Grab 'near-final' version of next Enterprise Linux next week
prev story

Whitepapers

Designing a defence for mobile apps
In this whitepaper learn the various considerations for defending mobile applications; from the mobile application architecture itself to the myriad testing technologies needed to properly assess mobile applications risk.
3 Big data security analytics techniques
Applying these Big Data security analytics techniques can help you make your business safer by detecting attacks early, before significant damage is done.
Five 3D headsets to be won!
We were so impressed by the Durovis Dive headset we’ve asked the company to give some away to Reg readers.
The benefits of software based PBX
Why you should break free from your proprietary PBX and how to leverage your existing server hardware.
Securing web applications made simple and scalable
In this whitepaper learn how automated security testing can provide a simple and scalable way to protect your web applications.