What a f'ing fantastic article. Thank you so much for writing this.
I spent a decent chunk of time last year building up a somewhat large Cocoa application (a telling synecdoche of how ambitious the app is: it integrates libevent with the Cocoa loop and involved writing a whole new evented Redis-backed HTTPS cache in ObjC).
But unfortunately, I got to the UI part of this project ("UI part", heh) thinking "this is going to be so much easier than webdev, look at all these tools!, and that was a crushing disappointment; getting anything reasonable on the screen has been intensely painful, and is if anything much harder than CSS3+JQ is on modern web apps.
I'm thrilled to hear that at least to some extent, it isn't just me, and making a good-looking Cocoa app (especially your first) is just very hard.
I had the same experience with my first Cocoa Touch/UIKit project. The GUI stuff far eclipsed the rest of the app in terms of development effort, which I did not expect. This hadn't been the case with previous GUI stuff I'd done (Windows apps, game UIs and the web), and took me completely by surprise.
The "no layouting engine" issue mentioned in the article applies to Cocoa Touch in the same way as it does to Cocoa, with the added wrinkle that if you want to support autorotation, this bites you even harder. Yes, there's the "struts & springs" system, but it's very limited - no equivalent to 'min-width' or 'max-width', and yeah I can't believe I'm citing CSS as a good example. It also doesn't help at all if you need to change the relative placement due to autorotation, or if you need to adjust positioning depending on content.
Styling is another issue - most UI elements can't even have custom colours. (this will improve with iOS 5, but not until iOS4 compatibility is no longer an issue) The default button looks awful. You have to come up with your own table view cells for pretty much anything but the most bare bones of lists.
In the end, I actually built my own fully fledged layouting system, which is content sensitive, has a fairly flexible elasticity system and supports a "flow" layouting mode which is somewhat similar to the way display:inline-block; HTML elements are laid out (but with grow-to-fit). I also built styleable versions of some of the views. If only I wanted to be in the business of building iOS apps, I'd be extremely well prepared at this stage. :-)
My recent foray into Cocoa on the Mac actually has been easier, but that's probably because you can get away with using the default widget styles. Apart from table cells anyway.
Um, there is a layout engine for Cocoa. It's called UIWebkitView... But the fact that you felt the need to write your own layout system instead of using the existing one suggests that generic layout systems don't give the needed flexibility, which means that it is more important for an API to provide the tools to build a layout system than to provide a layout system. Cocoa is one of the better frameworks for building layout systems in my experience (Java SWT, Cocoa, MFC - haven't tried .NET).
UIWebView is (presumably deliberately) pretty restrictive in its JS<->native bindings. Having to redirect to URLs which are then intercepted on the Objective-C side is pretty awkward. Then there's the fact that HTML/CSS aren't even that great for designing UIs, since they were created for document styling.
Any interest in either open sourcing said layout system or perhaps even selling it to those of us who struggle with these sort of problems (a la Sensible TableView)?
We've put some of the styling-related components online on http://appuicomponents.com/ but the layouting engine isn't there yet, I do feel it's valuable enough to productise eventually. The main problem is lack of polish right now. Interface Builder isn't much use once you get to that level of customisation - there's no way to set properties your subclasses introduce, let alone previewing the automatic layouting. I'd like to fix that at some point and have some ideas on how it could be done. Aside from that, I also still need to document the system, and tidy up the code implementing the layouting, as it's currently not the easiest to debug or find out why something isn't being laid out as you were expecting, even if the layout system itself isn't doing anything wrong.
Then of course there's the fact that I'm spending almost all my time on our startup, which is completely unrelated to iOS. (but it has a Cocoa-based Mac GUI, hence my recent Cocoa adventures)
Actually, if you're interested in the layout kit, go ahead and drop me a line (email on the website I mentioned, or in my HN profile) with what you're trying to do - if it does what you want, I'd be quite happy to progressively tidy it up and document it if I've got one or two users who are willing to put up with the rough edges initially, in exchange for some hand-holding.
I'm not a web guy by any stretch of the imagination, as you well know, but I find doing webdev really easy compared to any GUI library out there. If I can say "ok, this is only going to work in embedded Webkit/Chrome/whatever", I can whip up something that's pretty and functional in no time at all. When faced with the same task in GTK/Qt/Wx/whatever, I fail miserably. I've done a good bit of both, but I doubt I'll ever go back to making desktop apps -- I can always embed a webserver into whatever I'm building, and do the UI that way...
When confronted with porting a previous Win32 app to the Mac, we ended up just rewriting every piece of UI we could in HTML+CSS. It was literally easier to embed Gecko into our app than it would have been to get the UI up and running in Cocoa.
HTML+CSS being easier and more expressive than Win32 didn't hurt either. Shared codebase!
Absolutely. This is why I think native apps are going to hit an asymptotic growth limit eventually. Native will have its place but it's already so much easier to build a typical data-centric UI in HTML5.
I've had a similar shock getting into iOS development. I'd never done any Cocoa coding before but had heard it praised so highly over the years that I assumed it was going to be all rolling fields and sunshine. But it really does feel primitive in many ways compared to the modern web. Apple will address some of the biggest pain points (layouts, styling) in their next set of OS releases but it's made me appreciate what I've taken for granted for so long in web UI.
I haven't written any apps in Android yet but I've been studying their UI docs and it's clear that their UI kit was informed by the web. If you squint at their code samples they don't look all that different from HTML5 apps: layout in markup, wireup event handlers, go.
The Microsoft visual designers are really easy to use. I was able to figure them out when I was 15 or 16 or so. I can wire together stuff in the wx* toolkits in code by hand.
XCode Interface Builder baffles me still. It's really garbage compared to Visual Studio, IMO. Really a shame.
I had pretty much the same experience you did, except with Windows (and later on, iOS). It's jarring how, to get really good looking UIs, you often have to do custom pixel positioning and painting in code.
It's almost offensive after doing expressive layouts with html and css.
Comments
What a f'ing fantastic article. Thank you so much for writing this.
I spent a decent chunk of time last year building up a somewhat large Cocoa application (a telling synecdoche of how ambitious the app is: it integrates libevent with the Cocoa loop and involved writing a whole new evented Redis-backed HTTPS cache in ObjC).
But unfortunately, I got to the UI part of this project ("UI part", heh) thinking "this is going to be so much easier than webdev, look at all these tools!, and that was a crushing disappointment; getting anything reasonable on the screen has been intensely painful, and is if anything much harder than CSS3+JQ is on modern web apps.
I'm thrilled to hear that at least to some extent, it isn't just me, and making a good-looking Cocoa app (especially your first) is just very hard.
I had the same experience with my first Cocoa Touch/UIKit project. The GUI stuff far eclipsed the rest of the app in terms of development effort, which I did not expect. This hadn't been the case with previous GUI stuff I'd done (Windows apps, game UIs and the web), and took me completely by surprise.
The "no layouting engine" issue mentioned in the article applies to Cocoa Touch in the same way as it does to Cocoa, with the added wrinkle that if you want to support autorotation, this bites you even harder. Yes, there's the "struts & springs" system, but it's very limited - no equivalent to 'min-width' or 'max-width', and yeah I can't believe I'm citing CSS as a good example. It also doesn't help at all if you need to change the relative placement due to autorotation, or if you need to adjust positioning depending on content.
Styling is another issue - most UI elements can't even have custom colours. (this will improve with iOS 5, but not until iOS4 compatibility is no longer an issue) The default button looks awful. You have to come up with your own table view cells for pretty much anything but the most bare bones of lists.
In the end, I actually built my own fully fledged layouting system, which is content sensitive, has a fairly flexible elasticity system and supports a "flow" layouting mode which is somewhat similar to the way display:inline-block; HTML elements are laid out (but with grow-to-fit). I also built styleable versions of some of the views. If only I wanted to be in the business of building iOS apps, I'd be extremely well prepared at this stage. :-)
My recent foray into Cocoa on the Mac actually has been easier, but that's probably because you can get away with using the default widget styles. Apart from table cells anyway.
Um, there is a layout engine for Cocoa. It's called UIWebkitView... But the fact that you felt the need to write your own layout system instead of using the existing one suggests that generic layout systems don't give the needed flexibility, which means that it is more important for an API to provide the tools to build a layout system than to provide a layout system. Cocoa is one of the better frameworks for building layout systems in my experience (Java SWT, Cocoa, MFC - haven't tried .NET).
UIWebView is (presumably deliberately) pretty restrictive in its JS<->native bindings. Having to redirect to URLs which are then intercepted on the Objective-C side is pretty awkward. Then there's the fact that HTML/CSS aren't even that great for designing UIs, since they were created for document styling.
Any interest in either open sourcing said layout system or perhaps even selling it to those of us who struggle with these sort of problems (a la Sensible TableView)?
We've put some of the styling-related components online on http://appuicomponents.com/ but the layouting engine isn't there yet, I do feel it's valuable enough to productise eventually. The main problem is lack of polish right now. Interface Builder isn't much use once you get to that level of customisation - there's no way to set properties your subclasses introduce, let alone previewing the automatic layouting. I'd like to fix that at some point and have some ideas on how it could be done. Aside from that, I also still need to document the system, and tidy up the code implementing the layouting, as it's currently not the easiest to debug or find out why something isn't being laid out as you were expecting, even if the layout system itself isn't doing anything wrong.
Then of course there's the fact that I'm spending almost all my time on our startup, which is completely unrelated to iOS. (but it has a Cocoa-based Mac GUI, hence my recent Cocoa adventures)
Actually, if you're interested in the layout kit, go ahead and drop me a line (email on the website I mentioned, or in my HN profile) with what you're trying to do - if it does what you want, I'd be quite happy to progressively tidy it up and document it if I've got one or two users who are willing to put up with the rough edges initially, in exchange for some hand-holding.
Thanks for the link to Sensible. Are there any well-known apps using this stuff?
I'm not a web guy by any stretch of the imagination, as you well know, but I find doing webdev really easy compared to any GUI library out there. If I can say "ok, this is only going to work in embedded Webkit/Chrome/whatever", I can whip up something that's pretty and functional in no time at all. When faced with the same task in GTK/Qt/Wx/whatever, I fail miserably. I've done a good bit of both, but I doubt I'll ever go back to making desktop apps -- I can always embed a webserver into whatever I'm building, and do the UI that way...
When confronted with porting a previous Win32 app to the Mac, we ended up just rewriting every piece of UI we could in HTML+CSS. It was literally easier to embed Gecko into our app than it would have been to get the UI up and running in Cocoa.
HTML+CSS being easier and more expressive than Win32 didn't hurt either. Shared codebase!
Absolutely. This is why I think native apps are going to hit an asymptotic growth limit eventually. Native will have its place but it's already so much easier to build a typical data-centric UI in HTML5.
I've had a similar shock getting into iOS development. I'd never done any Cocoa coding before but had heard it praised so highly over the years that I assumed it was going to be all rolling fields and sunshine. But it really does feel primitive in many ways compared to the modern web. Apple will address some of the biggest pain points (layouts, styling) in their next set of OS releases but it's made me appreciate what I've taken for granted for so long in web UI.
I haven't written any apps in Android yet but I've been studying their UI docs and it's clear that their UI kit was informed by the web. If you squint at their code samples they don't look all that different from HTML5 apps: layout in markup, wireup event handlers, go.
The Microsoft visual designers are really easy to use. I was able to figure them out when I was 15 or 16 or so. I can wire together stuff in the wx* toolkits in code by hand.
XCode Interface Builder baffles me still. It's really garbage compared to Visual Studio, IMO. Really a shame.
I had pretty much the same experience you did, except with Windows (and later on, iOS). It's jarring how, to get really good looking UIs, you often have to do custom pixel positioning and painting in code. It's almost offensive after doing expressive layouts with html and css.