The Beauty of Code

Programming itself provides opportunities for self-expression.

In the midst of chaos and strife, when I need to take a break from the “real world”, I most often find my escape in source code, programming anything really. Of course, having more projects than I could hope to finish, and clients providing additional work to boot, means that I always have a ready avenue for directing my focus. However, it is not solely about the product, nor the money; it is also about the pleasure and enjoyment of coding itself.

There are a number of fairly passive experiences that I (and I imagine most of us) use to pass the time: playing games, reading books, watching television or movies. There are also more productive activities such as exercise (I quite enjoy hiking, bicycling, and swimming), house cleaning and organization, home improvement, and “gardening” (of a sort). None of these activities, however, provides the same creative outlet as programming.

When it comes to creative expression, appropriately, there are lots of different ways that people find to fulfill that need, which is important to our being. I know lots of people who like to sketch or doodle, or to write (for which I have gained some appreciation over the years), and others participate in higher commitment activities such as making stuffed animals, woodworking, or designing jewelry. When I was younger, I turned to more “design” oriented expression, such as creating original mazes, designing pinball machines, and architecting dream houses; at one time I designed a complete go-kart business, including the tracks and buildings.

The beauty of code is that it allows for self-expression within a systematic framework. I have always enjoyed numbers, logic, and the rational, and these all factor into programming. Within the rules, though, there are essentially infinite ways to express an idea, both in terms of method and of presentation. Of course, there are demonstrably “wrong” ways to do things, such as code that does not compile, fails to work, or crashes, but there are many levels of “right” ways to accomplish things, including how to efficiently increase functionality, how to handle errors and unexpected situations, and (importantly) how to make the source code understandable.

When I was required to attend an “advanced” BASIC course in high school, having already programmed for years (but with no formal education to show it took vociferous insistence just to avoid the “beginner” class), one of the first problems we were presented was to take a three-digit number as input and reverse the digits. I was the very first person to complete the task, twice. My second version was the anticipated method of accepting numerical input, with constraints placed on the operator (not the program) to limit the input to 3 digits, separating the number into ones, tens, and hundreds places, and printing them in reverse order, just to prove that I knew how to do it that way. My first version accepted the input as a string and printed the characters in reverse order, which worked on the specified input type, but also on numbers of arbitrary size, or any characters that could be input.

Around that time, I also set myself a challenge to create an “unbreakable” game, which I was able to accomplish with a high degree of confidence. To be unbreakable, the program had to be bulletproof, once executed, such that nobody could deliberately nor accidentally get to the prompt (and, hence, have access to the source code). This meant that the program needed to have no syntax errors (BASIC was interpreted code, rather than compiled, so such errors would only be found when executed), no logic or constraint errors that would allow a crash (such as selecting an unexpected/illogical action or overloading an input buffer), and also disallow breaking (via ^C), which was accomplished via system-specific methods. The only ways to end the program were turning off the power or hitting the reset button.

Programming has a lot in common with the scientific method. Although you use known logic to devise provably correct solutions, rather than testing hypotheses, you still test to confirm your approach and resolve errors, whether they be in your understanding of the problem, your design of a potential solution, or your execution of the plan. In fact, I constantly use this approach when building a program to regularly test my assumptions. I will make an interim change and state (to myself) the expected failure outcome, whether that be a compiler error (or specific number of compilation errors) or some weird behavior, just to confirm my understanding. If some code compiles unexpectedly, or the behavior is not as anticipated, I revisit the problem and make sure than I can explain why things went differently.

This shows yet another beautiful aspect of programming: its digital nature makes it precise and enables, at least ostensibly, the pursuit of perfection. You can experiment with something new with confidence that, if it does not work out, you can return to exactly the original situation. It does not matter how far out in the weeds I get with an idea; I can always get back to where I started. (Try that with oil painting.😉) Also, as my first computer book helpfully pointed out at the start of my career, nothing that you do with source code, short of typing it with a hammer, can break your computer (and while that is not strictly true, exceptions are exceptionally rare and not worth concern).

The fact that I value the actual source code as well as the outcome, which tends to be better for such appreciation, explains why I am not a fan of “visual programming”. With traditional source code, everything is enumerated and readily viewable, having been written by you or another programmer. While visual programming is ostensibly the same, it hides aspects of the code and logic behind objects, making development more like hide-and-seek. My first experiences were in the very early ’90s with Asymetrix ToolBook and Borland ObjectVision, where one would have to check every page and object to find all of the scripts to have a complete understanding of the logic, which unnecessarily fragmented the code. Today, such tools as Unity, Unreal Engine, and Interface Builder certainly make visual layout easier, but with the inherent risk that the complexity hides some of the logic, removing it from the source code and fragmenting it. It can be quicker to develop visually (especially if one is inclined toward fast results over quality), but it is inarguably harder to debug.

Outstanding programming is more craft than art, by which I mean that it can be learned and refined over the course of years, and one does not necessarily require an inherent creative ability. I can explain the rationale behind decisions in my source code, and I can teach you techniques, and if you have the requisite logical intelligence (which many people do not), then you can become at least a very good programmer. (I doubt one can read a book about fine art and learn what it takes to be a master.) One of the best compliments I can get is when I am told that I taught somebody the value of maintainable source code, or defensive programming, or quality assurance techniques.

With that in mind, I intend to document more of my approaches to development in general, to provide insights that interested parties can take or leave, along the lines of my Quality [index] series from many years ago. One current focus is refining my programming standards, so look for that in the near future.

Objective-C: @property gotcha #1

Sometimes “best” practices can bite you.

In Apple iOS documentation, they strongly recommend the use of declared properties to automatically generate access methods to class variables.  In header files, you would have something like this:

@interface MyClass
{
    IBOutlet UIView* view;
}

@property (nonatomic, retain) IBOutlet UIView* view;

@end

 

Technically, this generates access methods named ‘view’ and ‘setView’, but in practice one generally accesses the class variable with the dot notation (i.e., ‘self.view’) .  The implementation of this class (minus any explicit methods) would be:

@implementation MyClass

@synthesize view;

@end

 

Accessing the variable with dot notation calls the access methods (as does calling them explicitly, obviously), but simply using ‘view’ (without the ‘self’ reference) accesses the variable directly, omitting any other functionality associated with the accessors, such as (in the above example) retaining the new view.  This is generally a poor practice except in initialization and deallocation routines, where it is preferred.

So, in order to assure that one does not accidentally skip the accessors, the recommended best practice is to use the ability of @synthesize to generate accessors that access a slightly different variable name.  In other words, instead of ‘view’ and ‘setView’ referencing the ‘view’ variable, they can be instead made to access ‘view_’:

@synthesize view = view_;

 

This is, in theory, a good idea because one can only access the variable directly with the explicit addition of an underscore (in this case), and simply referencing ‘view’ instead of ‘self.view’ should produce a compiler error.  (Note that we use a trailing underscore because leading underscores already have a specific meaning in our coding guidelines.)

Problem: If you modify the class implementation as noted above to put this into practice, you introduce a bigger problem into your code.  It turns out that @synthesize actually creates a class variable if none of the specified name exists, but it does not generate a warning or error if the one of the ostensible name does exist.  In other words, the above line would create a new ‘view_’ class variable, and create accessor methods, despite the fact that ‘view’ already exists.  The ‘view’ and ‘setView’ methods modify ‘view_’, so ‘self.view’ does the same, but failing to ‘self’ reference, rather than generating the intended error, actually modifies the orphaned ‘view’ variable.  Instead of having an extra compiler check, you instead have two very similar variables in the same class and any error becomes even harder to diagnose.

If the @property/@synthesize combination essentially replaces normal variable declarations, it obviates the whole issue of these declarations.  This seems rather silly/weird, since declaring [class] variables is a staple of C[++], and the method of doing this in Objective-C is one of the first lessons taught.  Nevertheless…

Solution: To make this idea an actual best practice, at least for simple classes, omit the entire parenthesized section of the class declaration and just declare all variables via @property/@synthesize statements.  You would end up with something like the following:

@interface MyClass
@property (nonatomic, retain) IBOutlet UIView* view;
@end
@implementation MyClass
@synthesize view = view_;

- (id)init
{
    self = [super init];
    if ( self )
    {
        view_ = nil;
    }
    return self;
}

- (void)dealloc
{
    [view_ release];
    [super dealloc];
}

@end

 

All (or most) other references to the class variable would be via dot notation, ‘self.view’, which would (of course) modify the ‘view_’ variable via accessors, as desired.

Happy coding!

Ten Little Images (or so), Part 2

Making sense of launch image requirements for iOS universal applications.

When developing a “universal” application for iOS, an app that will run on all (current) iOS devices, one of the first things you have to consider are the initial branding graphics for your game. These include the launch images for each device (and orientation), in addition to the application icons.

The first part of this article dealt with application icons for a universal iOS app.  This part concerns the launch images, which are static full-screen graphics displayed by iOS itself while the app is loaded and initializes itself, before it has any opportunity to show other graphics.

On an iPad, your application could start in any of four different orientations, two vertical (portrait) and two horizontal (landscape), so you will want one portrait (iPad) launch image and one landscape launch image.  (Technically, you can specify a different launch image for each of the four orientations, but it seldom, if ever, makes a difference beyond portrait or landscape.)  On an iPhone or iPod touch, an application only launches in a portrait orientation, with the home button at the bottom, but these smaller devices may (or may not) have a Retina display, so you need to provide both a normal portrait launch image and a high resolution version.

The purpose of launch images is to provide immediate visual feedback to the user when an application icon is tapped.  Apple’s iOS Human Interface Guidelines document, which is very good in many respects, recommends that the launch image be identical to the first screen of the application, or even simpler, omitting information that is not guaranteed static.  For a game, however, ignore this advice; the launch image is a defacto splash screen, so rather than being simple and unobtrusive, launch images for a game application should be eye-catching.  (We actually do create a “first screen” that replicates the launch image, but can smoothly add information such as version number and build/release date.)

Again, the assumptions here are that you are creating a “universal” application, supporting iOS 3.2 (the minimum version for iPad), and want to be sure to have your branding artwork shown in the best light on all three types of devices. If you are supporting only iPad (no small screens or Retina displays) or only iOS 4+ (no backwards compatibility), then there are fewer conflicts and caveats, but this article should still be helpful.

Launch Image Artwork Specifications

All launch images (and icons) must be in PNG format (24-bit), with no transparency.  The naming conventions for launch images, specifying which graphics to display on each device and supported orientation, are more restrictive than for icons.  In fact, the default launch image base name is (unimaginatively) “Default”.  For somewhat more descriptive naming, we use the project name (“DemolishPairs” herein) as the base name, though the modifiers are mostly fixed (and somewhat ugly).

For a complete set of launch images, we have the following (4) launch image files:

  1. DemolishPairs-Portrait.png [768×1004] – This is the launch image for portrait orientations on the iPad.
  2. DemolishPairs-Landscape.png [1024×748] – This is the launch image for landscape orientations on the iPad.
  3. DemolishPairs~iphone.png [320×480] – This is the (portrait) launch image for the older iPhone and iPod touch.
  4. DemolishPairs@2x~iphone.png [640×960] – This is the (portrait) launch image for newer iPhone and iPod touch devices with a Retina display.  (It is also the ugliest required filename, but at least it is better than ‘Default@2x~iphone.png‘.)

Note that the portrait restriction for non-iPad devices is limited only to launch images; universal applications can (and usually should) support all four orientations, portrait and landscape, on iPhone and iPod touch devices.  For other background graphics, there are usually six different images: portrait and landscape each for iPad, iPhone, and iPhone (Retina) devices.

Project Configuration for Launch Images

Once you have the launch image artwork, it is necessary to include all of these files in the Xcode project, so they will be copied to the compiled bundle.  If you choose to use the ‘Default’ naming, this is all that is required.  However, we chose to use a different base file name, so we have to add a ‘Launch image‘ (UILaunchImageFile) string entry, with the value “DemolishPairs“, to the project’s ‘Info.plist‘ file.

Caveat #1: Xcode 4 allows you to drag launch image files to the ‘Summary’ page of a target’s configuration, and it will automatically add these files to the project.  Unfortunately, Xcode only understands the ‘Default’ naming, so it will name the iPad launch images ‘Default-Portrait~ipad.png’ and ‘Default-Landscape~ipad.png’.  These names are invalid on iOS 3.2, which does not recognize the ‘~ipad’ modifier for launch images, so if you use this shortcut and default naming, you still need to remove the “~ipad” part of each filename for backwards compatibility.

Corollary: Choosing not to use the default base file name for launch images (i.e., adding a valid UILaunchImageFile entry) causes Xcode to become confused and show no launch images on the ‘Summary’ page.  Our recommendation is to edit directly on the ‘Info’ page and ignore the ‘Summary’ page altogether.  (Xcode also has trouble with the “pretty” property values if the .plist file ends with anything other than “Info.plist“.)

More observant readers may have noticed that the two iPad launch images allow 20 pixels for the status bar (on the top), while the iPhone/iPod touch do not.  In order for those launch images not to lose 20 points (20 pixels for non-Retina, 40 pixels for Retina displays) hidden underneath a status bar, you need to hide the status bar on launch.  This is done by adding a ‘Status bar is initially hidden‘ (UIStatusBarHidden) boolean entry set to YES.  (Of course, you could compensate with the artwork, too, I suppose.)

Caveat #2: Hiding the status bar works fine for iPads running iOS 3, which (correctly) just turns the reserved status bar area black, displaying the launch image correctly regardless.  Unfortunately, iOS 4 ill-advisedly attempts to use the entire screen when the status bar is hidden, thus invalidating all of the Apple recommendations for launch image size.  The result is a stretched launch image which, because aspect ratio is preserved, extends off the right edge of the screen.  The only way to make launch images behave the same on all iPads is to not hide the status bar.  Fortunately, this can be done without invalidating the previous change by adding an iPad specific version of the property, UIStatusBarHidden~ipad, and set its (boolean) value to NO.  (Xcode itself does not understand the setting, so it has no “pretty” name, but iOS handles it just fine.)

Caveat #3: When entering property names for the Info.plist, especially for those specific to iPad (or iPhone), note that the names are case-sensitive.  In particular, the modifier is “~ipad” (or “~iphone“); if you capitalize the ‘P’ out of habit, the entire property will be ignored (on any device).

Technical notes:  The above information has been thoroughly tested using Xcode 4.0, specially created launch images, and both the iOS Simulator and a variety of physical devices.  The launch images were designed to be distinguishable from each other, with single pixel borders for detecting stretching and clipping.  Results were confirmed for iOS 4 on the simulator for all three types of devices: “iPad”, “iPhone”, and “iPhone (Retina)”, as well as on an original iPad (iOS 3.2), a second generation iPod touch (iOS 4.2.1), an iPhone 4 (iOS 4.2.6), and an iPad 2 (iOS 4.3.5).  [Editor’s note: We have no plans to upgrade any device to iOS 5.x in the immediate future.]

Making sure that your application icons and launch images look great is an early step in creating a compelling game experience, and I hope that both parts of this article help you develop a universal iOS application without falling victim to one of the potential iOS pitfalls with your branding graphics.  As always, questions and comments are happily accepted.

Ten Little Images (or so), Part 1

Making sense of icon image requirements for iOS universal applications.

If you are developing (or considering) a “universal” application for iOS, an app that will run on all (current) iOS devices, one of the first things you have to consider are the initial branding graphics for your game.  These include the icons, in various sizes, and the launch images for each device.

The icons, of course, are displayed on the home screen of the device to represent the game, but they can also be shown (in different sizes) on the search page (as well as in Settings, if appropriate).  The launch images are stand-in graphics that are displayed in a static fashion while the app is loaded and initializes itself.  On an iPad, there need to be launch images for each orientation (portrait and landscape), while the iPhone and iPod Touch only launch in portrait orientation.  For more variety, though, the iPhone 4 and 4th generation iPod Touch have the Retina displays, with higher resolution, requiring still more images.

The assumptions here are that you are creating a “universal” application, supporting iOS 3.2 (the minimum version for iPad), and want to be sure to have your branding artwork shown in the best light on all three types of devices.  If you are supporting only iPad (no small screens or Retina displays) or only iOS 4+ (no backwards compatibility), then there are fewer conflicts and caveats, but this article should still be helpful.

Icon Artwork Specifications

All icon (and launch) images must be in PNG format (24-bit), with no transparency.  Although there are naming conventions for automatically loading different files according to the device type, arbitrary (descriptive) file names for icons are preferred and more reliable.  In our case, we use the project name (“DemolishPairs” herein) as a base name, with “ipad”, “iphone”, and “retina” used as modifiers.

For complete icon coverage, with no scaling performed by iOS, we have the following (8) icon files:

  1. DemolishPairs.png [512×512] – This is the largest (current) icon size for iOS applications; generally, the artwork should begin at this size (or larger) and be scaled down to the other sizes.
  2. DemolishPairs_ipad.png [72×72] – This is the application icon for the iPad, as shown on the home screen.
  3. DemolishPairs_ipad_small.png [50×50] – This is the application icon for iPad, displayed in search results.
  4. DemolishPairs_iphone.png [57×57] – This is the application icon for the older (non-Retina) iPhone and iPod touch.
  5. DemolishPairs_iphone_small.png [29×29] – This is the search results icon for the older iPhone and iPod touch.
  6. DemolishPairs_retina.png [114×114] – This is the application icon for the newer (Retina) iPhone and iPod touch.
  7. DemolishPairs_retina_small.png [58×58] – This is the search results icon for iPhone/iPod touch with Retina displays.
  8. iTunesArtwork [512×512] – This is (in our case) a copy of ‘DemolishPairs.png‘ with a very specific filename (note: no file extension, not even ‘.png’) for ad-hoc distribution and/or submission to the App Store.

Note that most games will not have Settings packages, but those that do can use the 29×29 icon [5] for all older displays, including iPad, and the 58×58 icon [7] for all Retina displays.  (Document icons have different requirements but are generally unnecessary for games, so they are not covered here.)

Project Configuration for Icons

Once you have the icon artwork, it is necessary to include all of the icon files in the Xcode project, so they will be copied to the compiled bundle, and then modify the project’s ‘Info.plist‘ file (by whichever name) to indicate the icon image filenames.  There are two possible entries that indicate icons, and since we are specifying multiple image files (and by Apple recommendation), we will add an ‘Icon files‘ (CFBundleIconFiles) array with six entries:

  • DemolishPairs_ipad.png
  • DemolishPairs_ipad_small.png
  • DemolishPairs_iphone.png
  • DemolishPairs_iphone_small.png
  • DemolishPairs_retina.png
  • DemolishPairs_retina_small.png

Caveat:  ‘DemolishPairs_ipad_small.png‘ must appear before ‘DemolishPairs_iphone.png‘ in the list; otherwise, iOS 3.2 (iPad) will incorrectly select the 57×57 icon instead of the 50×50 icon when displaying search results.

Although the CFBundleIconFiles array takes precedence, there is still a minor reason to add the (singular) ‘Icon file‘ (CFBundleIconFile) string, with “DemolishPairs.png” as the value.  Xcode 4 uses this image file as the default icon for the target application in the project; if it is missing or empty, the last entry in the array is used.  This (currently) has no practical impact on the application itself, but supplying a reference (512×512) icon within the bundle is not a bad thing.

Of course, if one is building an application for only iPad devices, the number of icons necessary is reduced, but I would still recommend getting a complete set of the above icon sizes from your artist anyway (just in case).  On the other hand, if one is building an application for only iPhone devices, shame on you; there is no excuse for not supporting the iPad nowadays.

Technical notes:  The above information has been thoroughly tested using Xcode 4.0, specially created test icons, and both the iOS Simulator and a variety of physical devices.  The icon images were designed to be distinguishable from each other, with single pixel borders for detecting stretching and clipping.  Results were confirmed for iOS 4 on the simulator for all three types of devices: “iPad”, “iPhone”, and “iPhone (Retina)”, as well as on an original iPad (iOS 3.2), a second generation iPod touch (iOS 4.2.1), an iPhone 4 (iOS 4.2.6), and an iPad 2 (iOS 4.3.5).  [Editor’s note: We have no plans to upgrade any device to iOS 5.x in the immediate future.]

In our next installment, Ten Little Images (or so), Part 2, I discuss the requirements and caveats of launch images in universal iOS applications.

Carbon nibs update

A spurious warning appears to be spurious.

In my last post, Carbon nibs under Lion, I gave a solution to the problem of Carbon nib (interface) files not being supported in Xcode 4, while Xcode 3 would not run under Mac OS X 10.7 (Lion).  That solution was to run Interface Build 3.2.6 and convert the nibs to a newer format.

Toward the end of the post I mentioned that many windows in the converted nib files produced a warning: “This window’s content rectangle does not lie entirely on the screen with the menu bar and may not be completely visible for all screen resolutions and configurations.”  In testing, these files did not exhibit any errant behavior, but shipping a product, even a beta, with build warnings is against our development guidelines.

Since that post (and in preparation for a proper build, without warnings), I did a little research and experimentation and discovered that the problem appears to be a minor issue with the conversion, where the resulting data is aberrant enough to generate a warning, but is handled correctly in the resulting application.  Although I did not dig deeply enough to identify the exact source of the problem, it is related to window positioning (as one may have guessed).

The solution, oddly, is simply to open the offending nib file, select the (or each) window, click on the Size (ruler) tab in the Inspector, and then drag the window position image, even slightly.  As far as I can discern, any movement (within the simulated window) fixes the problem; at least, it fixed it for all of my affected windows.  Clearly, the size of the windows was not the issue, since that was not changed, and the position should never have been a problem, either, for windows with the ‘Center’ attribute enabled (as most of mine were).  I also note that the windows I created from scratch since moving to this Lion/IB 3.2.6 setup were unaffected.

One other idiosyncrasy to note is that the build process also produces the following message: “View is clipping its content.”  It is not a warning, just a message, and I assumed that it was related to the above warning until the warnings were fixed.  It is a straightforward message, albeit with no reference to the specific view involved, so I looked into find the problem there as well.

As it turns out, there is a very useful tool with IB 3.2.6 to assist with this.  Select ‘Layout->Show Clipping Indicators’ to enable a feature that displays a small “+” at the bottom of any view that is clipping its content.  I never noticed this setting before, and it can be very handy.  Alas, it also reveals (in our case) that the messages are just pointless chatter, since they are being given for list views with extra columns that are intended to scroll horizontally.  Fortunately, they do not produce a warning message, so the messages are easily ignored; in fact, they only appear on the full build log, so I may have never noticed them had I not been debugging a nearby warning.

[The most meaningful comment that I received for the last post was (seriously), “I’ve a cockroach on my pillow.  Wanna see it?”  The days of technical development posts may be numbered.]

Carbon nibs under Lion (Mac OS X 10.7)

Apple’s overly aggressive deprecation sucks.

If you are still maintaining a Carbon application for Mac OS X, you may have stumbled upon a serious issue with handling of nib (interface) files in Xcode 4 under Lion, and if you have not yet, you probably will soon.  Hopefully, this post will help you resolve problems or avoid some of the pitfalls.

The Problems

Apple marches forward and aggressively deprecates development technology.  In this particular case, they release Xcode 4 and only allow submissions to the Mac App Store from the latest version, forcing developers to upgrade.  We are maintaining and enhancing a product that was developed using Carbon, based on Apple’s (then) recommendation for cross-platform products, and was about 90% complete when they announced its deprecation in favor of Cocoa.

Additionally, we upgraded to Lion (to properly provide customer support), unaware that the latest version of Xcode 3, version 3.2.6, would not install or run on Lion.  Instead, we could only download and install Xcode 4.1, which does not provide support for Carbon nib files.  With Snow Leopard, we could download both versions normally, but from Lion, the Xcode 3 download link is removed and Xcode 4 is only available via the Mac App Store.  More accurately, the installer is available via the Mac App Store; you still need to find it in Launchpad and run it before Xcode is ready.

There are two particular problems that occur with Carbon nibs in Xcode 4.1:

First, there is no editing capability for modifying them, so when you highlight a Carbon nib, the editing window only displays an Interface Builder icon, but (importantly and annoyingly) there is no message that editing is not supported.  Unless you already know that is the case, you will waste some amount of time attempting to figure out how to activate the “integrated” Interface Builder.

Second, the build tools provided cannot process the older nib files, so you will get a message similar to the following: ‘error: ibtool could not strip “Main.nib” because it is not a valid Interface Builder document.

Of course, there are a few obvious options here.  If you stop upgrading your development system, you can still build on Xcode 3.2.6 under Snow Leopard, except that you cannot submit to the Mac App Store.  You may be able to have both versions in parallel, but that is not an option on Lion at all, and the nib build issue still exists in Xcode 4 (although the solution to that is provided below).  Finally, you can give in to Apple’s strongarm tactics and rewrite your application to use Cocoa, but that is not always feasible, economically or otherwise.  (In our case, we are trying to maintain our products and support our customers while we rewrite it with Cocoa.)

Or, I suppose, you could flip Apple the bird and abandon their Mac platform; that has crossed my mind more than once, but it is not really an option for us.  Instead, I found a way to resolve the two main problems above, without too much effort.  (That is, it will be fairly easy for you readers; it took me significant time to figure this all out.)

The Solution

To resolve the inability to edit Carbon nib files within Xcode 4, take advantage of the fact that Interface Builder was an external tool with Xcode 3, and that it does run in Lion.  Simply copy Interface Builder 3.2.6 from a (Snow Leopard) partition on which it is installed to the Lion partition.  It should be located (by default) in the ‘/Developer/Applications’ folder, and note that it must be copied to the same directory on the Lion partition after Xcode 4.1 is installed.  (It will not run properly from a different folder, and the Xcode installer apparently removes it [so make a backup copy].)  Since Xcode will no longer launch (the external) Interface Builder automatically, you will probably want to make an alias for it in a convenient location.

Then, to resolve the build problems with the older nib files, you must use the separate Interface Builder tool to covert your nib files to a newer (XIB) format.  This is accomplished by opening each nib file in IB, selecting ‘File->Save As…’ from the menu, changing the ‘File Type’ to “Interface Build Carbon Document (XIB 3.x)”, and saving.  You will then need to open your project in Xcode, add all of the new .xib files to it, and delete the older .nib files.  Clicking on one of the .xib files in Xcode will show/edit it as an XML file (instead of just an icon) but, of course, you will probably only want to edit it in your newly installed IB3.

There may (read: probably will) be other issues, both with Xcode 4 itself and with the newer SDKs.  For example, we use one (and only 1) function defined in ‘QuickdrawAPI.h’, which has been removed from the OS X 10.7 SDK, so we had to back down to the 10.6 SDK (plus each SDK has different versions of the zlib library available).  Also, several of our windows from (converted) nib files produce a new warning: “This window’s content rectangle does not lie entirely on the screen with the menu bar and may not be completely visible for all screen resolutions and configurations.”  (We dynamically adjust most of our windows anyway, so it appears to make no difference, but we have yet to eliminate these warnings.)

Nevertheless, making the above changes will allow an older Carbon-based application to be built on Lion using Xcode 4.1, leaving you free to discover more fun and excitement.

[If you find this information useful, please leave a meaningful comment.]

API Design Dilemma

I need to decide how to define certain parameter types.

The general situation is this:  I am refactoring a piece of C++ code to be part of a separate library, so I am in the process of defining and documenting an API for using the included classes and methods.  A fundamental design consideration is that the library may be called by third parties, without access to the source code, so I need to make the code as close to bulletproof as possible.  (For internal development, at least I know the methods used, how the API will be utilized, and that it will not be abused terribly.)

During this process, I encountered a theoretical dilemma about how to handle certain parameters.  Specifically, I was working on method definitions that included sizes and counts that should never be negative (but, of course, I need to prepare for abuse).  As an example, say I am reviewing a method that is declared like this:

    bool FillBuffer ( byte* pBuffer, int nSize );

Here, pBuffer is a pointer to the buffer to be filled, and nSize is the size of that buffer.  Of course, it is not possible for a buffer to be a negative size, so my initial reaction was to redefine it as:

    bool FillBuffer ( byte* pBuffer, unsigned uSize );

This makes perfect sense from a theoretical standpoint, but then a practical consideration occurred to me.  I always verify parameters with an assertion and, for a public method (as here), abort the routine if verification fails, with an exception or error return as appropriate.  In this case, my original method would assert nSize to be greater than zero (and return false), which would catch any negatives.  The new method would only catch the case where uSize was zero, but if a careless programmer cast a signed integer (or, worse, let the compiler do it), the current validation check would not identify a problem.

So, there were a few obvious solutions that I considered:

  • I could leave the original definition alone, which would catch obvious parameter errors, but would be theoretically incorrect, and if a programmer wanted to pass the size of a static buffer, using sizeof(), there would be a signed/unsigned mismatch.
  • I could use the new method definition, which would be correct in theory, and just trust programmers not to abuse the method with invalid parameters (and let them suffer if they do).
  • I could use the new method definition and add a sanity check so an extremely large buffer size (i.e., likely a negative value cast improperly) would be rejected, but the drawback there is that any such check would be somewhat arbitrary, and it would limit the functionality for any programmer who truly wanted to use an enormous buffer.

Each of these solutions has advantages and drawbacks.  I dislike having a parameter take a type that is not accurate (though not so much as to not have written this code in the first place), but I dislike arbitrary limits even more.  However, I know that defensive design is important here, since a careless programmer is, in my experience, the most likely to complain that the library or API is at fault.  (I was once threatened with physical violence when I produced a critical review of code written by a nominal “programmer”.)

At this point, I am leaning toward a hybrid solution by overloading the method with both (or multiple) definitions, the original checking for negative sizes as usual before doing an explicit cast of the size value and passing processing to the new/correct method.  The advantage is that passing an actual negative number (or signed type) will result in that extra checking, and a programmer could pass a buffer size up to the limit of the unsigned type.  The disadvantages are the additional work needed to create the extra stub(s), loss of type checking during static analysis, and the fact that our careless friend could still cast a value to create problems (but then it should be quite obvious, at least).

This post is an exercise in the process of working through a problem by simply writing down the issues, which often results in a solution (or decision) by the time one is finished with the description.  (It did here.)  I would, however, welcome any comments on my proposed solution, or other suggestions.

Finally, yes, I know that int and unsigned are not ideal parameter types for this in the first place, but I used them for the purpose of illustration.  (The principle also applies to object counts and other similar parameter types.)

Three Steps to Apple Help, Part 3

Accessing Apple Help from C++ Code (Carbon)

The third/final step in implementing Apple Help is programmatically displaying the main contents or individual topics within your help pages.  This, of course, assumes that you have already created a set of HTML help pages for Apple Help and then indexed and integrated these files into your Xcode project.

Accessing Apple Help from C++ using Carbon is fundamentally simple.  The Apple Help Reference contains only 4 functions (plus one constant enumeration that is no longer used).  There is a little bit of necessary mucking about with bundle references and whatnot that may be unfamiliar to programmers who have not worked with Mac development before, but it is all fairly straightforward.

In order to access Apple Help from the application, you first register your help files using the AHRegisterHelpBook() function.  This only needs to be done once, ideally during program initialization, and we do it something like this:

bool RegisterHelp ( void )
{

    CFBundleRef const bundle = CFBundleGetMainBundle ( );
    if ( !bundle )
        return false;

    CFURLRef const location = CFBundleCopyBundleURL ( bundle );
    if ( !location )
        return false;

    FSRef file;
    if ( !CFURLGetFSRef ( location, &file ) )
    {
        CFRelease ( location );
        return false;
    }

    _Error = AHRegisterHelpBook ( &file );

    CFRelease ( location );

    if ( _Error )
        return false;

    return true;

}

(Additional validity checking and error reporting has been stripped from this sample code for clarity.)

In the above example, most of the code is just to obtain the FSRef (file system reference) of the application bundle from which the help is to be displayed, and it assumes that you want help for the current application.  (Obviously, you could instead pass a reference to any other bundle and access a different help system, but that would be unusual.)

Once the help files are registered, you can display the main help page using the AHGotoPage() function (with default parameters), which we accomplish with a function similar to this:

void ShowHelpContents ( void )
{

    CFBundleRef const bundle = CFBundleGetMainBundle ( );
    if ( !bundle )
        return;

    CFStringRef const key = CFSTR( "CFBundleHelpBookName" );
    CFTypeRef const book =
        CFBundleGetValueForInfoDictionaryKey ( bundle, key );
    if ( !book )
        return;

    CFStringRef const help = (CFStringRef)book;

    _Error = AHGotoPage ( help, NULL, NULL );

}

(Additional validity checking and error reporting has been stripped from this sample code for clarity.)

You can also display a specific help topic by using the AHLookupAnchor() function, for which we use something like this:

void ShowHelpTopic ( CFStringRef topic )
{

    if ( !topic )
        return;

    CFBundleRef const bundle = CFBundleGetMainBundle ( );
    if ( !bundle )
        return;

    CFStringRef const key = CFSTR( "CFBundleHelpBookName" );
    CFTypeRef const book =
        CFBundleGetValueForInfoDictionaryKey ( bundle, key );
    if ( !book )
        return;

    CFStringRef const help = (CFStringRef)book;

    _Error = AHLookupAnchor ( help, topic );

}

(Additional validity checking and error reporting has been stripped from this sample code for clarity.)

In both of these last two examples, the function reads the CFBundleHelpBookName string from the main application bundle and uses that string for the name of the help system, passed as the first parameter to the appropriate Apple Help function.  (You could, of course, hard code this string, but if you were thinking that this is a good idea, shame on you.)

Accessing Apple Help from Objective-C (Cocoa)

If you are using Objective-C and Cocoa, much of the help system handling is done behind the scenes (which is, in part, why some programmers find Objective-C to be objectionable).  If you follow the steps in the previous two posts (Part 1 and Part 2) to insert your Apple Help into a Cocoa project, your main help system will work automatically.

The main help page in a Cocoa application is accessible by the user through the ‘Help->[ApplicationName] Help’ menu option by default.  If you wish to bring up the main page from your Objective-C code, you may need to reference an anchor on that page (see below) or use the Carbon method described above.

To access a specific help topic (anchor) from Objective-C and Cocoa, this is done through the shared NSHelpManager object using the openHelpAnchor:inBook: method.  For example, to open the ‘rules’ topic, you would use the following code:

    NSString *book = [[NSBundle mainBundle]
        objectForInfoDictionaryKey:@"CFBundleHelpBookName"];
    [[NSHelpManager sharedHelpManager]
        openHelpAnchor:@"rules" inBook:book];

The documentation for NSHelpManager is quite clear that all of its functionality is simply a number of wrappers around the functions described in the first section of this post, so you could always use those functions directly, if desired.

There you have it.  At this point, you should know enough to properly implement Apple Help in your Carbon or Cocoa application for Mac OS X.  The process is a little convoluted to suss out from the documentation, so I hope this provides a decent jump start.

No Magic Numbers

Action Solitaire 1.31 is now available for download.

After the last posting, we discovered a rather significant bug in Action Solitaire. It was fortunate that it was discovered in house, but unfortunate that it was not found during beta testing and, hence, required a public update. The problem caused two of the 65 games to behave incorrectly (or even crash) when large or huge card sizes were selected, either explicitly or implicitly through automatic sizing.

The problem turned out to be magic numbers in the code. We released the first version of Action Solitaire back in 2003, which was six years of coding experience ago and at a time when I felt under some (self-imposed) pressure to get the product finished. Unlike some of the other projects, the source code for this game has not been refactored, except to the extent necessary to make updates for Vista and add new games, so I never revisited these (working) games to see the problem.

For those who do not know, a magic number is an explicit and undocumented constant in the source code for a program, so named because the value works like magic, without any proper explanation. In this particular case, the width and height of an image buffer were set to constant values, calculated (manually) to accommodate an area based on the largest card sizes supported by the game at that time. Rather than actually letting the computer determine the necessary buffer size, based on named constant values (e.g., MaxCardWidth and MaxCardHeight), the code just used constant numbers directly. When the maximum card size increased, the buffer was too small and problems ensued. Such are the dangers of magic numbers.

It did not take long to find and fix the problem, but it should not have been necessary in the first place, especially since we had standards, even back then, that discouraged the use of magic numbers. I made an exception and got burned. Ouch.

Anyway, Action Solitaire can be downloaded here, and I guarantee ample opportunity to find other bugs in this product, but the game is fun (and addictive) as well.