Feeds

String theory and the OS X AppKit

Colorful language

Next gen security for virtualised datacentres

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! ®

Build a business case: developing custom apps

More from The Register

next story
Why has the web gone to hell? Market chaos and HUMAN NATURE
Tim Berners-Lee isn't happy, but we should be
Microsoft boots 1,500 dodgy apps from the Windows Store
DEVELOPERS! DEVELOPERS! DEVELOPERS! Naughty, misleading developers!
Mozilla's 'Tiles' ads debut in new Firefox nightlies
You can try turning them off and on again
'Stop dissing Google or quit': OK, I quit, says Code Club co-founder
And now a message from our sponsors: 'STFU or else'
Apple promises to lift Curse of the Drained iPhone 5 Battery
Have you tried turning it off and...? Never mind, here's a replacement
Uber, Lyft and cutting corners: The true face of the Sharing Economy
Casual labour and tired ideas = not really web-tastic
Linux turns 23 and Linus Torvalds celebrates as only he can
No, not with swearing, but by controlling the release cycle
prev story

Whitepapers

Gartner critical capabilities for enterprise endpoint backup
Learn why inSync received the highest overall rating from Druva and is the top choice for the mobile workforce.
Implementing global e-invoicing with guaranteed legal certainty
Explaining the role local tax compliance plays in successful supply chain management and e-business and how leading global brands are addressing this.
Rethinking backup and recovery in the modern data center
Combining intelligence, operational analytics, and automation to enable efficient, data-driven IT organizations using the HP ABR approach.
Consolidation: The Foundation for IT Business Transformation
In this whitepaper learn how effective consolidation of IT and business resources can enable multiple, meaningful business benefits.
Next gen security for virtualised datacentres
Legacy security solutions are inefficient due to the architectural differences between physical and virtual environments.