Category: OS X


Talking to my self

October 9th, 2007 — 10:21pm

I have code that takes in a string and uses key-value coding to extract a value from an object. It works fine if you want to get a property of an object, but what about getting the object itself? Using nil or an empty string with -valueForKey: or -valueForKeyPath: causes it to call -valueForUndefinedKey: which, by default, throws an exception.

After some diddling around, I found that you can use the key @"self". Doing valueForKey:@"self" on an object returns that object. There’s no magic here. NSObject has a -self method which returns, crazily enough, itself. This is peculiar because on the surface, this method is useless. Anywhere where you can type [anObject self] you can type anObject instead. Where this method comes in handy is in cases where you dynamically call a method/selector, as in KVC, and you want to specify a method that is a short-circuit of sorts.

So, in short, all of the following are equivalent:

someObject
[someObject self]
[someObject valueForKey:@"self"]
[[[someObject valueForKey:@"self"] self] valueForKey:@"self"]

I’m sure someone can use the last one in some Objective-C obfuscation contest.

5 comments » | Cocoa, OS X, Programming

Moving to MarsEdit

September 5th, 2007 — 11:22am

Until now, I’ve always written up my blog posts in a combination of TextEdit for the initial draft and the WordPress web UI for subsequent drafts (mostly to get the formatting right) and final posting. Needless to say, it’s been painful. For a web app, WP isn’t so bad but, in the grand scheme of things, it’s lacking. I know this will probably draw the ire of all of you who think web apps are going to take over the desktop but seriously, it’s not going to happen with the current state of the art (unless users are willing to sacrifice a good bit of usability).

I am now switching over to MarsEdit. Resizable editing area. No html tag buttons whose key equivalents conflict with my use of emacs key bindings. No waiting 10 seconds to preview or save because of a laggy internet or server. The markup macros are editable (so I don’t keep having to type in target="_blank" on every link). The UI is quick and responsive. All the niceties of a native desktop app. Yeah, I’m sure I’ll bump into problems but at least a desktop app can fix most of those. With the web app, there are fundamental problems with the paradigm that make it clumsy and slow.

I know you’re thinking, “well, if the web app sucked so bad, why did you use it?” Simply enough, momentum, or lack thereof. Also, there is my ambivalence towards blogs. I resisted investing in any blogging tools as I didn’t want to admit that I was taking this seriously. I wanted to keep it painful so I would have a reason to hate it. Though now I’m still a bit of a curmudgeon when it comes to blogging, at least I’m willing to concede it’s not worth doing things the hard way.

In any case, MarsEdit 2 is out now. If the thought of writing up a blog post makes you wince, then you should check it out. Who knows, instead of hating it you might end up liking tolerating it.

Oh, and yes, the same Daniel Jalkut who convinced me to start this blog is also responsible for MarsEdit 2. So once again, this is all his fault.

2 comments » | OS X, Software

Numbers and the Next Big Thing

August 15th, 2007 — 1:42pm

I’ve been waiting around for Numbers. Well, not Numbers specifically but for Apple to do a spreadsheet. Now that it’s out, I have to say that I’m disappointed. It’s not about features but about the base paradigm. I wanted Apple to revamp how spreadsheets are perceived and conceived. It may be a bit much to expect from Apple except that the new paradigm was already created some 20 years ago, and not only that, Steve Jobs had a hand in it.

Instead of explaining it all here, I suggest you read about Lotus Improv. Here’s a great article describing the history.

In short, Lotus came out with what is now known as the multidimensional spreadsheet. It was one of the first apps on the NeXT platform. It was also a revolutionary new way of doing spreadsheets.

It’s hard to really get a sense of how it works by reading about it. Quantrix has some great Flash presentations. I advise viewing those before reading on.

The main benefits of a multidimensional spreadsheet is that it actually knows about your model. When constructing a multidimensional spreadsheet, you are not constructing a visual structure so much as a semantic one. Those headers aren’t just for your benefit. The row and column headers are, in effect, axes in your multidimensional model. But you aren’t limited to two dimensions. You can define as many dimensions as you want and dynamically rearrange the axes as you see fit. The order of the axes (which axis is the column and which is the row) is just a part of the view and not the model itself. This also extends to charts. They are just graphical views of the same model and if your model changes, the charts can automatically update as well since they are based on the same semantic structure (i.e. the charts are not just one-offs).

The result of this is that the program makes many things natural and intuitive (it only sounds complicated). For instance, “pivot tables”. In the multidimensional model, it’s a natural extension of the paradigm (there’s no special marketing term for it) which makes pivot tables in traditional spreadsheets look like a hack. Natural language formulas also come, well, naturally. The generic headers and cell designations (A1, C5) are gone. You define the items in the headers so a cell is referenced as “Sales:1990” which makes tons more sense. Also, formulas are more based on the structure of the model and not on individual cells. This allows the formulas to be separated out so you can see (and edit) them all in one place (the formulas don’t go in the cells). Because it is a multidimensional model, extending any one dimension (i.e. adding rows or columns) will bring along any formulas with it. Again, this is hard to visualize if you haven’t seen it before so check out the Flash tours linked above.

So, where are the multidimensional spreadsheets now? Lotus did port Improv to Windows but Improv on both platforms ended up being abandoned. To fill the void, Lighthouse (the company I worked at) created a clone, Quantrix (which I worked on). As I’ve mentioned before, the Lighthouse apps were mothballed by Sun.

Since then, Pete Murray (one of the original authors of Quantrix) wrote it all over again, from scratch in Java, and has released it with his new company. He even got rights to the Quantrix name. As linked above, you can check it out at Quantrix (and thanks to Pete for allowing me to link to his demo presentations). Note that it is not priced for the casual user, being oriented more towards the enterprise customer but they do have educational pricing.

There’s also Flexisheet if you want something free, open source and/or native, though it does not seem to have been worked on in years.

• • •

iWork’s Numbers is fundamentally a 2D spreadsheet. It does some trickery with the headers to allow for some level of natural language formulas. It has some things here and there to simulate some of the aspects of a multidimensional spreadsheet but it’s still a traditional sheet underneath.

One subtle difference between the 2D and multidimensional models is that in the latter, the data model is expected to be dense. What this means you don’t really have unused cells; all cells are intended to have meaning in your model. It’s not a freeform grid but a packed model of data. For people used to sticking all sorts of random non-computational stuff into spreadsheets, this can be hard to adjust to. Basically, people are using spreadsheets not so much as computational tables but as a big piece of graph paper.

Numbers shifts this around a bit by making the tables a part of a larger freeform canvas. This is a big improvement from other traditional spreadsheets as I’ve always believed cells are for numbers. That clip art or paragraph of text you stuck in there is not a part of the model you are creating. It makes it such that the spreadsheet is used as it was intended and anything you attach to it, you put together with it and not in it. All in all, the separation of table and canvas is a welcome change.

Why wasn’t Numbers done as a multidimensional spreadsheet? Several factors come into play here. The main one is that multidimensional spreadsheets are quite different from traditional spreadsheets. If you’re an Excel user then you’d have to unlearn a lot of how you conceive of spreadsheets. In essence, it’s a hard sell to anyone that uses a traditional spreadsheet. The only market where it seems to stick is the financial market, which is not a market Apple is concerned with. It’s too bad, really, since I’ve always felt that the multidimensional model is actually more intuitive for the user who has never touched a spreadsheet. I felt a consumer-level multidimensional spreadsheet would have been the innovation the spreadsheet market needed.

Maybe in the end it was too much to expect of Apple. With innovation comes risk and it’s hard to bet on something that has already failed in the market once. Nonetheless, the innovation is there. The hard part is getting people to use it.

27 comments » | OS X, Software

NoodleLabs: Fix for Mac Pro headphone behavior

July 12th, 2007 — 12:52am

I’ve done it. I’ve joined the 8-core club. Historically, I always shoot for the sweet spot in terms of price/performance but this time I thought I’d splurge for once and get the octocore (or is it octacore?) Mac Pro. Realistically, it’s a bit overkill. Sure, Hazel now compiles 5x faster but it’s not like I’m doing full builds all the time and it didn’t take all that long before either. Nonetheless, it’s a great machine. There’s one thing about it that bugs me, though.

On my Powermac, when I plug in headphones, it automatically switches sound output to them, even if I have external speakers connected to line-out. Basically, the headphones, internal speaker and line-out are treated as three devices sharing a channel. To me, it makes sense. If I plug in my headphones, it’s because I want to listen through them. If I pull them out, it’s because I want audio to go back through the speakers. Most every piece of consumer audio equipment I’ve used operates like this.

On the Mac Pro, that has changed. The line-out is a separate output and is unaffected when you plug in headphones. So, if you are using external speakers, you have to go into System Preferences and manually change the output audio device to headphones. You could use something like Rogue Amoeba’s SoundSource to switch output devices in a more convenient fashion but nonetheless it’s a manual process. This Apple doc describes the change but it sounds like an engineering decision imposing itself on the user. I don’t care if it’s now orthogonal and consistent; I want it to be useful.

Well, the nice thing about being a programmer is that you can solve the problem yourself. So, I went ahead and created headphoned (read it as “headphone-d” like a unix daemon). All it does is sit there and watch for when the headphones are plugged in, at which point it switches audio output automatically. When the headphones are unplugged, output reverts back to whatever device was selected before.

I’ve never touched the CoreAudio API before so please excuse the naiveté of the implementation. Suggestions and improvements are most welcome. A big thanks to Vincent Gable, author of IMLocation for this article which gave me a big headstart.

There seems to be a problem where the audio will wedge when plugging/unplugging. I found that updating with Apple’s recent audio fix got rid of the problem (or maybe it’s wishful thinking on my part but I haven’t experienced it since). If you find it does happen, just plug the headphones in/out again as that usually unwedges things. Also let me know if you experience this even after updating with Apple’s fix.

And, of course, it’s free (MIT License). Do what you will. It’s a bit rough around the edges (no automatic install), but I figure if you are using a Mac Pro, you are less daunted by the command-line. I’ve included a launchd config. Install it in ~/Library/LaunchDaemons and edit it to reflect where you put the executable. Note that it doesn’t seem to work if it runs as root (I think it needs to run as the console user), so don’t bother installing it at the top level LaunchDaemons directories.

Enjoy.

Download headphoned-1.0.zip

Update [Sep. 5, 2007]:

Rogue Amoeba has now integrated this functionality into SoundSource. The announcement is here. You can grab it from their freebies page (and yes, it is free).

21 comments » | Downloads, OS X, Programming, Software

Productive Waste of Time: Figuring out the main thread

May 1st, 2007 — 10:40am

In keeping with my tradition of random experiments of no practical use, I present another edition of “Productive Waste of Time”.

In a Cocoa app, there’s a notion of the main thread. It’s the thread where all events are dispatched. If you don’t create any threads yourself, all your code is going to run in this thread.

The issue of getting a hold of the main thread came up in #macsb. While the Cocoa docs talk a bit about the main thread and what should and should not happen there, they do not give you a way to actually get a handle on it. Daniel Jalkut, whose fault it is for bringing this all up, suggested using pthread_main_np(). While it may work, I looked for a Cocoa-only solution that didn’t assume that pthreads’ notion of a main thread would always align with Cocoa’s.

So, I whipped up this NSThread category to do just that. Just drop it in. No special hooks or hook up needed. It basically just uses -performSelectorOnMainThread:… to set a static var. I didn’t use any locks as I felt the worse that would happen is a bunch of threads set the variable multiple times with the same value. If there’s a subtlety in the memory model that I’m missing here, let me know. Also, if the main thread is tied up, you could potentially tie up other threads as well. Also also, if the main thread exits, I’m guessing bad stuff will happen though it will happen regardless of the code here.

@interface NSThread (MainThreadAdditions)

+ (NSThread *)mainThread;
- (BOOL)isMainThread;

@end

static NSThread		*_mainThread;

@implementation NSThread (MainThreadAdditions)

// Only call this from the main thread.
// Actually, do not call this at all. It is done for you.
+ (void)_setMainThread
{
    _mainThread = [NSThread currentThread];
}

+ (NSThread *)mainThread
{
    if (_mainThread == nil)
    {
        [self performSelectorOnMainThread:@selector(_setMainThread) withObject:nil waitUntilDone:YES];
    }
    return _mainThread;
}


- (BOOL)isMainThread
{
    return [[NSThread currentThread] isEqual:[NSThread mainThread]];
}

@end

Now, why would you need this? Beats me. It came up in discussion and I decided to roll with it. I provide the code here for your use. It is released under the ‘Splain license. This license says you can do whatever you want with this code under the condition that you ‘splain why you need it. Please post here.

Use this code at your own risk. I am not liable for any bad stuff that may happen as the result, directly or indirectly, of using this code. Side-effects may include nausea, dry mouth and brain rash. This is not a suppository.

9 comments » | Cocoa, OS X, Programming

Keeping Dock Clutter Down

April 23rd, 2007 — 11:40pm

That’s right. I’m doing a productivity post. Not sure what is possessing me to do this. I’ll have to make up for it by posting some VAX assembly in my next article (if you send me a snippet, I may post it).

Personally, I like my Dock icons on the larger side which means reducing the number of icons in the Dock. I know for some of you the Dock is like a trophy case, but for the rest of us, here are some basic tips for cleaning out the Dock.

Also, this is a post for people who use the Dock. If you don’t like the Dock, good for you. Go write your own article.

Pull Dashboard out.

Did you know that you could remove Dashboard from the Dock? Just drag it out. This doesn’t disable it. F12 can still be used to bring it up. Since I never clicked on its Dock icon, it’s a wasted spot, but at least it’s easily regained. Thanks to Brian Cooke at Roobasoft for showing me this at WWDC last year.

Keep “viewers” out of the Dock.

There are certain apps you never really launch directly. They only get launched when you open one of their documents. Good candidates are apps which are primarily meant to just view a file. QuickTime Player and Preview come to mind. I almost never launch them directly but instead launch them by double-clicking a movie or pic in Finder. Pull those out of your Dock. They’ll appear there when you open their documents but when they are not running, save some Dock space and quit them.

The Dock is for the Everyday.

Look at your Dock now. What isn’t running? When’s the last time you ran it? Do a “Get Info” on the app in Finder and check the “Last opened” time. Basically, every app in your Dock should be running and if it isn’t, it should be run sometime today. If not, then poof it. In my case, I don’t actually use Keynote or Pages all that often so finding them in my Applications folder when I need to run them every now and then is no big deal (or I could use Quicksilver. See the last point).

Replace less used apps with a folder.

You can stick arbitrary folders on the right side (or bottom part for you vertical Dockers) of the Dock. Stick your Applications folder there or, if you want to be more precise, create a folder with aliases to a subset of your apps and stick that in your Dock. Of course, you need to do this in exchange for taking some apps out of the Dock otherwise you don’t gain any space.

If you miniaturize windows, get in the habit of hiding apps.

Those miniaturized windows take up space on the Dock. Hiding the app hides them as well. They’ll come back when you switch back to the app.

Use 3rd party software.

There’s a bunch of third party software such as Overflow and Quicksilver that you can use to either extend the Dock or obviate/lessen the need for it.

• • • 

Nothing earth-shattering here but maybe useful to someone. I still have a bunch of icons in my Dock but at least I can say that they are all in use.

4 comments » | OS X

A Modest Proposal: A New Way To Install

April 15th, 2007 — 10:40pm

Currently, there are two main ways that Mac software is packaged. There are Installer packages and there are apps that you just drag and drop into their install location (usually /Applications). The latter has come into favor in Mac ISV circles because of a dislike of the former.

There are various reasons why some people dislike Installer packages. There is the perception that the software is not self-contained and that the installer can run random scripts and do weird things to your permissions. In contrast, taking a self contained bundle and dropping it in your Applications folder seems tidy, controlled and predictable. Nevertheless, it seems that there are a large number of users for whom this does not work. Now, the evidence I have is anecdotal (i.e. stories of people’s less technically savvy relatives and such) so take it as you will.

It seems as if the “drag app into App folder” style of installation is not as intuitive as many developers think. Even with instructions shown in the DMG background image, I’ve heard numerous stories of users running the app directly from the disk image indefinitely. The notion of installing the app is not clear to them. It seems that whatever icon is there just gets double-clicked. They do not care about installing your software. They want to run your software.

If that is the case, then when presenting user with your software, you have one chance to do what you need to do and that is when the user double-clicks on whatever icon you present. It appears that anything more involved will not be followed by many users.

In some ways, then, Installer packages are more ideal. The user will double-click them and are then led through the install process. But, as mentioned previously, the power-user segment is not found of Installer packages plus after the install, the user must still find the application and run it.

Now, let’s look at preference panes. When you double-click a preference pane file, you are asked where to install it and after that, it starts up System Preferences with your pane loaded. Simple. It does what you, the developer, want (get the app off the disk image and onto the user’s system) and what they, the users, want (which is just to run the thing).

My suggestion? When your app launches for the first time, check to see if it’s on a disk image. If so, offer to install it for them. If they accept, you copy it to Applications or wherever and restart. Done and done.

Of course there are details to figure out. To detect if you are running of a disk image, I suggest maybe playing with NSWorkspace’s -getFileSystemInfoForPath:isRemovable:isWritable:isUnmountable:description:type: method. My guess is that an unwritable, removable and ejectable filesystem is sufficient to identify it as some sort of distribution medium but feel free to refine this and let me know. Also, you would have to deal with the situation of the app already being installed and such but these are all surmountable.

So, my proposal is for all you app-writing people to use this type of install. It’s straightforward and benefits both developers and users. Additionally, unlike someone else’s modest proposal, no children will have to be eaten (I’ll leave it to you to decide whether that is a good or bad thing).

If anyone already does this (I feel someone must have come up with this already), please let me know. I’m curious as to your experiences with it. Lastly, but not leastly, thanks go to the #macsb channel for the discussions on the topic.

Update:

I’ve had a few discussions with different devs via different channels on the topic. The one that carried the most weight was the email exchange I had with Dave Nanian. He’s the author of Super Duper which already does what I have proposed here. It appears that from his experiences, there is still confusion even with using this approach. It appears that users still are confused with disk images and end up copying them to their app folder as if they were the app itself. I’ll leave it to him to expound on this when he has time but seeing as this is empirical evidence, maybe people should consider internet enabled disk images.

For the record, this isn’t something I would have needed for my own product. Being a preference pane, System Preference’s way of automatically installing has provided for a smooth and trouble-free experience. Actually, I can see using internet-enabled disk images as being a liability for preference panes as it deposits the pane in your downloads folder tempting users to keep double-clicking it to launch it, installing it over and over again. So, I’m not the best person to spearhead this effort as I lack the actual need for it. While there is the “for the betterment of humanity”-type motivation, I feel someone else who is dealing with actual support emails on the topic should take up the cause.

In the end, you should assess the situation as it pertains to your own product. As mentioned in the comments. Rainer Brockerhoff’s PathProps category on NSWorkspace would be useful for anyone looking into implementing this. I’ve played around with it and it seems to work as advertised.

Thanks to all for the great feedback and comments.

Update #2 (May 25, 2007):

Just got a note from Michael Nickerson who has just released a framework for this. You can read all about it here.

53 comments » | OS X, Software

Mystery Bug: Heisenberg’s Uncertainty Principle

March 7th, 2007 — 6:59pm

I’ve spent the past couple hours going crazy over a bug. It’s the type of bug where it breaks except for when you look at it, in which case, it works all the time. Don’t believe me? Compile the following program:

#import <Foundation/Foundation.h>

int main(int argc, const char *argv[])
{
    NSAutoreleasePool     *pool;
    NSString              *path;
    NSDictionary          *dict;
  
    pool = [[NSAutoreleasePool alloc] init];
    path = [NSString stringWithUTF8String:argv[1]];
  
    dict = [[NSFileManager defaultManager] fileAttributesAtPath:path
                                         traverseLink:NO];

    // The busy flag will be NULL if you comment out the next line.
    //NSLog(@"DICT: %@", dict);

    NSLog(@"Creation: %@", [dict objectForKey:NSFileCreationDate]);
    NSLog(@"Busy: %@", [dict objectForKey:NSFileBusy]);
}


By the way, I know I’m not releasing the pool.

Now, take a file and set its busy flag. You can do this as follows:

/Developer/Tools/SetFile -a Z some file

Then run my little program with some file as an argument. Notice how the busy flag is null?

Well, let’s see what’s in the dictionary passed back to us to find out what’s going wrong here. Edit the program above to uncomment the NSLog statement. Run it again. Notice how the busy flag is now set?

It appears that the dictionary is half-initialized until you happen to call certain methods (-allKeys works as well as -description). I haven’t tested every key but it does seem to be peculiar to NSFileBusy.

For the time being, I’m going to switch to Carbon to do this but I’d love to hear theories (or even facts) on what’s going on here. Let the wild speculation begin.

Oh, and since I brought up Heisenberg, I can’t let an opportunity to include an artful rendering of a dead cat pass by so here:

dead cat

6 comments » | Carbon, Cocoa, Debugging, OS X, Programming

NoodleLabs: Super Duper Menu Bar Icon Tester Thing

February 17th, 2007 — 12:54pm

My graphic designer is working on a menu bar icon for the next version of Hazel. The problem is that it’s hard to visualize them in situ. To aid my designer in this regard, I threw together a quick little proggie. It’s just a simple program that has a menu bar icon. It provides a controls where you can edit NSStatusItem settings as well as image wells into which you can drag icons. The status item updates so you can see your icons in their natural habitat.

StatusItemTester Screen

I also added an image well where you can test out app icons to see how they look in the dock.

Source (what very little there is) and binary included. MIT license. Valentine’s Day has passed but it’s never too late to show your designer a little love.

Download: Status Item Tester

2 comments » | Cocoa, Downloads, Icons, OS X

Search and Replace in Xcode

January 27th, 2007 — 5:59pm

This issue came up twice in the past couple weeks thus triggering my rule that if something comes up more than once then others may be interested in it. So, here’s a little tip that may save you some frustration.

When using regular expressions with Xcode’s search, the docs mention that XCode uses the ICU library. Naturally, you’d think it would use ICU’s syntax for specifying backreferences in the replace string, which would be to use variables consisting of a dollar sign ($) followed by the number of the capture group being referenced.

Of course, if that were the case, I probably wouldn’t be writing this tip. Using $ for backreferences turns “Search & Replace” into “Search & Destroy”. The syntax is to use backslash (\) instead of dollar sign. In short, \1 instead of $1.

Type the following in an Xcode editor window: “$1 works in replace strings.”

Now perform the following search & replace:

find-replace-crop.png

Ok, maybe this example makes things more confusing. If in doubt, just remember: $ = bad, \ = good in Xcode Find panel.

As to why Xcode does not use the ICU syntax in the replace strings, beats me. If anyone has a simple explanation, send it my way though I also welcome apocryphal anecdotes and crackpot conspiracy theories (extra points if you can convincingly implicate the Trilateral Commission).

11 comments » | OS X, Programming, Software, Xcode

Back to top