Vincent Gable’s Blog

July 7, 2008

Getting OS X Icons

Filed under: Design,MacOSX,Programming,Reverse Engineering,Usability | ,
― Vincent Gable on July 7, 2008

This is what the Apple HIG has to say about icons. You should read it if you ever use icons. Even if you are not drawing your own icons, you need to understand how they should be used. (eg: icons in a toolbar should have a flat “head on” perspective, not the three-demensional look they have in the Dock.) You’ll find the icons you need faster if you know what they should look like.

Websites with icons you can use freely: IconDrawer, Iconfactory, Kombine.net.

SystemIconViewer (source included) by Noodlesoft is a useful tool. It lets you browse over 100 standard OS X icons that are available programatically.

For getting paths to private OS X icons, try poking around inside CandyBar.app — A commercial program that lets you customize just about any icon on your system. As of v2.6.1 /CandyBar.app/Contents/Resources/English.lproj/IconData.plist contains information on where icons are located. Icon locations do change completely between releases of OS X, even if the icon itself does not! I found CandyBar to be a better source of up-to-date icon locations then google. IconData.plist is pretty big and dense, but you can search it for keywords if you open it in Xcode, which helped me a lot.

(Although I haven’t used any of them personally, these are some design firms Apple recommends, if you have the cash.)

Programatically Excluding Things from Time Machine Backups

Filed under: Cocoa,MacOSX,Objective-C,Programming,UNIX | , ,
― Vincent Gable on July 7, 2008

To exclude files/folders from a Time Machine backup, you can use the C-function CSBackupSetItemExcluded().

As far as I know there isn’t an official way to do this from the command-line or a shell script. As near as I can tell, the safest way to it without using compiled C-code is:

sudo defaults write /Library/Preferences/com.apple.TimeMachine \
SkipPaths -array-add "PATH-ONE" "PATH-TWO"

where "PATH-ONE" "PATH-TWO" are of course paths to items you want to exclude.

Credit to Ellis Jordan Bojar for this solution. (original article) Using defaults instead of tinkering with .plist files directly is really the way to go!

July 5, 2008

FourCharCode2NSString

Filed under: MacOSX,Objective-C,Programming,Sample Code,Usability | , , ,
― Vincent Gable on July 5, 2008

As I have written before, the best way to convert a FourCharCode to an NSString* for NSLog()ing is to use the NSFileTypeForHFSTypeCode() function. But for the life of me I can’t remember that name, even though I use it about once a month. It’s too long, and it has too little to do with what I’m using it for.

So I have added the line:
#define FourCharCode2NSString(err) NSFileTypeForHFSTypeCode(err)
To my prefix-files, because I can remember FourCharCode2NSString().

UPDATE: (2008-08-06) There is an even easier way.

-dealloc Warning

Filed under: Bug Bite,Cocoa,MacOSX,Objective-C,Programming |
― Vincent Gable on July 5, 2008

The only time you should call ever call -dealloc in Objective-C is on the last line of your own -dealloc method. This call should be [super dealloc];. The proper way to dispose of an object is to send it a -release message — -dealloc will then be called if appropriate.

Now when I was first learning Cocoa, I sometimes disposed of objects by calling -dealloc directly. This caused all sorts of problems. Truth be known, if I’ve been messing with several object’s -dealloc methods, I’ll sometimes dyslex out and type dealloc when I mean release, just because it’s more fresh in my head. This is very rare, but it has happened once, and will happen again. I’m fallible like that. Murphy’s law tells us that I won’t catch it every time.

So I humbly propose that GCC should warn you if you use -dealloc any way other then calling [super dealloc]; on the last line of your own -dealloc methods.

Missing Frameworks

Filed under: Bug Bite,Cocoa,MacOSX,Objective-C,Programming | , ,
― Vincent Gable on July 5, 2008

I tried using an AMWorkflowView in a project, but when I ran it, I would crash with the following printed to the console:


*** Terminating app due to uncaught exception ‘NSInvalidUnarchiveOperationException’, reason: ‘*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (AMWorkflowView)’

It turns out I just forgot to include Automator.framework in my project!

It turns out that you also have to include Automator.framework to use any OSAScriptView objects.

I hope this helps someone who googles the error message :-).

July 3, 2008

NSApplicationName Inconsistencies

Filed under: Bug Bite,Cocoa,MacOSX,Objective-C,Programming,Sample Code | , , ,
― Vincent Gable on July 3, 2008

The value stored under the NSApplicationName key of the result of [[NSWorkspace sharedWorkspace] activeApplication] is not the always the name the user knows the application by. Worse, it’s not always the same as the name for the application that other APIs expect or return. Even fullPathForApplication: in NSWorkspace sometimes won’t recognize it!

The problem stems from the fact that there are at least five application names floating around, at least in concept: (1) the file name the Finder sees, which in the case of an application package is the package (bundle) name; (2) the name of the executable inside the package, (3) the long name used in many places for display purposes only; (4) the short name used as the application menu title and in a few other places where a long name won’t fit for display purposes; and (5) the process name of a running application. They aren’t always the same, especially in Microsoft and Adobe products.

–From an informative message by Bill Cheeseman.

So instead of relying on NSApplicationName I now use -[[NSFileManager defaultManager] displayNameAtPath:] then strip off the filename extension. This should give exactly the filename the user sees. Every time.


NSDictionary *appInfo = [[NSWorkspace sharedWorkspace] activeApplication];
NSString *appPath = [appInfo objectForKey:@"NSApplicationPath"];
NSString *name = [[[NSFileManager defaultManager] displayNameAtPath:appPath] stringByDeletingPathExtension];

And of course, you really should be using bundle identifiers, instead of names, to identify an application. Unfortunately, a very few applications are not bundles. (For example, Microsoft stuff prior to Office 2008), so it might be necessary to fall back on using a name to locate them in a path-independent way.

Creating a custom CFBundleName in an application’s info.plist file seems to confuse NSApplicationName. For this reason I don’t think setting it is a good idea.

UPDATE 2010-01-20: See also, Technical Q&A QA1544: Obtaining the localized application name in Cocoa

Learning From Other People’s Failures: Acrobat Reader 9

Filed under: MacOSX,Usability | , ,
― Vincent Gable on July 3, 2008

Epic Fail.

The PC version is awful too.

June 20, 2008

Modern Browsers

Filed under: MacOSX,Programming,Quotes | , , , ,
― Vincent Gable on June 20, 2008

… What struck me watching these (WebKit) demos is that you could build a really slick web app UI using stuff like the canvas tag, SVG, and advanced CSS. Yes, none of this stuff works in IE, and IE still has massive market share — but not among the sort of people who adopt hip new web apps. The combined market share for, say, Firefox 3 and Safari 3 is larger than the overall market share for Mac OS X. Plenty of developers write desktop software that only works on the Mac — why aren’t more people writing apps web apps that only work in truly modern web browsers? The first one to do it is going to be a sensation.

John Grubber

I didn’t have a sense for how far behind IE lags, historically and today, until I saw this compatibility table (via Toby Jungen),

Calculation of support of currently displayed feature lists

Internet Explorer Firefox Safari Chrome Opera
Far Past 6.0: 4% 2.0: 34% 3.1: 43% 0.2: 54% 9.0: 35%
Past 7.0: 12% 2.0: 34% 3.1: 43% 0.2: 54% 9.0: 35%
Present 8.0: 29% 3.0: 48% 3.2: 67% 1.0: 54% 9.6: 58%
Near Future (2009) 8.0: 29% 3.5: 78% 4.0: 88% 2.0: 84% 10.0: 63%
Future (2010 or later) 9.0: 29% 4.0: 86% 4.*: 88% 2.0: 84% 10.*: 72%

June 17, 2008

Every OS Sucks

Filed under: MacOSX,Programming,Usability |
― Vincent Gable on June 17, 2008

Funny, and true, video.

June 16, 2008

Hold off on Upgrading QuickTime to Version 7.5

Filed under: Announcement,MacOSX,Tips |
― Vincent Gable on June 16, 2008

The QuickTime 7.5 update appears to have broken sound in VMWare Fusion, and also in some code I’m working on. I will know more once I have fixed the issue in my own code. But for now, I advise waiting to update QuickTime to version 7.5.

UPDATE 2008-06-19: problems in my code solved. Basically I was specifying a bit-rate for a compressed audio stream, and QuickTime expected it to be 0. Earlier versions of QuickTime didn’t care, but 7.5 was more strict. Also, the VMWare problems have been fixed.

« Newer PostsOlder Posts »

Powered by WordPress