Mac Development 7 Years Later – More Fun, Kind of Weird
Recent projects have given me the opportunity to do some coding on the Mac. I used to be a Mac Shareware Author back in the mid-90’s, but I haven’t done any development on OS X, other than going through the same Apple Tutorial several times, first as the Yellow Box Tutorial, then as the Cocoa Tutorial in Java, and most recently as the Cocoa Tutorial in Objective C.
Prior to my current job, I had been doing mainly server-side programming for the last several years. At my last job, I did a fair amount of client-side Java Swing development, and for the past few months, I’ve done a bunch of C# .NET coding. The return to client-side development has been a lot of fun — it’s great to have more control over user experience than you get with a browser, and the technologies have come a long way since I stopped doing client development around 1999.
It’s not surprising that Mac development is significantly different than it was in 1999, when I released the final version of HTML Markup. The OS is completely different. What is surprising is how much is actually the same. And that’s one of the things that bugs me — see below.
There is much to like in OS X development. It has a certain feel to it and you can tell that (parts of it) were lovingly crafted by programmers who actually wanted their APIs used to a creative end.
Encouraged MVC Separation – Cocoa gets the separation between Model, View, and Controller correct. It’s better than .NET does it, and I’d say it’s even better than Ruby on Rails. Cocoa is the only framework I’ve used where it’s not tedious to separate things into MVC — it actually happens naturally.
Visualization – If you’ve gone through any of the Cocoa tutorials, you’ve created a simple UI and drawn the little lines between objects to denote ownership (outlets) and behavior (actions). At first this seemed hokey, but I came to really like it. In a very simple way, you can start to illustrate graphically the relationships between objects that previously only existed in the programmer’s mind. Better still, it doesn’t get in your way. Once I figured out the right way to do it, I far preferred switching to Interface Builder to draw some lines to just writing the equivalent code.
Clean APIs – The Cocoa APIs are nicely written and fairly well documented. Of course, this means that it’s all the more frustrating when you have to move outside Cocoa to do what you want to do (see below).
Objective-C — why not? – I can’t say that I was excited about learning yet another language, but there are certain advantages to having Objective-C as the preferred Cocoa development language. First, Apple has a large degree of control over the language since, let’s face it, precious few non-Mac apps are written in ObjC. Second, everybody who claims that ObjC is an elegant and simple approach to OOP is telling the truth. Reading Apple’s PDF ObjC manual took a day or two and it covers the entire language. Finally, I think the new syntax and the language features helped develop many of the stylistic standards that make Mac coding unique and pleasant.
A Pretty Sweet Memory Model – I could (and will) argue that maybe memory management shouldn’t even be an issue anymore. But if you accept that your application will have to manage memory, Cocoa’s approach is (at least to me) very unique and very smart. It is an extra hurdle though — to get past trivial programs, you really need to read the memory management PDF a bunch of times until you realize that yes, the framework is keeping track of things and yes, it will free them, but no, it’s not garbage collection.
You Can See Why the Apps are Better – In general, Mac apps have always felt more personal to me. You can tell that someone thought hard about how the app should behave and exactly where each button should be. There’s no one thing about Mac development that makes this the case. I think there has always been a sense that when you’re writing for the Mac, you’re writing for a smaller, more intimate, audience. I think the tools certainly help. And the community has always been important. At any given time, there have always been a handful of well-known Mac developers who gladly share their code for window transparency or respond to the newbies on the message boards.
Particularly around 1995, being a Mac programmer kind of sucked. You were rebooting constantly, there weren’t many people to help you, documentation was poor, and it was just an uphill battle in general. Thankfully, things are nowhere near as bad now. But after coding in C# .NET for a while, I was surprised at some of the downsides to Mac development.
CFTypeRef — That’s Still Around? – It was shocking (shocking!) to me how much of the old Mac Toolbox types and calls are still around. I mean, I knew that Carbon existed, but I was under the impression that Carbon was just an interim thing Apple supported in the early days of OS X so that Photoshop could still run. It turns out that not everything you want to do exists in Cocoa. You’re dropping down to the Carbon level quite frequently, often using a bizarre mix of ObjC and C++ that they actually call Objective-C++! I think that Cocoa is great. I’ve drunk the Kool-Aid. So why is Apple introducing new API’s into Carbon at all? Why isn’t everything new in Cocoa? Why the fuck can’t I record sound from the microphone without resorting to several pages of fairly gross Core Audio code?
Not Feeling Lucky – Pick any random task you might want to do in C# .NET and type it into Google. I can almost guarantee that the first link will be someone doing the exact same thing and will have the solution. That’s just the nature of having such a huge community of developers. Anything you could want to do in Windows has been done a million times and somebody has posted how to do it. I thought doing a tray icon in Windows might be hard. Nope — turns out it’s just a property of the window. I thought window transparency might be tough — nope, Microsoft had a very nice tutorial on how to do it. On the Mac, you sometimes get lucky and find a ready-made solution. But more often than not, you’re reading through old threads that may or may not turn out to be relevant and digging through APIs that seem to specifically avoid the question you’re trying to answer.
That’s Not Built In? – The thing about Mac apps is that a lot of them are so beautiful that as a novice Cocoa developer, you assume that certain things are just automatic. Many Mac apps do some pretty cool animations with their UI elements. Apple provides some support for this, but it’s not as easy as I assumed it would be. Just like in the old days of writing OS 9 extensions, there are a number of techniques that are just known and shared amongst the Mac community. Luckily, it’s easier to find these things than it used to be. You no longer need to have a friend on the Finder team; you just need to read the right blogs.
Autocomplete’s Downfall – I learned C# and .NET through autocomplete. Literally. The only time I remember actually using a language reference was to learn about how C# dealt with threads. Other than that, I’d just throw a UI element on the screen, double-click it, and see what properties and methods it had. XCode has autocomplete, but it’s not nearly as useful. You can blame Objective-C for that. Since objects are much more runtime oriented, they are often entirely untyped and autocomplete’s usefulness suffers. Don’t get me wrong — I think the Smalltalk roots of ObjC are interesting and all, but it means that you sometimes have to dig a little deeper.
You’re Still Doing Your Own Taxes? – I guess I always knew that Objective-C didn’t have garbage collection, but after doing Java for several years and then several months of C#, it just felt so weird to have to think about that stuff again. As I said above, ObjC’s memory model is pretty sweet but the fact that it has to exist is kind of a downer. And frankly, I’m surprised that more Mac apps don’t crash randomly since it seems so easy to get the reference counting wrong.
I’m pleased to say that Mac programming is better than it ever has been. The tools are top-notch, the community is small, but vibrant and supportive, and the framework is better than anything else. Most of my complaints are related to the learning curve more than fundamental problems. What I’ve noticed in general lately is that the current generation of language/framework combinations are more pleasant than previous ones. Ruby/Rails makes webapp development less repetitive and boring, C#/.NET makes building a Windows app almost trivial, and ObjC/Cocoa lets you focus on what really matters in your app. That is, of course, after you’ve read the Memory Management PDF.