mac

6 entries have been tagged with mac.

Typesafe typecasts

[The minimal sample code in an Xcode window]

This is probably obvious to everyone else out there, but since I only just realized this, I thought others may be similarly dense, so I’d like to point out a little bit of Pascal ingenuity that can be applied to a common Mac programming problem.

There are many classes and structs on the Mac that exist in duplicates. For example, CoreGraphics has CGRect to represent Quartz coordinates, while AppKit uses NSRect. They’re exactly the same in layout, but have separate names. Similarly, there are many toll-free bridged classes between CoreFoundation and Foundation. For example a CFURLRef can be used wherever an NSURL* is needed, as long as you typecast between the types so the compiler doesn’t whine.

Now, typecasts are dangerous: Assume you have an NSString* storing a file path, and now you decide to change it into an NSURL*, because that’s Apple’s new recommended type for file references. You change it in the class header, and all call sites start giving you type errors, which you fix.

All call sites? Nope. In one spot you were typecasting your NSString* into a CFStringRef. Now you’re typecasting an NSURL* to a CFStringRef, which is obviously wrong, but will only give you runtime errors. Ouch. So, what can you do? Well, there’s a neat trick that Pascal programmers used to use to get around Pascal’s refusal to typecast: They used a union. Unions are usually considered as type-unsafe, but in this case, they’re just type-safe enough for our purposes:

CFStringRef  UKNSToCFString( NSString* str )
{
    union ConversionUnion
    {
        NSString*      mNSString;
        CFStringRef    mCFString;
    } myUnion;

myUnion.mNSString = str;

return myUnion.mCFString; }

The neat thing is that this function type-checks the input and output, but since it’s a union, it lets us set an NSString* and get a CFStringRef. Our above change would cause a compiler warning now since we’re passing an NSURL* into a function that takes an NSString*. It encodes the fact that an NSString and a CFString are the same, but only those.

Apple even does that. Look at NSRectFromCGRect() (I slightly cleaned up the code):

NSRect NSRectFromCGRect( CGRect cgrect )
{
    union ConversionUnion
    {
        NSRect ns;
        CGRect cg;
    };
    return ((union ConversionUnion *)&cgrect)->ns;
}

They’re even a tad more efficient: Since the input parameter already is a CGRect, they just typecast it to a union ConversionUnion, saving you that one extra copy to an actual temporary local union variable. You could probably even get rid of the union completely and just typecast inside the function, as its input parameter type and return type already perfectly codify the conversion in a type-safe manner.

A neat trick for which I’ve created a header for a bunch of commonly bridged types and put it on my github.

Double click is a shortcut

IMG_0364.jpg

John Gruber mentioned in passing that people are confused about when to double-click and when not to. It’s true, but that doesn’t just apply to users. I’ve seen many application developers not knowing (or simply not caring) about when to use a double-click, and when not to.

The simple matter of the fact is: Double-clicks are a shortcut.

Look at the Finder: A single click selects an object. A double click opens it. A double click here is simply a shortcut for a single click (“select this item”) plus the most common menu item used on this item (“File” -> “Open”).

Many users are simply never taught that this is why to double-click. Many think “Files are always double-clicked”.

In the dock, you can’t select an item. So, a single click already triggers an action.

I won’t count minimizing windows by double-click here. Why? Because it’s actually a historic feature. Back in System 7, you couldn’t minimize windows. There was a title bar with a close button and a zoom button. Someone wrote a nice extension called “WindowShade” that rolled up a window into a title bar. Since they couldn’t add a widget to every window, and single clicks already dragged the window, they just decided to use a double click. When that extension got rolled into the system with System 7.5, the shortcut stayed, and never got removed, even after MacOS 8 added the collapse box widget.

I don’t know why this feature even still is in OS X. We have a “minimize” widget taking up valuable screen real estate. Why even leave something like that in? So many newbies accidentally trigger this and wonder where their window has gone.

Helpful Xcode User Scripts

One of the more annoying tasks when writing Cocoa code is defining symbolic constants for all those keys when doing key-value coding. I’ve already posted my trick for getting auto-validated key-value-observing constants, but there are constants that aren’t accessors. Does lazy Uli have a trick for these as well?

xcode_user_scripts.jpg

Yes! Xcode has a really neat feature called “User scripts”. It takes the form of a little black scripture roll in the menu bar. If you open it, there is an “Edit User Scripts…” menu item. Choose it, and it shows a list of the scripts that come with Xcode, plus an edit field on the right where you can edit the current script.

The neat thing here is: These are just unix shell scripts. Notice the shebang at the top? That means you can specify every script interpreter, and you aren’t stuck with those terrible search-and-replace-with-side-effects-languages like bash or zsh. You could use Perl, or Ruby, or … heck, why not use PHP? Let’s do that, let’s solve our problem with constants in PHP. Click the “+” button and add a new script, change its name and give it a nice keyboard shortcut (I chose Cmd-Ctrl-K, K as in Konstant – C was already taken). Then paste in the folowing script:

#!/usr/bin/php
<?php
$fd = fopen( "php://stdin", "r" ) ;
$the_ident = fgets($fd) ;
echo "NSString*\t$the_ident = @\"$the_ident\"; \n";
?>

Make sure the “Input” popup is set to “Selection”, and the “Output” is set to “Place on Clipboard”. Now, whenever you need a new string constant as a dictionary key in Cocoa, you can just write the constant’s symbolic name

MyAppShouldOpenUntitledWindowPrefsKey

select it by double-clicking, hit Cmd-Ctrl-K, and then paste a finished declaration for it at the top of your source file:

NSString*   MyShouldOpenUntitledDocPrefsKey = @"MyShouldOpenUntitledDocPrefsKey";

Of course that’s just one of the neat macro things you can do. Since most scripting languages these days support regular expressions, you can do things like turn detect string literals on a line and generate a .strings file entry from it (or vice versa), put brackets and angle brackets around the selected expression (set the output to also be “Selection”), and do a multitude of other handy things.

Okay, you don’t really have to write code for putting brackets around certain expressions. Just look in the Edit -> Insert Text Macro -> C and Edit -> Insert Text Macro -> Objective-C submenus. You can use the Preferences window’s Key Bindings page to specify keyboard shortcuts (I chose Cmd-Ctrl-9, the key where my UK keyboard has the opening bracket, for Parenthesize Expression and Cmd-Ctrl-[ for Bracket Expression).

Of course, you can also put scripts in this menu that talk to the command line tool for your version control system of choice. For example, if you’re as addicted to GUI clients as I am, you’ll want the following script:

#!/bin/bash
# Find current document's repository root and cd to it:
MYPATH=`osascript -e "tell application \"Xcode\" to (path of document 1)"`
while [[ -n "$MYPATH" && "$MYPATH" != "/" && ! -e "$MYPATH/.git" ]]
do
	MYPATH=`dirname "$MYPATH"`
done
cd "$MYPATH"
if [[ -n "$MYPATH" && "$MYPATH" != "/" ]]
then
	# Now do our magic!
	open -a GitX.app "$MYPATH"
fi

This opens the current Xcode file’s Git repository in GitX so you can get yourself some hot merging and staging goodness. You can write a lot of code following this principle. For example, here is a script that does a git push on the project folder in a Terminal window, so you can actually type something into the password prompt:

#!/bin/bash
# Find current document's repository root and cd to it:
MYPATH=`osascript -e 'tell application "Xcode" to (path of document 1)'`
while [[ -n "$MYPATH" && "$MYPATH" != "/" && ! -e "$MYPATH/.git" ]]
do
 MYPATH=`dirname "$MYPATH"`
done

cd "$MYPATH" if [[ -n "$MYPATH" && "$MYPATH" != "/" ]] then # Now do our magic! IGNORE=`osascript -e "tell application \"Terminal\" to do script \"cd \" & quote & \"${MYPATH}\" & quote & \"; git push\""` fi

Any other suggestions for other useful scripts for coding that one may want to put in this menu?

Inference vs. Knowledge

I’ve blogged before about Sensible defaults and Anticipating User’s Needs. One suspicion that the feedback I received to this article raised in me was that people are very unclear about when inferring user intention is good, and when it gets in the way. Of course, this is not easy, and thus there’s no clear-cut answer, but if you’re aware of what you are doing, you can find the right way.

Distinguish Inference from Knowledge

Just like when designing any other algorithm, there are two extremes: On one hand, you may actually know what the user is trying to do. E.g. the user chooses the Quit menu item, and everything has already been saved: You know that the user wants your app to go away. It’s straightforward to implement.

On the other hand, there are also cases where you do not know what the user wants to do. E.g. the user has chosen Quit, but has unsaved changes. Does the user want to discard all changes made? Or did the user forget to save?

What can we do in the second case? Well, for one, we can apply a heuristic. We can assume that the user doesn’t want to lose data, and just save implicitly and then quit. Any user that actually didn’t want to apply the changes she did would simply be screwed. We could assume that the user knows what she’s doing and just quit and lose all unsaved changes. But everyone makes a mistake, and computers should be forgiving. No action the user initiates should be an irreversible mistake. Heck, even my washing machine lets me pause it and add a few more socks I found behind the couch. Why shouldn’t my Mac?

Still, both are options we have. There’s also the third option that we have: Put a fat stinkin’ dialog in the user’s face. This is the equivalent of grabbing someone about to leave a store by the collar and asking him: HAVE YOU PAID YET? This may sometimes be necessary, but generally you want to be nice to your user, you don’t want to halt them in the middle of their work. Ideally, you’d just quietly do the right thing.

The thing to keep in mind here is that you simply do not know what the user intended to do. Even worse: although the user explicitly said Quit, you do not know whether you should do that. This is neither bad or good, but it is an important thing to keep in mind when you design your program: How certain are you, that what your app is doing now is what the user wants?

If you are very sure, go ahead, do it. But what if you’re not so sure? The first rule should be: Do No Harm. The developer is given care of the user’s valuable data, her work, so he should not damage it. Take our quit example from above: In most applications today, you should not just quit if there are unsaved changes: Not saving would lose whatever changes the user just made, saving could damage the previous state of the data by applying changes that were never intended to be saved.

So, should we ask?

What if the user could just re-open the document and undo these damaging changes? In that case, just saving would actually be a much better choice. Nothing is lost, and the saved undo stack in the document lets us revert any damage.

So, you see, even in a common case, which is done so frequently in every application on your computer, you should actually be asking: What do I know? How sure am I of this knowledge? Is there a heuristic that lets me do something implicitly, but doesn’t hurt if I get it wrong?

Ask the User, but Do Not Ask the User

Another thing that is often done wrong when applying heuristics, is how to handle the situation where you aren’t sure what to do. Yes, you need a decision from the user, but that does not mean you should ask. Every time you put up an alert, you interrupt the user in their work, and force them to read the alert text and make a decision. If you do this too often, the user will just get used to clicking one of the buttons, without reading. The one time they actually made a mistake, they’ll already reflexively have clicked that button and be screwed.

Or in other words: Every time you put up an alert panel, God kills a cute little anthropomorphic paperclip.

You have many options to get input from the user, an alert isn’t the only one. And by alert, I mean everything that is kind of modal, including the weird status messages with buttons iTunes shows at the top of the window in its LED display.

For example, if your application detects at startup that it was quit with a document open, should it ask the user to reopen? I say no. What should we do instead? Well, look at your application’s workflow and typical use, of course!

If your application is mainly for generating documents, like GarageBand, where you typically create a song or Podcast over a period of time, then export it to a more standard audio format and publish it in some way, the user will likely want to return to a document. In that case, just reopen what was open last.

If your application is mainly for editing documents, for working with many documents, or for polishing and revisiting various documents, you’ll want to provide a “recent items” list instead. You can just use the built-in system menu, or you can additionally bring up a welcome window whenever no documents are open, showing recent items, templates for new files and an “open” button, like it’s done in Keynote or Xcode.

And if your application is one of those single-window monsters, for managing sufficiently distinct sets of items in a central database, you can put a “recent items” section in your sidebar. The user gets the main window, and has quick and obvious access to their most recently used item, without you loading a potentially huge item the user is not that likely to use.

Yes, I’m really saying that not asking the user, not doing anything, is OK sometimes. Your app doesn’t know with enough certainty what to do. You don’t want it to annoy the user. However, if you can infer a reasonably common case, you can still design your application to support the user in that task by making sure that, at this moment, the controls to achieve this common task (e.g. grabbing the most recent file) are within easy reach.

Also, sometimes an action is so nonsensical that you can be sure the user was trying to do something else. Instead of just telling the user “No can do”, your app can infer what they might have wanted to do, and offer to do that instead. You’re putting up an alert anyway, so why not put something useful in it?

You are not the typical user

When evaluating how certain you are about the user’s intents, also keep in mind that you are someone involved in application development. The way you use and understand the application goes much deeper than that of your users. You may know more about kerning, anchored selections and grammar-checking algorithms, while the users of your text editor may know more about particle physics or elaborate stitching, or whatever topic they are writing about when they use your text editor. A novelist has different needs than someone who mainly writes correspondence, who has again different needs from someone writing a technical manual.

So, when you infer that “everybody hand-picks their photos off the camera”, keep in mind that that may not at all be true. Someone taking a large amount of photos on a holiday to Lucerne, Switzerland, will probably want to quickly empty the memory card of the camera by transferring all photos to their Mac, and then quickly head out again with a fresh card, to enjoy the place more. They will want to just plug it in and have it import all while they take a shower.

On the other hand, a photographer on a scheduled outdoor shoot may be looking over each image anyway, to see whether he got the coverage he wanted, or whether he has to keep going to get the right picture because of a pedestrian in the background who was picking his nose at just the wrong moment, or a smudgy fingerprint on the lens that didn’t show up on the small camera screen.

So, how do I find out whether I’m right? Although there is no patented recipe, there are simple checks you can perform right away: Get a second opinion. Even if you just talk to a colleague, chances are that they use the app differently, and will spot an additional flaw in your thinking. You can give a test build to a friend and use them as your guinea pig. Ask your favorite user that e-mailed you with a “thanks for coding this” letter, how they would achieve a task that involves your new inference. Whatever. Of course, none of these people constitute a representative sample, but at least you’ll get additional data points to ponder.

And if you’re facing a big decision, you can always try more formal usability tests. But every little bit helps you gain experience, make better decisions, and discover those novel use cases you never considered.

But isn’t this inconsistent?

So you’ve tested something on your users and found that the system’s standard behavior doesn’t work. You’ve found a different solution, but now you’re wondering about consistency: everyone else on the Mac does it one way. Should you implement things differently?

The first thing you have to ask yourself is: What if a user forgets my app behaves differently? If they’ll lose data if they mix up the way your app and other apps they use work, you need to work harder. If it’s harmless … ? Well, you’ve done research to back it up, right? Tested it on a few friends, maybe even done a public beta? If you have a good reason and research to support your point that this behavior is better, then do it.

The number of beings doing something doesn’t mean it’s the best thing to do. Hey, there’s millions of flies eating doggy poo, still we humans don’t eat it…

Drawing off-screen in Cocoa

In general, drawing in Cocoa always happens in an NSView‘s -drawRect: method on the main thread. The OS calls that whenever you’re supposed to draw anything, and if you want to redraw, you use -setNeedsDisplay: to ask the OS to call you back, and it will in turn call -drawRect:.

But sometimes, you just want to draw on a secondary thread, or you want to draw something for later use that shouldn’t show up in the view right now. The approach mentioned above seems awfully limited, doesn’t it? Of course there are other ways to do that.

A very easy way is to just take an NSImage, create it in your helper thread or threaded NSOperation, call -lockFocus on it, draw your stuff, call -unlockFocus and then send the finished image back off to your main thread using -performSelectorOnMainThread:withObject:waitUntilDone:. Note though, that doing a -lockFocus on an NSImage pretty much deletes and recreates the image contents, along with a Graphics Context needed to draw into the image, so if you plan to lockFocus/unlockFocus a lot, this will be fairly slow. In this case, you might be better off creating an NSBitmapImageRep directly and drawing into that, or even creating a CGBitmapGraphicsContext, doing your drawing in there, and only creating an NSImage from that once you’re finished.

Since you decide what to do with the NSImage once you’ve created it, this is a decent way to cache drawing that will need to be displayed later, or to pre-render more detailed versions of tiles of an image in the background to allow for more detail when zooming. It is also a way to speed up drawing of complex stuff. The CPU and GPU are fast enough to blast a full-screen pixel buffer to the screen at 50fps or more, but actually doing anti-aliased rendering of bezier paths or laying out text at this rate might be taxing the machine a bit. It also means all your drawing resources are together on your secondary thread, completely disconnected from the main thread. So it’s unlikely your thread has to wait for someone on the main thread to finish drawing, unnecessarily slowing things down.

If you really, urgently need to draw now, and need to do it on another thread (e.g. for video playback), you’ll need to do the threaded NSView drawing thing: Call -lockFocusIfCanDraw on the view, do your drawing, being careful that all your state has thread-safety locks or is immutable, call -flushGraphics on the current context and then -unlockFocus again. This is a bit dangerous due to all the thread synchronization points, though, and doesn’t work all the way back across system releases, so don’t do that if you can avoid it. If you want to learn more, see Apple’s thread-safety documentation.

Debugging Assembler on Mac OS X

The thing a programmer probably does most is, unsurprisingly, debugging. Not that programmers necessarily love debugging, but if you don’t have a high pain tolerance for debugging, you probably don’t want to pursue a career in programming. On the other hand, if you like the challenge of the bug hunt, you should try getting into this biz. Or into exterminating. Whatever makes you happy, man.

Anyway, my recent posting on Intel Assembly Language Programming on Mac OS X kinda left you hanging in the air on this one. I didn’t say anything about debugging. Why? Because, honestly, I hadn’t got that far yet. Of course, the first bug didn’t leave me waiting for long, so here’s some handy tools if you want to debug your assembler program.

First, you need to compile your assembler source files with GCC using the -g option. That will give you debug symbols, which means the debugger will show you each line. Once you’ve done that, you just launch GDB, on the command line, as usual:

% gdb path/to/your/executable

You’ll get the GDB prompt you may have already seen in Xcode’s debugger console. Type in

(gdb) start

and it will jump to the start of your main function. GDB will always print the next line, and you can use the step command to execute it and see the next one. Of course, you may want to see what is in a particular register or at a particular memory address. Easy:

(gdb) print/x $eax

will print register eax as hexadecimal (that’s what the ‘/x’ means – there’s also ‘/d’ for decimal, ‘/c’ for character, ‘/s’ for string and ‘/t’ for binary). If you want to view a memory location, you use the ‘x’ command instead.

(gdb) x/1xb $eax

will take the address in $eax, and print 1 byte at that address in hexadecimal. The parts after the slash decode into /<count><displayFormat><type>. displayFormat is the same as the thing after the slash when you print, count is a number indicating how many to print, and type is ‘b’ for byte, ‘h’ for halfword (2 bytes) or ‘w’ for word (4 bytes).

Oh yeah and to get out of gdb again, the command is quit. Happy debugging!

Update: I recently realized I’d omitted two important little tricks from this description: If you don’t have debug symbols, you can still step through code. The relevant commands are

(gdb) si

which steps through code by one instruction (this even works with system functions etc.) and

(gdb) p/i

which disassembles and prints the current instruction.