Feeds

String theory and the OS X AppKit

Colorful language

The Power of One Brief: Top reasons to choose HP BladeSystem

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

Securing Web Applications Made Simple and Scalable

More from The Register

next story
Apple fanbois SCREAM as update BRICKS their Macbook Airs
Ragegasm spills over as firmware upgrade kills machines
HIDDEN packet sniffer spy tech in MILLIONS of iPhones, iPads – expert
Don't panic though – Apple's backdoor is not wide open to all, guru tells us
NO MORE ALL CAPS and other pleasures of Visual Studio 14
Unpicking a packed preview that breaks down ASP.NET
Captain Kirk sets phaser to SLAUGHTER after trying new Facebook app
William Shatner less-than-impressed by Zuck's celebrity-only app
Cheer up, Nokia fans. It can start making mobes again in 18 months
The real winner of the Nokia sale is *drumroll* ... Nokia
Mozilla fixes CRITICAL security holes in Firefox, urges v31 upgrade
Misc memory hazards 'could be exploited' - and guess what, one's a Javascript vuln
EU dons gloves, pokes Google's deals with Android mobe makers
El Reg cops a squint at investigatory letters
Chrome browser has been DRAINING PC batteries for YEARS
Google is only now fixing ancient, energy-sapping bug
prev story

Whitepapers

Designing a Defense for Mobile Applications
Learn about the various considerations for defending mobile applications - from the application architecture itself to the myriad testing technologies.
How modern custom applications can spur business growth
Learn how to create, deploy and manage custom applications without consuming or expanding the need for scarce, expensive IT resources.
Reducing security risks from open source software
Follow a few strategies and your organization can gain the full benefits of open source and the cloud without compromising the security of your applications.
Boost IT visibility and business value
How building a great service catalog relieves pressure points and demonstrates the value of IT service management.
Consolidation: the foundation for IT and business transformation
In this whitepaper learn how effective consolidation of IT and business resources can enable multiple, meaningful business benefits.