A Present for Monocle Users

Halfway to Nothing

MacRumors:

9to5mac claims that Apple will reach approximately 5 million in iPhone sales by Macworld San Francisco in January 2008 which would bring them half way to their goal of 10 million iPhones sold by the end of 2008.

No. Apple said they’d sell 10 million iPhones in 2008, “our first full year in the market”. Not that they’d have sold 10 million iPhones by the end of it. Even if you would interpret this to mean Apple’s fiscal 2008 which started in October, the wording in MacRumors’ article doesn’t support this - “reach” implies total units sold ever.

Oh, and as for Think SettlementSecret? There’s no involuntary censorship going on - Apple realized that they might not have a strong chance of winning the suit and sat down to negotiate (if they thought they had a reasonable chance of winning, they wouldn’t negotiate, or at least demand sources). Nick decided to call it a day, cash out and flash a winning grin and mention how the deal didn’t outright suck to any inquiries, and I don’t blame him. It’s a good deal for him but not for Apple - Think Secret’s accuracy/temporary dip in lunacy peaked around the time the lawsuit was initiated.

Cocoa Bindings in Actual Use, Episode Umpteen

So here’s the deal.

Monocle uses a special NSCell to paint the engine’s icon and color in the engine preferences list. That cell is used in a table, and this table’s data (along with the rest of the stuff in the engine preferences) is pulled from an array controller which pulls data directly out of user defaults (I suspect that this is widely considered to be foolish and if any more hinders do show up I might just replan my entire data handling). I think it’s the “user defaults” part that is the root of my worries, or even just the prerequisite binding to contentArray and “Handles Content as Compound Value” option.

The table column is bound to the engine object itself (a dictionary), and this is from where my issues stem. (No, I can’t just simply bind to a property of the model object since it’s an ordinary dictionary, and no, I can’t just bind to one of the two properties; color depends on a third property, which decides if it should make up a color by eyedropping the image or go with the chosen color.)

The problem I’m having is that when I do change the color or icon inside that wonderful direct edit pane that I’ve now inserted into the same panel instead of requiring a trip to the Edit sheet, the cell simply wouldn’t update until I had forced another sort of update or nudge or redraw on the list, presumably since it didn’t pick up on the whole engine object (which is what the column was bound to) updating. Like by changing the selection. Had I had a model object instead of NSDictionary, I would have synthesized an accessor giving me the data I needed from the model, and signalled that it was dependent on the other keys for color and icon info and needed to update whenever they did.

After some deep mulling, I did manage to come up with a solution. I subclassed my array controller - rather, I had already done that for other reasons - and overrode the two init methods: initWithContent: and initWithCoder:. From within them, I called a shared init method which observes its own selection key path with the NSKeyValueObservingOptionNew and NSKeyValueObservingOptionOld options, and then I implemented observeValueForKeyPath:ofObject:change:context:.

Inside observe..., when the selection observation hits, I add observers to the newly selected engine’s properties, as many as I’d like (and remove the corresponding observers for the old selection). When these properties change and I get their observations, in turn, I simply do:

[self willChange:NSKeyValueChangeSetting
    valuesAtIndexes:[self selectionIndexes] forKey:@"arrangedObjects"];
[self didChange:NSKeyValueChangeSetting
    valuesAtIndexes:[self selectionIndexes] forKey:@"arrangedObjects"];

…to force a full nudge of that engine.

It seems to work this far.

Update: I would like to point out that even if the spirit of the way I’m using what I’ve described in this post is clearly a “hack” in my situation - ie. it lets me continue to work with bindings without a special model class and under other questionable circumstances - I dare say that the actual way it’s implemented is clean. This is not something that abuses the way NSArrayController works today in private and will be broken in 10.6 (”Liger”). I’m using KVO itself to go all meta sending observers inside the array controller to itself, and I imagine that this could be useful information for someone running up against the very limits (more ‘legitimately’) of bindings. The only ‘parameters’ are the model property names, which you control, and ’selection’ which is very clearly established API for an object controller or array controller.

Another Good Birthday Present

The 2007-12-12 nightly VLC build comes with a VLC.framework, complete with Objective-C classes (like VLCAudio, VLCMedia, VLCMediaDiscoverer, VLCMediaLibrary, VLCMediaPlayer and VLCTime) and a Cocoa view (VLCVideoView). It’s obviously in its early stages, but there’s promising work being made on VLC’s two biggest Achilles heels: it looks/feels like crap and it’s not embeddable.

Finally, quick, someone make a dual QTKit/VLC.framework player with a sleek GUI.

Update: Apparently this was a VLC Summer of Code project, and there’s an ongoing effort to base the VLC app itself on it.

« Newer posts · Older posts »