The Register® — Biting the hand that feeds IT

Feeds

Uncle Mac takes A Cup of Cold Cocoa...

A first diatribe from the Grumpy Old Man

Agentless Backup is Not a Myth

'Twas the night after Christmas. The left-over turkey had been stuffed into the freezer, the surplus mince pies stuffed into the dog, and my thoughts turned once more to programming – Mac programming. Seduced, as ever, by the Aqua interface, I decided it was time to write that killer Mac utility, the proceeds from which would magically transport me to balmier climes, somewhere where the air was redolent with spices rather than day-old sage & onion stuffing…

I fired up XCode, created a new Cocoa application and launched Interface Builder (IB) to begin my user interface design. Dropping a NSTableView control onto the new window, I looked around eagerly for IB’s equivalent of the Delphi Property Inspector so that I could set the table to automatically perform a column-based sort, just like the Apple Finder does. While I was at it, I also wanted to set some kind of AcceptDroppedFiles property so that users could drop files directly onto the table.

Note: No, I’m not going to tell you what my killer Mac utility does, or you just might get there first. As far as balmier climes are concerned, my need is greater than yours, ok?

Well, guess what? Interface Builder doesn’t have a Property Inspector. An Inspector window, yes, but not a property Inspector window. This is very possibly because Cocoa objects don’t actually have properties. In fairness, the upcoming new release of Objective-C 2.0 (in Leopard) will have property support. (See the info here, which has been gleaned from an inspection of Apple’s branch of the GCC sources).

Of course, we Delphi and C# developers understand that a property is usually just syntactic sugar-coating around a method call, right? So presumably, there are methods (errr...sorry…messages) which will give me auto-sort tables and file drop facilities, right?

Nope. If you want such user-interface baubles, you must do the job yourself. In the case of auto-sort tables, you have to respond to a snappily-named tableView:didClickTableColumn: message (and compared to a lot of Cocoa messages, that’s pretty damn snappy!) which, if all this stuff were written in Delphi, would probably be an OnColumnClicked event. You then need to display a little sort glyph (up or down pointing arrow) in the appropriate column header, and reverse the sort order if the user just clicked the column header that’s already sorted - IYSWIM.

Naturally, Apple doesn’t provide the images for you to do this. Well, it does, but they’re undocumented. You can adopt the really dirty approach using the internal, undocumented _defaultTableHeaderReverseSortImage and _defaultTableHeaderSortImage messages to get the images; or you can be a purist and create your own custom glyphs from scratch. I didn’t want to get dirty, and I don’t have the artistic skills to “do it proper”, so I cheated and used “NSAscendingSortIndicator” and “NSDescendingSortIndicator” as parameters to the NSImage imageNamed: message. That particular wheeze is documented, but… not by Apple. I won’t bore you with the details of the sort itself. Suffice to say that the NSTableView won’t do it for you.

And then there’s file dropping. Once you’ve registered your table to receive filename drops, you then need to give the thumbs-up once a file drop operation is under way. This is done using the code below. Now you see why I referred to tableView:didClickTableColumn: as being snappily-named!

// Called to validate a file drag-over operation 

- (NSDragOperation) 
tableView: (NSTableView *) tv 
validateDrop: (id <NSDraggingInfo>)info 
proposedRow: (int) row 
proposedDropOperation: (NSTableViewDropOperation) 
operation
{
        [self setDropRow: -1 
        dropOperation: NSTableViewDropOn];
        return NSDragOperationCopy;
}

When it comes to hooking up the user interface to your actual Objective-C code, you’re suddenly thrown into the bizarre world of outlets and actions. Maybe I’m dim, but I had to read three Cocoa programming books before I finally found a reasonably cogent explanation of this. Again, in Delphi or C# terms, an “action” is simply an event handler; a method that gets triggered (if you prefer, a message that gets sent) when some user interface event takes place. An outlet, on the other hand, is an object instance variable which connects the code back to the user interface – it allows your Objective-C code to reference a particular pushbutton, checkbox, or whatever. Fundamentally, actions map from interface to code, while outlets map from code to interface.

The reason for this strange dichotomy between interface and code is pretty obvious; XCode, the Objective-C IDE, understands code rather than visual interface layout; while Interface Builder, as the name suggests, understands interfaces and not code. To put it bluntly, XCode desperately (and I do mean desperately!) needs an integrated form designer. Imagine being able to drop a pushbutton control onto a form, double-click it and – bang! – there you are in the code editor, with an insertion caret inside your event handler. Imagine not having to “introduce” your code to each element of your user interface design. Alas, such joys are entirely unknown to Cocoa programmers; as perhaps, are the joys of terse method names.

OK, I’m being a little tongue in cheek here, but I really think that if the average Cocoa programmer spent some time with Delphi, s/he’d be totally blown away. Naturally, our average Cocoa programmer wouldn’t agree with this assertion. For example, Cocoa programmers brag about these wonderful things called NIBs (an ancient acronym for NeXTstep Interface Builder) which we’re told allow user interface objects to be “freeze-dried”. Ever heard of DFM files? Delphi 1.0 has had ‘em since 1995. OK, I’ll concede that NeXTstep and NIBs have been around for even longer than that, but the essential point is that Delphi, C#, (even VB.NET!) achieve much better synergy between code and form design than does Cocoa.

There’s a whole bunch of other stuff I could talk about here, such as the component-based architecture of Delphi and .NET, which compares starkly with the monolithic nature of Cocoa, but hopefully you’re getting my drift. I’m a big fan of the Mac, and I’m a big fan of much of the intuitive, powerful but easy-to-use software that’s available for OS X. But more than all that, I’m a huge fan of the dedicated Mac developers who have achieved so much with – frankly – so little.

If you’re a dedicated Cocoa-head, you’ve probably had it drilled into you that Cocoa is your “secret weapon”. Compared to Carbon, it certainly is. But everything’s relative, and I’m really looking forward to seeing what the Mac community can achieve when they finally get some decent development tools. When will Interface Builder and XCode finally tie the knot? Not in Leopard, for sure, but maybe in what comes next? Here’s hoping…

Now if you'll excuse me, I have a killer Mac application to write…

Regcast training : Hyper-V 3.0, VM high availability and disaster recovery

Latest Comments
Anonymous Coward

RE: Controls

> I mean the default widget set provided by Microsoft.

> If I need to go to a 3rd party web site to download

> an extra control just to achieve a very common task

> then that highlights an omission in the framework.

hi Tim. I'd agree with that. But equally, I think that some of the issues I've outlined also point to omissions in the Cocoa framework. Richy's great tutorial on the wiredupandfiredup web site highlighted that even with an NSArrayController, automatic sorting of new entries doesn't happen for free. With Delphi (for instance), I can create a

TStringList object, set its Sorted property to True, and anything I throw into it is sorted automatically. Why is this so klunky with Cocoa?

> My personal peeve with Obj-C is it's lack of

> operator overloading.

I agree with that. Because ObjC isn't C++, it misses out on goodies such as operator overloading which I think is a shame.

> I also have an ADC account, but not a dual layer DVD

> burner. So I can't burn the Leopard disc image to

> DVD to try it out. The only thing I've done with

> Leopard so far is read through some of the docs on

> the ADC site.

Actually, you *can* install Leopard without a dual-layer burner. There are instructions on how to do this on the ADC web site. Download "Leopard Client 9A321 Seed Note" and read it carefully. Basically you need to create a couple of partitions on your HD, use Disk Utility to restore the Install DVD into a small partition, boot from that, and then install Leopard onto whichever other parition you want to use. I use this method all the time: it's slightly long-winded, but it means you're not forever burning expensive dual-layered media.

Hope that helps,

Uncle Mac

0
0

Controls

>When you say "Windows controls", which ones are you talking about?

I mean the default widget set provided by Microsoft. If I need to go to a 3rd party web site to download an extra control just to achieve a very common task then that highlights an omission in the framework.

.Net makes it easy to create a scrollable content area. But it's hard to create a scrollable content area that has syncronised views to act as a header, or rulers to the main scroll view. I shouldn't have to roll my own solution or buy in someone elses.

The functionality and flexibility of the Apple provided controls far exceeds that of .Net and it's precursors. That said there is a huge 3rd party market for ActiveX controls covering the major omissions and more. Some are free, some aren't, some come with strange licensing agreements that need to be taken into account.

So for the want of a set of ruler bars, I spent a morning trawling the Internet looking for other's saying the needed the same thing. Hours looking through code snippets that didn't work properly. More time looking for appropriate ready made control, then looking at licenses.

Maybe there's a better way of doing this stuff, but I sure didn't feel at all productive while doing this. Considering I was just creating a simple graphical profiling tool for a multi-threaded VBScript engine we use so I could see how the various scripts were interacting, I just gave up and stuck the heading info in tooltips as you moused over sections.

I think in part a software engineer's take on software design and frameworks is going to be shaped by their route to learning OO development. My first formal education in object orientated development was in Smalltalk. I've found a home with Objective-C and Cocoa and find it comfortable. C++/MFC+GDI, Java/Swing and C#/.Net just aren't to me.

My personal peeve with Obj-C is it's lack of operator overloading.

I also have an ADC account, but not a dual layer DVD burner. So I can't burn the Leopard disc image to DVD to try it out. The only thing I've done with Leopard so far is read through some of the docs on the ADC site.

0
0

RE: Doing it the hard way

Thanks for that, Tim - lots of good comments there.

> Sure you can use the documentation for NSTableView

> and suporting classes to work out how to populate

> a table with data and sort it. But it would be a

> whole lot easier to use Cocoa Bindings.

Briefly, I'm deliberately *not* using Cocoa Bindings because I want to get to grips with 'barefoot Cocoa' itself first. I appreciate that some of this stuff can be simplified with CB, but - on a personal level - I want to thoroughly understand Cocoa itself, and how it's built on top of Carbon, before introducing an additional level of abstraction.

> You don't need properties. Allowing direct access

> to object data breaks the concept of encapsulation.

> Otherwise they are just accessor methods to the data.

Properties don't break encapsulation. But they are a more convenient way of doing things, if only from a syntactic sugar point of view. This is why Apple are introducing properties in ObjC 2.0 with Leopard. That said, I doubt that Apple will retrospectively "propertize" (for want of a better word!) the existing Appkit framework.

> The inspector palette is the equivalent of a

> property palette. If you create your own custom

> controls then you can also create a IBPalette plug-in

> so others can easily configure and use it within IB.

Yes - that's all understood. My point was that XCode/IB are not oriented towards component-based design. With Delphi or C# (for example), you create your new custom control and the job is done. With XCode/IB, you create your control, and you then *THEN* have to go through the completely separate process of creating an IB plug-in for it.

Why is this extra step needed? In one word, metadata. XCode/IB does not have a reflection mechanism whereby the properties/events of a new control can be interrogated and automatically displayed on the component palette. It is incredibly crude compared to .NET or VCL technologies.

> IB has many shortcomings, it hasn't had the major

> overhaul that ProjectBuilder -> XCode had, but I'd

> still take the Apple supplied controls over the

> Windows ones. Try creating a table view that has

> ruler bars in Visual Studio/.Net.

IB is being overhauled (somewhat) in Leopard. But it is still miles away from what it should be. When you say "Windows controls", which ones are you talking about? Check out the stuff available from www.devexpress.com (both VCL and .NET) and then try implementing that under Cocoa. You may be gone some time! :-)

> I've not used Delphi so I can't comment on that, but

> .Net and Visual Studio I do use regularly. Personally

> I prefer the NeXT way.

Personally, I don't. ;-)

> Using Visual Studio in the way you describe results

> in disorganised code and duplication. Two buttons

> that perform ultimately the same action must still

> have their own handler, even if it's only a wrapper

> to a worker method.

It sounds like you need to get deeper into VS.NET. It is actually dead easy with .NET and Delphi to have multiple buttons pointing at the same handler, and use the sender method to perform disambiguation in the code.

> ProjectBuilder and InterfaceBuilder were way ahead

> of the times when they were produced in 1986. Since

> then other tools caught up, and even bettered

> them in some areas.

I'd agree with that, though I'd tend to replace "some" with "many". ;-)

> XCode 2.0 will make live even easier for the developer

> to do cool stuff. CoreAnimation is amazing. If you

> want to have a play with the precursor in Tiger,

> open up the Quartz Compositor app installed as part

> of the Dev tools and play.

No disagreement that Quartz and CoreAnimation are awesome compared to what's on the PC. I already have Leopard, by the way :- I have ADC membership.

> Garbage collection is added to Objective-C, if you

> like that sort of thing.

I do. ;-)

> In all I think Cocoa is still strong in all the areas

> it was originally. Other advances have happened in the

> developer world and XCode will have to play catch up.

Agreed.

> But I feel better working with a very well designed

> framework with tools that aren't the best in every way,

> than working with an inferior framework in better tools.

I don't believe that .NET and VCL are inferior frameworks to Cocoa. Quite the reverse. I would prefer to use the best tools with the best framework but unfortunately, neither is available for the Mac right now. Hopefully, that will change....

> From what I know of Delphi, it's basically object pascal. > I can't imagine any of the magic implemented in the

> Cocoa frameworks being implemented in such a strongly

> typed language.

Strongly-typed languages are not necessarily a bad thing - you would be surprised how much magic can be achieved. ;-)

Uncle Mac

0
0

More from The Register

SCO vs. IBM battle resumes over ownership of Unix
Zombie lawsuit back and wants to suck the brains out of Linux
Bjarne Again: Hallelujah for C++
Plus: Now officially OK to admit you never used STL algorithms
Interwebs taunt Sir Jony over Apple eye candy makeover
Hey Ive, Ive... add more unicorns, willya?
Apple: iOS7 dayglo Barbie makeover is UNFINISHED - report
Plus: You don't like the icons? Blame marketing
Red Hat to ditch MySQL for MariaDB in RHEL 7
So long, Oracle! Don't let the door hit you on the way out
Shy? Socially inadequate? Fiddling with your phone could help
App 'tells the brutal truth' about social inadequates' chatup lines
Java EE 7 melds HTML5 with enterprise apps
New release arrives with GlassFish, NetBeans support
 breaking news
'Office Facebook' firm Tibbr wants you to PAY for mobe-meetings app
Great idea. Punters won't cough for it though
 breaking news
The only Waze is Google: Ad giant tipped to gobble map app 'for $1.3bn'
Pac-Man-satnav-ish upstart in bidding war with Apple, Facebook
 breaking news
PM Cameron calls for modern, programmable computers! (We think)
IT education musings to G8 chiefs to mystify IT industry