Category Archives: Opinion

Lessons from AngularJS

AngularJS

AngularJS

The past two weeks I’ve been working on a web project using AngularJS.  Angular is a Javascript MVC framework with the backing of Google.  I always enjoy taking some time to learn a new language or tool from time to time.  As iOS developers I think there’s a couple of concepts we could learn from Angular.

Bindings – Bindings everywhere.

One of the first thing you learn in Angular development is its two way binding system.  Placing a binding in your HTML template is dead simple; simply enclose the variable in the handlebars: {{myvar}} or link it via the ng-model attribute on an input tag.  The binding is two way such that changing the value of a text field will update that in your model.

Unfortunately iOS is often much more difficult and manual when it comes to keeping your model and UI in sync.  MacOS provides bindings to developers but there’s no once and done solution for iOS.  However binding is not difficult to implement using KVO.  KVO has its downside when it comes to performance, but it may be worth it for the simplicity.  I haven’t tried to implement it myself to be able to tell.

Thin models; thin controllers

Angular makes very few assumptions about what your model in the MVC way of thinking is.  In fact, the model for any controller is expected to be a special variable called the $scope.  The $scope object is provided by the controller, whose entire job is to do nothing but populate the scope.  Compared to iOS view controllers, Angular controllers are extremely light.

iOS view controllers have a bad habit of being very involved in both in view-ish things and model-ish things, as well as its dictated function of handing controller-ish things.  How many times have you managed a view directly in your view controller as well as managed changes back to the model?  Probably a lot.  One of the downsides of UIViewController is that they often wind up being behemoth and barely manageable monster objects. Angular’s documentation strongly advises that you don’t make changes to the DOM (the literal view of a web application) from within the controller, delegating those tasks elsewhere.  The result is a very simple controller that does its job of exposing the model to the view well and without needless other operations.

Greater separation of the view and the controller

Web applications have an inherently strong presentation layer: the HTML and CSS that handles display in the browser.  In Angular style, the HTML provides structure of a view, CSS provides the presentation of the view, and Angular does the job of providing data to the view.  As mentioned above it’s all too common in an iOS application to jam all this functionality into a single view controller.

It’s not a stretch to say that UIViewControllers are often required to do far too much for any non-trivial application.  A view controller might be responsible for loading data from somewhere, maybe through an NSURLConnection, doing any formatting or transformation of the data, creating a view in loadView: and laying all the pieces out.  It may also be the datasource and delegate for a table view providing cells and handling cell selection.  After all of that it might also be accepting event callbacks from UI controls and altering the model appropriately.  That’s a huge set of tasks and I’m as guilty as anyone of writing multi-thousand line view controllers.

Applying the lessons

So how should we break up a UIViewController subclass into more manageable chunks?  I think Angular presents a couple of ideas.

  1. The most simple task is to separate the model related concerns of a UIViewController from its view related concerns.  In iOS development you need to have view controllers, but there’s no rule that you can have other controllers to handle other tasks.  NSFetchedResultsController provides a great example of a way to separate the needs of dealing with CoreData from the other responsibilities of the view controller.
  2. Relegate the UIViewController subclass to what its name implies:  management of the view.  Offload data related concerns to a custom defined model controller.
  3. Make views a little smarter.  HTML and CSS provide a natural separation between controllers and views.  Interface builder is one of the best tools and iOS developer has but there’s no reason we can’t make smarter views that know more about it’s layout and the properties of it’s subviews.  If reuse is concern there’s nothing wrong with the root view of a view controller being a custom subclass that arranges other pre-made components.
  4. Attempt bindings using KVO.  You could easily inject a transformer into the mix for formatting.

Fully realizing these are all a little abstract right now I’m planning to take a concrete stab at these in some future posts.  For now the takeaway is that learning a different way of doing things can always open your eyes to some better ideas in your current workflow.

Advertisements

To Code or Not To Code – That is the (stupid) question

There’s a lot talk this week around Jeff Atwood’s post on CodingHorror where he asks the populace at large to not learn to code.  I’m not sure of what to think of the numerous responses and comments on the web.  Perhaps it’s a matter of people being too caught up in their craft.  Perhaps it’s simply vogue to disagree with Jeff Atwood.  Regardless, 90% of the responses are missing Jeff Atwood’s point.

When all you have is a hammer . . .

You don’t have to look around and see that multiple systems are horribly broken: education, healthcare, government just to name a few.  Entrepreneurs everywhere are and should be chomping at the bit to fix these problems.  There’s a hell of business to be made on solving these problems successfully and safely.  Code is not the way.

These industries have no shortage code.  Government has more code than they know what to do with.  So does healthcare.  Much of it is probably bad.  Simply throwing more code at it shouldn’t be the answer, especially if it’s bad code.  Jeff Atwood makes the point that the world doesn’t need more bad code by bad coders.  He’s right.

What these industries need and what Jeff is really advocating is solutions.  Code should be the last thing we’re all thinking about when we’re trying to solve the enormous problems plaguing them.  Code will most certainly be a part of the solution, but only a means to that solution once the important decisions have been handled elsewhere.  Code itself is not the solution anymore than a hammer and nails are the solution to housing problems.

Code if you want to . . .

Code if you want to learn to code.  Code if you really want a deep understanding of how computer programs work.  But if you’re going to delve in learn it well and learn it right.  Don’t learn “just enough to be dangerous” as the adage goes.  If you’re an entrepreneur, learn to find and craft solutions.  Solutions are always more than just code.  Once you have a good solution to horrible problem there will be no shortage of great coders to work with you and take care of the hammers and nails.

MacOS Lion Thoughts

I simply couldn’t take the suspense, so I installed Lion yesterday. I know there’s no shortage of reviews out there, but I wanted to list my impressions of the OS so far:

The Good:

  • Most apps just work – All my apps, even the more finicky among them seemed to work just fine. Many developers have already released Lion ready versions as well.
  • Speed – The OS feels a bit snappier all around once everything gets settled down. This is especially true for XCode.
  • Mail, iCal, iChat – I was really impressed with how easy it was to get my company’s calendars and mail set up. Very smooth and unexpected, especially compared with previous versions. It does seem that online accounts such as google are more deeply integrated into the OS.

The Bad:

  • Full Screen Mode – Apple has been touting the virtues of full screen apps in the months leading up to the release. My experience has been less than ideal. Using multiple monitors, the transition to full screen is laggy. Additionally, an app will full screen to the primary display, in this case my macbook screen, leaving the 24″ secondary display unused, covered with that linen texture apple has become so fond of.
  • Bounce Scrolling – Easily one of the more annoying UI enhancements apple put into this latest revision. I’m not entirely sure why I need my text editor to bounce when I reach the end. As with some other animations, it doesn’t convey any new information about what’s going on and just makes things harder to track. The other problem is that apps not using cocoa scroll views don’t get this feature. Chrome, my default browser, and Postbox, my mail client still have the plain jane scroll views, making things less consistent across the OS.

The Unexpected:
There’s a couple of things you’ll need to do right away after upgrading that I didn’t see coming, especially not having used any of the prerelease versions:

  • Java – any app that uses Java (even ones that don’t seem to) will ask you do to do a Java update immediately.
  • XCode – the previous version of XCode, 4.02, doesn’t run in Lion, so you’ll need to download the newest one. Caveat is that it’s on the developer site but rather as a (now free) download from the app store. I will say that this version of XCode adds more stability and speed as compared to 4.02.
  • Spotlight – for about the first hour after upgrading my system churned as spotlight was reindexing. This will sap your performance for that time, but it does seem much snappier afterwards.

Final Take:

At $30, the price of an upgrade is cheap and worth the money.  The speed improvements are quite noticeable across the board and my system seems more stable.  All told, to get everything back up and running you’ll probably need the better part of an afternoon.  I’m hoping there’s some updates to disable some of the animations like the bounce scroll.  Most are unobtrusive, but they’re really unnecessary eye-candy that I could do without.

ARC: Cat’s out of the bag

LLVM has posted about the new automatic reference counting feature coming in (I assume) future versions of the compiler.  I have a hard time thinking of this as a helpful improvement in dealing with memory in objective-c in a non garbage collected environment:

  • It doesn’t change the way you think about your allocations.  You still have to place __weak, __strong, or __autoreleased to tell LLVM how you intend to use the declaration.
  • If you’re already declaring your intentions to the compiler, why not simply go the extra step and follow through.
  • The above also holds for the new @autoreleasepool directive to run a local pool.

I also have a few, more personal reasons for not liking the feature:

  • It makes the code uglier: __weak, __strong are not particularly attractive to look at.
  • Alongside the above, I feel it’s a poor abstraction: In a purely garbage collected environment like java or any scripting language du jour, there’s not even a mental model for memory under the hood with the notable exception of scoping rules.  You can simply “new” an object, and it’s there until you either null it out or it goes out of scope.  In the case of ARC, you still have to have be somewhat aware of what you’re doing, but you don’t necessarily need to REALLY understand what’s going on under the hood in terms of the retain count and balancing retain release calls.  As I see it, a clearer and more complete understanding is better than a foggier one any day.  This brings me to my next point:
  • Understanding and managing your memory makes you a better programmer:  There’s something to be said for the level of detail you must think about while working with the memory model in objective-c, and I can’t help but that it pervades the entire application process from design to testing.
  • Is it really all that hard?  Objective-c provides quite clear ownership rules, and with the reference counting built into NSObject, it’s relatively easy to manage memory properly.  Sure, there are plenty of beginner mistakes to be made both with leaking memory and the dreaded EXEC_BAD_ACCESS crash, but now after writing iOS code for a couple years, typing something like [[NSMutableArray array] retain] feels perfectly natural and automatic.

What are your thoughts on adding ARC to your development workflow?