Vincent Gable’s Blog

August 14, 2008

Only Skin Deep…

Filed under: Design,MacOSX | , ,
― Vincent Gable on August 14, 2008

Pictures showing that a nerds desktop can look like other operating-systems … at least from a few feet away.

It’s a good reminder that design is not just skin deep.

August 13, 2008

Quickly Switching Between Headers and Source Files in Xcode

Filed under: MacOSX,Programming,Tips |
― Vincent Gable on August 13, 2008

Command + Option + Up-arrow will switch between a header and source-code file in Xcode. I wish I had figured this out years ago.

August 12, 2008

Dude, Where’s my Gun?

Filed under: Announcement | ,
― Vincent Gable on August 12, 2008

Last weekend I watched National Treasure 2: Book of Secrets. I don’t recommend it.

But there is one, unintentionally, interesting scene. About one hour and 17 minutes into the movie, the police rush into the Library of Congress (chasing the man who kidnapped the president of course). Interestingly, there were no (fake) guns in any of the scenes inside the Library of Congress. The actors rushed in pointing their fingers!
Look ma, no guns!
Look carefully at this policeman’s hands, he’s holding them in a “low ready” position as if he were carrying a pistol, but there’s nothing there.

I guess they thought nobody would notice, and according to google, they were right so far.

If anyone has a high-definition copy of the movie, and can extract that one scene, I would appreciate it. A picture just doesn’t show it all (although a grainy video is worse).

Aesthetics Matter

Filed under: Accessibility,Design,Quotes,Usability | , ,
― Vincent Gable on August 12, 2008

.. aesthetics (are) important in UI. If you begin to look at something and want to avert your eyes, the site has failed.

Hank Williams

I highly recommend the book Emotional Design, which makes this point in much more detail. A person’s emotional state has a quantifiable impact on how successful they will be at a task. Aesthetics are still the most direct way to manipulate emotion.

Make What You Love

Filed under: Quotes |
― Vincent Gable on August 12, 2008

If you can’t think of anything in your company’s “space” that you personally would use, then you should think seriously about (a) changing your company’s direction, or (b) finding another company. This is true no matter what level you’re at. You should be working on something you love, or failing that, at least working on something that you know really well.

Steve Yegge

August 11, 2008

Internal Microphones are OK

Filed under: Announcement
― Vincent Gable on August 11, 2008

Laptop’s built-in microphones, even on pretty cheap laptops, do a surprisingly decent job of recording talks. At least that’s the word on the street.

August 6, 2008

Distorting Text for Readability?

Filed under: Design,Usability | ,
― Vincent Gable on August 6, 2008

This is an award winning example. Compared to traditional “flat” text, the distorted text is certainly striking, looks more three-dimensional, and since it’s drawn on top of objects that would normally obscure signage it’s larger. But it can only be seen correctly from a few angles.

This example from 1939 looks a little confusing — more like a POTS sign then a STOP sign.

August 5, 2008

Simplified Logging

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

I have noticed a pattern in my Cocoa code, which I have been able to simplify. I often print out the value of a variable for debugging. 99 times out of 100, the code looks like this: NSLog(@"actionURL = %@", actionURL);, where actionURL is some variable.

But using the macros, I can say LOG_ID(actionURL);. This is shorter, and non-repetitive.

The macros I use to simplify debugging (2008-09-16):

#define FourCharCode2NSString(err) NSFileTypeForHFSTypeCode(err)

#define LOG_4CC(x) NSLog(@"%s = %@", # x, FourCharCode2NSString(x))
#define LOG_FUNCTION() NSLog(@"%s", __FUNCTION__)
#define LOG_ID(o) NSLog(@"%s = %@", # o, o)
#define LOG_INT(i) NSLog(@"%s = %d", # i, i)
#define LOG_INT64(ll) NSLog(@"%s = %lld", # ll, ll)
#define LOG_FLOAT(f) NSLog(@"%s = %f", # f, f)
#define LOG_LONG_FLOAT(f) NSLog(@"%s = %Lf", # f, f)
#define LOG_OBJECT(o) LOG_ID(o)
#define LOG_POINT(p) NSLog(@"%s = %@", # p, NSStringFromPoint(p))
#define LOG_RECT(r) NSLog(@"%s = %@", # r, NSStringFromRect(r))
#define LOG_SIZE(s) NSLog(@"%s = %@", # s, NSStringFromSize(s))

Look in assert.h for insight on how to roll your own debugging macros.

Neat iSight Trick

Filed under: MacOSX,Tips |
― Vincent Gable on August 5, 2008

Your iSight camera can see into the IR spectrum. You can see the invisible IR light on your remote control if you watch it thought your iSight.

August 3, 2008

How to Implement Automatic Updating

Filed under: Cocoa,Design,MacOSX,Objective-C,Programming,Sample Code,Usability
― Vincent Gable on August 3, 2008

If you are about to add automatic updating to your application (and you should), then check out the Sparkle Framework before you start. I wish I had done this before I spent a lot of time writing my own automatic updating code.

A quick-and-dirty hack.

Get your application’s version number by:
[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"];
(This articles explains setting up Xcode to bake the current subversion-number into every build.)

Get the the latest version number out of a text-file on a website:
[NSString stringWithContentsOfURL:[NSURL URLWithString:@"www.your-url-here.com/whaterver/version.txt" encoding:NSASCIIStringEncoding error:nil]];
If there is any trouble, it will return nil. CAUTION: This will block the main thread for up to 30 seconds, while -stringWithContentsOfURL: tries to access the URL.

Making it Usable

If you don’t want your program to be unresponsive while it tries to get something off the internet, try this:

- (void) updatesReady
{
   //do something....
}

- (void) synchronousCheck
{
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

   NSURL* latestURL = [NSURL URLWithString:@"http://www.your-url-here.com/currentversion.txt"];
   NSString* latestVersion = [NSString stringWithContentsOfURL:latestURL encoding:NSASCIIStringEncoding error:nil];
   //latestVersion will be nil if there trouble was accessing latestURL.

   NSString* ourVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"];
   if([ourVersion isLessThan: latestVersion])
      [self performSelectorOnMainThread:@selector(updatesReady) withObject:nil waitUntilDone:YES];

   [pool drain];
}

//will call updatesReady iff a new version is ready, otherwise does nothing.
- (void) checkForUpdates
{
   [NSThread detachNewThreadSelector:@selector(synchronousCheck) toTarget:self withObject:nil];
}

A few thoughts on automatic updating:

When the user explicitly runs an update-check, they should get immediate feedback that something happened. You should put up a window with a spinner. Even though checking for updates may only take 100msec in your lab, if the user is on a flakey wireless connection while traveling, it could take several seconds for them.

It feels like it takes several years for an HTTP fetch to time out, if you can’t do anything while you wait.

Anything having to do with threads is harder then it looks.

“Check for updates {daily, weekly, monthly}” is a useless preference. Just because Apple’s Software Update has it does not mean you should offer those choices! They do not give the user any real control over when and how they are annoyed by requests to update. Users don’t care when the update checks are performed — they only care when new software is announced to them. Ether go with the a simple check-box that toggles automatic updating, or go with something like:
“Let me know about new software: at 12 PM”.

Display the date of the last successful update check, never display “Last Update Monday 9AM — update failed”. (This should be obvious, but I see it all the time). Version checking should be silent and unobtrusive. Don’t tell the user about it — only tell them about results.

Automatically downloading updates in the background is a great idea if they are small, and the computer has a reasonably fast internet connection.

You might also want to check out: NiftyFeatures 0.4 By Uli Kusterer .

An example project containing two classes, UKUpdateChecker and UKFeedbackProvider that can be plugged into your applications to add “Check for Update…” and “Send Feedback…” menu items to your applications.

« Newer Posts

Powered by WordPress