2010
09.01

My coworker-friend-buddy, Sean, and I are putting the final touches on our iPhone framework, iBoost. One thing we have to think about now is how it will integrate with our (and your) applications. There are two basic strategies I’ve seen:

  • Copy the source code into the project. This is never done with Java projects, but is always an easy choice for C-based systems because compiled code is platform dependent. This is a very common choice for small classes, too. I make a lot of my mini-modules available this way.
  • Compile as a library and copy header files. This involves distributing as a compiled library with header files. Flurry does this, as well as AdMob. The obvious motivation is to keep the source a secret.
  • Obviously, if wee distributed iBoost as a library, it wouldn’t be to keep the code secret (since it’s open source), but it’s still a valid way to go.

    I lean towards the former. Dumping the source into your project may seem messier, but if you keep it isolated in a directory instead of copying it to your Classes, it’s really no different than library distribution. Plus, as the SDK iterates, and different platforms become available, you don’t have to worry about updating your libraries all the time. I just recently had to do this with the Acapela Text-to-Speech library and it was doubly painful because they are located in France and I needed it immediately. :-)

    Minification

    But now I have a new thought. It seems messy to distribute source as a large group of files. I’d love to make it a two-file (*.h and *.m) distribution. Hell, one would be great if it’s doable. But how?

    Well, if you’ve been involved with the JavaScript scene the last few years, the little trick we like to do when publishing websites is to run a “minify” on the JS code. This is a script (there are several out there, but the YUI version is used a lot) that takes your JavaScript code, cuts out as much whitespace as possible, and basically runs your code through a vacuum. The resulting code is often unreadable, but (hopefully) works exactly the same. The idea is that you not only save some bytes of bandwidth, but it makes it a little harder for people to snoop through your code which is obviously uncompilable.

    So, it is possible in Objective-C? I can’t find any references to it. No one seems to have done it. My guess is it’s doable. Here’s my theory on how it could work:

    1. Append all of the header files together.
    2. Pull out #import’s referencing any of the files themselves.
    3. Add forward references (@class) for all classes at the top of the file. (No need to ull existing ones unless we want to keep the file size minimal, which is not necessary.

    I’m going to attempt it this week with a Python solution. I’ll let you know the results. What do you think?

    • Print
    • Digg
    • del.icio.us
    • Facebook
    • Twitter
    • DZone
    • LinkedIn
    • Reddit
2010
08.29

Back in June, a client approached me about writing an iPhone app that would let users report and be notified of speed traps while driving. I hadn’t been familiar with this app space and thought the idea was great! We spent the next two months working together designing, implementing, testing and ultimately releasing the app Fuzz Alert Pro which made it onto the App Store just a few days ago.

As a closeted UX Designer-wannabe (alright, I’m out of the closet now aren’t I?), I found this app fascinating in its challenge. We wanted to make an app with an interface perfect for driving. There’s a handful of other apps out there that do something similar, but it was clear that none of them had their UI right. In this industry, how your app speaks with the users is as much a part of its success as its technical achievements.

Speaking With the User

The first thing we did in our research was get an idea of how users would use this app. Now, the ideal way is to have an iPhone Car Mount. Not only does it accomodate a better viewing angle for the driver, but it makes plugging in to the car charger convenient since the slot on an iPhone is at the bottom of the phone where it would interfere with positioning. However, despite this, clearly most users would not have a mount and so we wanted to design for the most common case of the user driving with the iPhone sitting in a cup holder.

In addition, drivers would overwhelmingly not be looking at the app while driving. Many drivers might give a glance every so often, especially when stopped at an intersection, but audio would be important. From this, we came up with the idea of “Radar Mode.” Radar Mode can best be described as a replication of a classic radar detector, though obviously based on different technology. In fact, Fuzz Alert Pro plays similar audio “beeps” that you would hear from one, with beeps repeating faster and faster as you get closer to a known speed trap. This pure-audio interface means the user never has to look at the screen while driving. Ever.

Modal Interruption

In all of UI design, my biggest pet peeve is unnecessary dialog boxes, modals, and interruptions. The classic case has always been text search. There’s no doubt that, at some point, you’ve run a text editor or word processor and you ran a text search and this popped up:
A pointless dialog that appears when text search fails.

Why are you interrupting my workflow? I can see that no words were found. Half the time, I’m kind of expecting it, anyway. Now, think about how this problem might effect a navigation app…

Clearly, with a user busy driving, both hands on the wheel (we hope), having the app pop up an alert would be silly. The users view of the map would be obscured and they’d be forced to hit the OK button. If this were a major error, it could be excused. However, what if it was just normal workflow?

Of the apps we’ve reviewed during the course of this project, no app personified this terrible design like Trapster. For a user to simply report a trap, it takes no less than 5 clicks:

  1. Click “Report Trap”.
  2. Move the map to line up the pointer under the location marker (which can be a little confusing to some users).
  3. Click “Done”.
  4. Click the type of trap that it is (e.g., red light camera, cop, etc.)
  5. Wait for the submission to process and then click “OK” when the alert pops up.

That last step is the most outrageous offender! Even if everything was perfectly successful, an alert pops up a good 1-2 seconds after submission to say “Success!” Why can’t we just assume success and have the app simply report the rare failure? The result is that the user has to either (A) hold the iPhone in their hand until the response comes back and they can hit “OK” and put the phone back down or (B) the alert pops up after they put the phone down and now they’ll need to wait until a good moment comes along to dismiss it.

In Fuzz Alert Pro, we made the process as quick and simple as possible. The user can report a trap in 2 clicks:

  1. Move the map to the location and double-tap where the speed trap is located.
  2. Click the type of trap that it is (e.g., red light camera, cop, etc.).

The user is notified on success or failure with a passive dropdown status header that displays for a few seconds and then goes away. The user never has to wait for an action to complete. They can keep their focus on the road.

Do One Thing Right

iPhone Apps, especially productivity or utility apps, tend to find themselves following the same paths many modern corporations do: they try to do too much. A friend of mine once criticized Apple because they aren’t focused anymore, “they make computers, MP3 players, phones, no wonder they screw up everything!” That last part was news to me, but the kicker was when he said, “Look at Coca-Cola. They make Coke. They do it well. And that’s all they do.”

I kindly informed my friend that Coca-Cola has several dozen lines of drinks, but what he says does have some truth. Focus is good. We felt that Fuzz Alert Pro needed that same focus. Here’s a list of the kinds of things it won’t do:

  1. It won’t navigate you to your destination.
  2. It won’t update you about where your friends are driving.
  3. It won’t tweet your friends when you arrive at your destination.
  4. It doesn’t estimate your time remaining until reaching a destination.
  5. It doesn’t use push notification to let you know when new speed traps are added.

All of these things appear in some of the competitors’ apps. They’re trying to do too much. In some cases, the user interface gets so overwhelmed with features the user no longer knows how to make the original functionality work! In one app, there are over a half-dozen pages of settings! We want to be the best at alerting drivers to speed traps and making it as simple (and fun) as possible to report them accurately.

iPhone apps are not desktop apps. Users expect to have dozens of apps on their iPhone at any given time, all with a specialty. They want the best-of-breed for everything they need. And we plan on providing that to them with our speed trap app.

How Did it Turn Out?

With the app now released, I can look at it and feel pretty good with what we did and on the budget we did it in. The app looks good to the eye, has some really sweet iconography, and does its job well. We’re now in a very important phase (post launch) where we need to build up the database. We hope that our game-oriented points system invites and motivates users to report all the speed traps they find and compete with other users on the Fuzz Alert website.

Care to give it a shot?

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.22

Apple has gotten a lot of bad press lately over the iPhone 4. But, as “AntennaGate” (barf) closes up shop and we move on with life, it’s really important to point out that one other thing the whole controversy has done is cover up for a whole lot of bad decisions by Apple.

I’m miffed, and you should be, too. Let’s review, shall we?

The iPhoneOS 3.2 Release — Where’s iPhone?

iPhone developers saw the end of their honeymoon with Apple in April, 2010, with the release of the iPad. For the first time, developers had to deal with a substantially different piece of hardware: bigger screen, different user experience, no 3G or camera, and the real problem in a new iPhoneOS upgrade to 3.2. Well, the problem being that it ain’t for iPhone!

iPhoneOS 3.2 added a slew of new API features, but most notably user gestures. A nice little framework, it took all of the pain out of doing event management by hand. Gestures captured complex motions but sent simple notifications to the app. It’s great! However, it’s almost completely useless. The only time you can ever use gestures is for iPad-only apps.

The problem is that if you want your app to be 3.1.3-compatible (for the iPhone crowd), you can’t use gestures because they don’t exist in the 3.1.3 SDK. Your app would only support iOS 4. But supporting only iOS 4 is a non-starter right now, because…

The Big Middle Finger to 3G Users

When iPhone 4 was announced, iOS 4 was as well. We were all excited, there were lots of new SDK features and were eager to — wait, what? Original iPhone and iPod Touch users can’t upgrade????

Yes, for the first time, there was no longer an upgrade path for our “elderly” friends. We sorta let it slide because those devices were a few years old and too slow to handle our new applications well anyway. We also found out the heavily mainstream 3G wouldn’t support some of the newer features, most notably running apps in the background and home screen wallpaper. Oh, well.

What no one foresaw was the buggy upgrade Apple would make available for the 3G. Just about everybody I know with a 3G has seen their phone performance drop like a rock. Honestly, I don’t know how they deal with it. Huge hiccups and freezes, it would drive me crazy. From what I know, the problem isn’t the OS itself, but rather when you update it rather than restore. I believe it affects users more than developers because we were forced to restore during the betas. Users, however, generally do not. It’s risky, more complicated, and frankly I don’t blame a non-technical user for thinking it’s just a great sounding idea.

In fact, last month I was speaking with a particular industry icon (non-technical, you’ve seen her on TV) and we were discussing an iPhone issue she was having (not related to the 3G upgrade), and when I told her about restoring her phone her eyes went wide and she said, “You want me to erase all my data?”

Until now, Apple has not communicated well the problem. I work in a very tech-savvy office and there are literally dozens of people with useless 3G phones, walking around like zombies not knowing what to do. it was only in the last few days Steve Jobs hinted that the next update will fix the widespread problem.

This has been an unspoken disaster for Apple in terms of brand confidence. Surely, many of these people have decided to “upgrade” to a different phone completely — and they certainly weren’t choosing the iPhone 4 giving THAT publicity! (*cough* Android *cough*)

The iOS 4 Release — Where’s iPad?

Having sufficiently screwed over iPhone developers enough with the 3.2 mess, Apple has made amends by screwing over iPad developers even worse! Why on Earth can’t we run background apps on the iPad yet? My iPad feels so old and decrepit next to my iPhone 4. I can’t imagine why a company of such quality as Apple couldn’t possible release iOS universally on launch day?

Think about it. It’s not like there’s years of legacy here. At some point in the last few years at Apple, some exec (likely Jobs) said, “Hey, let’s make a bigger iPhone, we’ll call it an iPad!” and a wise developer responded, “OK, but we’d better keep the OS’s in sync because it would be a maintenance nightmare if we forked them!”

Well, apparently that developer DID NOT say that.

So, it seems the OS’s split, and they’re working towards unity within the next year. Kudos to them. But, WHY wasn’t there unity right away? Did they really want to start a new era of multi-versioned OS’s so soon, with just two pieces of hardware?? So now all of us iPad owners sit around wondering why we can’t use the GameCenter or get embedded fonts or background apps on our iPad. (And, heck, we got the home screen wallpaper before our iPhone friends — so now I’m really confused!)

We Expect More Form Apple

Our dream scenario of having all devices upgradable and supporting iOS 4 well doesn’t seem like it should be such a dream. We could all be building for and targeting iOS 4 right now if that was the case. Instead, most of our projects MUST still target 3.1.3 to support the bulk of 3G users who simply won’t upgrade. Plus, it doesn’t help that you can’t put out an iPhone-only app that targets 3.2 simply so iPad users can run it. (Apple forbids it when you try to distribute — the bastards.)

I expect Apple’s rough patch to stop. There’s no doubt there will be an iPhone 5 in July and they will address the antenna (and, yes, there really are problems with the iPhone 4′s reception) and put a TON of money into bringing confidence back to their brand. Hopefully, by then, the iOS is unified and the 3G issues are indeed snuffed.

We simply expect more, guys.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.15

About a year ago, I released my first *real* app on the App Store, a To-Do List app I called Task List. I wrote it for myself, actually, as I didn’t like the variety of offerings at the time. I wanted something simple, quick-to-use, and with a UI that got to the point so I could update my tasks on the go.

I released Task List at the price point of $0.99 so that anyone else looking for the same thing could have it. Sales were OK, on good days I’d sell 15 copies. On slow days I’d sell a couple. As the year has wound down, however, sales were pretty slow at about 3 a day.

So, a couple days ago, I decided the profit wasn’t considerable to me anymore and that it’d be more fun to let anyone who wanted it have what I thought is a pretty keen app for FREE, and so I made it free! What has followed over the next couple days I think has been pretty enlightening and educational:

Task Lists Downloads Between 07/13/2010 - 08/14/2010

It’s hard for me to explain the explosion of numbers past the fact that the app was made free. I went from almost no new users a day to 500 and then to 1,000! On Reddit yesterday, some theorized that apps like PandoraBox have driven users to the app, but to me it’s still just a To-Do List app. It’s not Doom. :-)

My theory is that downloads have skyrocketed because the To-Do List market fills a huge demand — iPhone currently doesn’t bundle with a To-Do List app like BlackBerry does, which seems strange. So, many people come looking for one and are immediately drawn to the free apps. And now they find Task List which, being well-named and #1 on search for “task list”, is an attractive deal.

I’ll be very curious to see how downloads move over the next week.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.13

Headed to 360 iDev

I’ve been told I should tell you this. :-)

I just bought my ticket for 360|iDev! The show will be going down November 7 to 10, 2010. You can find more details at the conference website: 360 iDev It’s being organized by the folks who put on the 360|Flex shows, which is a crowd favorite. Tickets are cheaper on a first come, first serve basis! So buy your tickets ASAP at 360 iDev to get the best possible price. I did!

See you there!

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.12

For 4 years, I worked in the insurance software industry. I still can’t tell you how I ended up there. I had a nice string of fun jobs writing home-control software (sorry if I woke you) and email distribution systems (sorry if I spammed you), and one day I just couldn’t stand life anymore with a particular employer and I started looking for a new job where I ended up…I ended up writing Workers’ Compensation Insurance software.

(THE HORROR!)

During my first week, I spent my time absorbing code. My desk was covered in printouts of our software that I’d marked up in pen to high heaven. This class calls that class which creates a factory which returns a command which calls another class which makes a request that queues a call to an anonymous class which runs a threaded method that…wait, what were we trying to do again? I’ve lost track.

There’s something about writing so-called enterprise code that seems to make developers want to hide all the concrete functionality deep underneath an unimaginable number of abstracted layers. I HATE IT! I hate it and I want it to stop. Enterprise has nothing to do with abstraction so take your abstraction and EAT IT. Enterprise is about writing rock solid, correct code and hiding your functionality behind 3 interfaces, 4 abstract classes, 2 proxies, and 2 abstract factories is not conducive to reliable code.

Let’s walk through what leads to over-abstracted code and how it can be stopped.

Design Patterns

On every interview I give, I always ask the candidate about design patterns. Do they use them? How many do they know about? QUICK, WHAT’S THE VISITOR PATTERN AND WHEN HOW COULD IT BE APPLIED?? The way I see it, all good developers know some design patterns, but that doesn’t mean all developers that know some design patterns are good.

Factories, Template Methods, Bridges, Adapters, these are all well and good, and I’ve used most of them, but DO NOT IMPLEMENT THESE ON FIRST PASS! Write your code in iterations. The first time through, make your code works as simply as possible. Once it’s working correctly, identify the sections of your code that are candidates for future extension and refactor — only then should you be using these patterns if they are appropriate.

If you opt to implement th design pattern on first pass, you may find that the abstraction needs to change later due to:

  • …changes to the inheritance hierarchy.
  • …refactoring which allows you to narrow several code paths into just one.
  • …functional changes.
  • …requirements changes.

The problem is that when you run into one of these problems, you are most likely not going to rollback the abstraction you created in the first place. The extra time the abstraction took to write, plus the pride you take in having done it in the first place, handcuffs you to the implementation.

Your best bet is to write the code with basic logic and inheritance the first time and then, once everything is working, only then refactor the parts that need it. When starting from working code, you can make more informed decisions about what the right level of abstraction should be.

In fact, this is the soul of Agile design. We make our best decisions when we have the most information. You don’t buy a car based on a spec sheet. You get in the car first. You drive the car first. Then, you have more information to go on. You’ll make a better decision on if that car is the right fit for you. The difference is deciding to buy a var based on reading how much horsepower it has versus feeling how much horsepower it has. So, why would you create abstractions to support functionality that you don’t require yet? Why would you implement redirection when you haven’t written what it is you’re redirecting to?

Are you really in a position to make the best choice yet?

Code From the Bottom Up

Good Design™ generally dictates we code in a top-down approach, progressing our levels of abstraction generally lower as classes implement methods which call other methods. However, this leads to premature abstraction that can lead to the kind of unexpressive code that I’ve already described. One way to keep ourselves on the straight-and-narrow, ironically, is to intentionally code in the opposite direction.

Let me explain.

Say you need to write a key/value persistence system. You might conceptualize, and implement, the system with a top-down approach:

I want to be able to save key/value pairs. These can come from a user, or just be specified by the system. A flat file would work for now, but a database could be a better choice in the future. It’d also be nice to have an in-memory store. I got it! I’ll write an interface, IKeyValueStore, and then create a factory that will return one of many possible stores.

And this is perfectly reasonable. Good thought has been put in to this decision. You go about writing it. You go ahead and design the interface to be as implementation-agnostic as possible. The key/value pairs are easy, and save() is obvious. What about loading? You decide that should be kept private since you’ll need to think about database credentials and file a file path for the various implementations. Next, you set to work creating all three stub implementations. You create the factory that returns one of the three. You only fully implement the flat file implementation for now because that’s all you need.

But now, how will you pass the path to the flat file in? Is it specified in the factory? Or is it in settings? Wait! That’s what’s being written. And now you’re making a lot of decisions and you still don’t have a working key/value persistence system.

Contrast that with this line of approach:

I want to be able to save key/value pairs. This will initially be a flat file. I’ll write that. If we need other methods of persistence later, I’ll refactor.

Feel strange? It feels like we went to implementation too quickly, doesn’t it? We feel like writing a concrete class so soon is sorta dirty. Surely there will be some tight coupling as a result. And what happens if we later want to switch to a database? This can’t be right.

And if this was all we ever did, it would be wrong. In reality, we implement the file-based store and hardcode a file path in. But, as we do so, we realize that in order to unit test appropriately we’ll pull need to pull the file path into the constructor so we can better specify where it goes.

See how that decision was much easier to make? We based it on real needs, not theoretical desires. The decisions “bubble up.”

In a short time, we have a working key store and a clear mind. The application uses the file-based key store concretely; does this feel right. Why or why not? Perhaps we forsee changes later. So what? Why do we need to try to predict the future? When the time comes to add a new kind of key/value store, we can do it. So let’s fast-forward now…

New requirements have come and instead of a database store we want a networked REST store so that the settings can be shared via the Cloud. We go to our implementation and determine what needs to change: three of our methods assume a synchronous implementation and we obviously need a new constructor. Since we’ll have two key/store implementations now, we also need to pull out an interface. The new interface now supports asynchronous calls and we write the new REST implementation for it.

See what we did? We haven’t wasted any effort. As we’ve gone along, we’ve used our experience to anticipate future changes by writing flexible code, but we haven’t written any code for imaginary requirements. You see, anticipating change in the future is far different than prematurely building to it. Instead of trying to predict the future by writing high-level code before the low-level, we’re letting the real requirements of the application drive where the abstraction goes. Our decisions are made easier because we’re reacting to real stimuli.

Give It A Try!

The next time you find yourself having to write a complex system, start with the low-level classes and work your way up. You’ll find that the decisions are easily solvable when you have the benefit of existing, working code. Ideating on the theoretical leaves too many unknowns for you to make the best choices.

The end result will be concise, get-to-the-point code with no unnecessary abstraction because you only added the abstraction you needed, not what you anticipated.

Now come on, enterprise. Is that so hard?

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.04

This blog is the second part of my post, Is Good Code Impossible?. In it, I go through a case study of a project with “Gorilla Mart” that illustrates how difficult it is to maintain good coding practices in contract- and commercial-based software.

I’ve gotten a lot of feedback on Part 1 of this blog series and quite a few of you have been quick to lay blame on the developer, while the rest have sympathized as having been there before. You’re all right! And what I hope to lay out for you now is not some generic contracting checklist we’ve seen a million times, but for once begin to outline a very clear, clever, and repeated strategy that clients will use to manipulate a project. When we’re all done, we’ll tie it all back to good code and why it’s so difficult to execute on it and how we *CAN* change things to make it possible once more.

Oooooooooh it sounds cool, let’s go!

The Basic Project Manipulation Patterns

The client is bright. You, the developer, are also bright. Two smart entities should be able to run a project that’s smooth and free of problems. But, we know that never happens! So, why not? Well, the reason is that the client and developer are not on the same side. Neither is good or bad, but both are expectedly self-serving.

The developer’s goal is to either finish a flat-rate contract under-time or up-sell features for an hourly-rate job. In either case, profits are maximized. When a project has risks, the developer hopes those risks are unfounded. If new technologies are required to complete the job, the developer holds hopes that their inexperience in those areas does not cause delays. In summary, the developer wants maximum money for minimum work.

The clients’s goal is to get the most work possible from a flat-rate contract or get the most work done in the fewest hours for an hourly-rate job. They expect bug-free code — done fast! They want the project to be done on time, preferably early, and have their product (A) making them money right away and/or (B) be able to bring it in-house to plan out future money-making updates. In short, the client’s goals are the exact opposite of yours.

Now, think back to every project that didn’t go as planned. You’ve no-doubt taken a host of lessons from these: maybe you didn’t nail down the requirements well enough, you mis-estimated the client, or perhaps there were too many bugs and you spent too much time fixing them to cut a good profit (i.e., your hourly rate dropped too much). Think about each of them. And, if you do, you’ll realize that there are several patterns that emerge.

Yes, patterns. Like design patterns. What I’m about to tell you is that clients have a set of patterns, strategies if you will, to meet their goals for a project. So let’s do this thing — we’re on to you, fellas! Let’s reveal the client gameplan!

False Representation

The next time you’re establishing a contract with a new client, pay attention, because this one *ALWAYS* happens. Here’s how it’s done.

The client contacts you with a project proposal. The project is “pretty straightforward” or “simple.” All you need to do is maintain a list of ___________ that you retrieve from a server they already have. Or maybe they “have a guy” who can do it in no time. The user does a few “basic” things and there ya go, the app is done. They might need a “couple of extra features” but “for the most part” that’s “about it”.

Sound familiar? Of course it does.

False Representation is the client’s tactic of delegitimizing the project’s complexity. You’ll be led to believe that the work is simple and if you don’t think it’s simple then you’re probably not cut out for the job. The macho pride that is the hallmark of every quality developer is a strength that is manipulated into a weakness in such a way that would make Karl Rove proud. (From his rotting, underground lair.) To be honest, clients may not even realize they’re doing this. All they want is get you to quote a cheap price. You can’t blame them, really. It’s their job.

One of the worst cases of this I’ve ever seen happened when a Network Diagnostics company came to us about re-implementing their Java-based application in Flex. The pitch was classic False Representation:

What we need is a simple port of our application from Java to Flex. We understand that Flex applications can be built much quicker and, since the application already exists, we won’t even need requirements. Nothing complicated. We’ll arrange for each of you to have a copy of the application and the source and we’ll have a small team available for consulting. It should be a piece of cake for you guys.

The sign that you’re getting hit with this tactic is the soothing language. Everything will be simple. The app is very straightforward. These guys even went the Full Monty on us and presented one of the most misleading tours of their product imaginable: they showcased the two main screens of the applications, discussed the behavior, and called it a day.

I wasn’t part of that presentation, but the initial SWAG was made based on it. After I joined the team, another presentation was made before kicking off development. Screen after screen after screen after screen…it was endless. Where developers were previously convinced that the other screens were very much the same, the client had not let on that the data and behavior were completely different — and there was a LOT of data, and it all required more custom behavior. After the meeting I was like, “You guys think this is two months?” and they explained how they hadn’t seen 85% of the stuff they just saw.

What was initially SWAG’d as a two-month effort took us a full year. The lesson here is that when discussing requirements with the client, either at introduction or in a formal analysis session, *IGNORE* their vocabulary. If the client thinks a feature will be easy to implement, ignore them. Evaluate it on your own. And if they’re demo’ing an application, keep a keen eye out for every menu item, every view, every corner and crevice of that application. And get a copy to play with yourself before you SWAG anything.

It’s a Bug, Not a Feature!

A favorite joke amongst developers is to be presented with some of the strangest, buggiest behavior in our code to which we reply, “That’s a feature!” While it’s just a joke for us, the opposite phrase will be a favorite of your clients’ — and it ain’t gonna be a joke to them.

The basis of It’s a Bug, Not a Feature! comes in the root philosophy of flat-rate contracts. The idea is that you are guaranteeing a set of functionality in exchange for a sum of money. The expectation is always that this functionality is only considered complete when there are no significant bugs included in it. The problem is that I have never, ever seen any language that defined exactly what constitutes a “significant bug” included in an SOW (Statement of Work).

Have I seen some language on it? Sure. Not always, but on occasion, yes. But it’s certainly not the kind that a lawyer has gone through. The difficulty is that bugs come in so many shapes and sizes, it’s simply impossible to classify them well. On top of that, as a developer, you will be inclined to win some equity from the client by fixing some bugs you wouldn’t otherwise need to. (Yeah, the easy ones, but still, they don’t know that, and you’re doing it for free anyway so you should get credit, right?)

What occurs is a tango between client and developer. The Tango Cod-ing. (Any Rent fans in the house?) Once the client starts receiving builds, the dance music begins. These buttons should be a darker shade of blue. You didn’t specify they should be skinned. Yes, but I can’t see them. Skinning them wasn’t in the contract, and I can’t draw. But, if they don’t stick out to the user, the app is broken. It’s a bug. Fix it or you don’t get paid!

It’s my belief that it’s the developer’s experience that determines the effect this has. The experienced developer is adept at identifying where a client has misunderstood what they themselves say they want. These developers have gained a feel for where the problems will be later and either (A) address it during the requirements gathering phase or (B) forsee it and code it the right way anyway. They know that they have gone against the will of the client, but they’re also confident they know it’s what they’ll want.

Experience can’t be bought. The less-experienced developers will have to fight clients on these issues for a while before that intuition builds up. If you find this is happening to you, you can combat it somewhat by being more proactive with the client. Be pushy on their desires if you feel they will dislike their own idea later. Trust yourself. It’s what they’ve come to you for. Tell them why. Don’t be afraid, the client wants someone who can guide them. It will boost your credibility and ease your workload!

Deadline Shoveling

This is the one that sometimes makes me want to simply leave the industry entirely. :-) Tell me if this sounds familiar…and you don’t even need to be on a contract to have it happen…

You’re working on a 3-month project and there’s a week left. You’re excited! All the hard work is about to pay off in a released product. It’s going pretty well, but you have a little more work than hours available so you’re going to have to put in some 10 hour-days (at least). Monday, Tuesday go by and you’ve worked 21 hours. Wednesday you put in some serious crunch time and work until 2 AM. Thursday you still manage to push out a 9 hour day before heading to sleep early, but things look good for Friday! Friday comes and at about 10 AM you are pulled into a project meeting:

Jim just got off the phone with Bob and he said he wants to add a new screen that allows you to rotate the interface in 3D space. They can push the deadline a few days, but they really need to have it by Wednesday because there’s a tradeshow on Thursday and they really want to show this feature off to the industry drivers.

I really don’t know if these tradeshows exist, but they come up quite often, eh? It’s a great way to specify a deadline and not have to negotiate it. The client says they’d loooooove to give you more time, but the tradeshow can’t be pushed back. And now your manager has no room for negotiation. They want to keep the client happy and there doesn’t seem to be room for compromise. The killer feature the client decided 5 days in a advance simply had to be completed has to be shown off at the immovable tradeshow. And if the client were to become unhappy, at the last minute, your manager’s manager may not be too please come promotion time.

So, you have to kiss that weekend plus a comp’d Monday goodbye (no more Vegas!) and you put in 15 hours on Saturday and Sunday and a massive 26 hours Monday and Tuesday and you’re tired. But the code is in place — though it ain’t pretty. But, you’re done.

Wednesday comes, hold the phone. The design isn’t gonna fly. They’ve decided not to show it off at the tradeshow, but now they want to do a presentation for the CEO first-thing Monday morning. And guess who has to fix the design?

Don’t laugh, and don’t point fingers! This happens all the time! It transcends development, this is about business. Keep the client happy and future work will come. It’s justified by the fact that the project is almost over. It always seems to happen (to varying degrees) and it’s brutal. I was once on a project that had done this for months, sans the huge hours. After 4 months of having a deadline pushed at the last minute, I simply didn’t care anymore about the product. I hoped it would succeed, but I really didn’t care anymore. It’s massively demotivating. Development is about setting a goal and getting it done and celebrating the accomplishment. If you pull out the accomplishment, it’s just work. Never-ending work.

The only way to fight this is with good management. In many cases, this isn’t going to be on you. Your representation has to fight for you, and this may or may not happen depending on who it is doing it. Be sure to communicate the time you’re putting in and the de-motivation. Make it known that you want clearer milestones, that you are willing to do more work in a proper timeframe, but you need a realistic goal, predictibility and more trust in the client if you are going to create a great product.

Now Let’s Get Back to that Good Code, Shall We?

So how does this all relate to good code? Well, my gosh, it has everything to do with it! Look, you’re a developer capable of writing good code. How do I know? You wouldn’t even be reading this if you weren’t! How many happy-to-be-a-lacky developers will read an article about “good code?” None, that’s what. But *YOU* want to write good code.

Can you? Not if the client is pulling these shenanigans!

Get familiar with these tactics, learn how to prevent them, and you’re going to open yourself to a freer world of time and expectations. In that environment, you can take the principles your favorite authors have taught you and fulfill the implementation of a world of good design. With good project planning, minimal surprises, and creating a good pace with your team you can hit all of your milestones coding the way *YOU* want to be.

Good luck out there!

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
08.01

As developers, we tend to be categorized by our specialties:

There are backend developers, those who work with databases and scalable architectures with systems like Java EE or .NET.

There are Web developers, those who either specialize in PHP, Rails, and Django or perhaps HTML, CSS, and JavaScript.

There are frontend developers, specialists in the UI. Flex, Silverlight, Swin–*cough*–Swing…and we even sometimes refer to Web developers this way as well.

Then there’s the Mobile developer. We work with iPhone, BlackBerry, Symbian, Android, Java ME, and whatever Windows phones remain on the planet.

Five years ago, I could give you a long list of reasons why I’d be more qualified to take on a new mobile project, even if it was a new phone technology I was unfamiliar with. When the iPhone was released in 2007, I knew I was more qualified than any other non-mobile developer to take a stab at writing an app. It wasn’t that I knew iPhone (or Objective-C, or even Mac!), it was that I knew mobile. I was a mobile guy.

Here’s a long list of qualifications that I believe defines the classic mobile developer:

  • Writes code in a low-memory environment, handling more common out-of-memory errors and creating low-memory algorithms.
  • Writes highly optimized code that runs efficiently on low-performance devices.
  • Writes applications that can target a diverse set of devices that may include black & white vs. color screens, tiny to moderate amounts of RAM, differing platforms such as MIDP1 vs. MIDP2 or CLDC1 vs. CLDC1.2, etc.
  • Writes software for a platform other than the machine they’re developing code on.
  • Has the knowledge to install applications in a variety of ways depending on individual platform requirements. (USB, Over-the-Air, serial cable, etc.)
  • Writes software on obscure platforms like Java ME, Windows CE, or the hybrid BlackBerry API.
  • Able to code to multiple API’s at once, for example when GPS was still being standardized and you had both JSR 179 and private API’s for varying phones that produced varying results. (Good luck with device coverage back then!)
  • Able to design an application that can be built by multiple SDK’s simultaneously.

There’s more, but let’s stop here. Hopefully we can agree that these qualities are what allowed us to identify a mobile developer as such.

Something’s changed, though. It happened subtly. Back in the “old days,” phones came and went quickly, all with their own private API’s, and the technology was improving rapidly. We saw Java phones, BlackBerry’s, Windows, tons of manufacturers like Symbian and Samsung and all the PAYGO phones.

Nowadays, things have slowed down.

The New Mobile Developer

In the last three years, the mobile landscape has been dominated by just three platforms: iPhone, Android, and BlackBerry. I exclude Palm from this because, well, no one has a Palm. (BURN!) And I’m eager to drop BlackBerry as well because RIM has always been awful at cultivating a development community. There are plenty of other phones, and some, like Symbian, still control major portions of the market, but we all know that’s going away soon.

Over these three years, we’ve seen iterations of the iPhone along with iterations of their SDK. Even when the iPad was introduced, the SDK was almost exactly the same, and you could build for both iPhone and iPad easily. When the iPhone 4 was released with a higher-res screen, they made sure is was exactly twice the size. Not only was it simple, you retained all your skills and didn’t have to deal with a new, custom SDK.

Android phones have come out in large droves as well. While I predict that Android-powered phones are breaking the market up into so many pieces that developers will soon flock in droves away from the platform, it’s still an important one today. (Java ME developers know what I’m talking about — that feeling of wanting stab yourself with something very sharp come deployment time.)

The iPhone benefits from modern software modules. Remember the past when you needed an XML processor and you were forced to choose from libraries that might be called MiniXML or TinyXML? Not anymore. I remember spending DAYS trying to find a SOAP library for Java ME. I ended up having to roll my own. :-( Today, most of the Mac libraries used for desktop development now work for the iPhone untouched.

The same goes for Android. The limitations of Java ME made using modern Java libraries impossible, and there simply wasn’t significant demand to have them all re-written. Android has more power, and with it, most Java frameworks can be installed on the phone without issue…and if there is a problem, there is significant motivation to make it so. And it’s easy to do compared to doing it for Java ME.

Also, thanks to these new phone lines, low-memory and low-performance considerations are fading away. Play with an iPhone 4 for just a minute and tell me that you’ll need a mobile developer to be able to write software for it. HA! It runs faster than my laptop did just 5 years ago. (Not fair, that was a Windows machine.) Any serious developer can take their turn at it. Finally, quality software and competition is at the forefront, not fringe software availability.

You see this difference every time you look for an application for a favorite website of yours, and are literally outraged if it’s not there. “How could they not have an iPhone app??” You had zero expectations when you had your free Java phone.

I’m a Mini-Frontend Developer

For the sake of marketing, I do consider myself a mobile developer. I advertise as such and I regard Rapture In Venice as a mobile solutions provider. But, is the work I’m doing similar to what it was a few years ago when I was pumping out Java ME and BlackBerry apps for my clients? Certainly not. The only difference between me and a Mac programmer is a resizable window bar.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
07.31

This blog seems to have sparked a little bit of backlash towards me as if I were an irresponsible developer making things worse on my peers. I assure you, it’s not true. Sometimes, in business, we have to be willing to accept a little more work than we’d like or a little more hardship in general to gain something back. What was gained from the client was (A) good notoriety for having worked with them and (B) the promise of a longer and more lucrative Phase II. In all things, there is give and take. We gave as much as took.

When you hit your teenage years you decide you want to be a software developer. During your high school years, you learn how to write software using object-oriented principles. When you graduate to college, you apply all the principles you’ve learned to areas such as Artificial Intelligence or 3D graphics.

And when you hit the professional circuit, you begin your never-ending quest to write commercial-quality, maintainable, and “perfect” code that will stand the test of time.

Commercial-quality. Huh. That’s pretty funny.

I consider myself lucky, I *love* design patterns. I like studying the theory of coding perfection. I have no problem starting up an hour-long discussion about why my XP partner’s choice of inheritance hierarchy is wrong — that HAS-A is better than IS-A in so many cases. But something has been bugging me lately and I am wondering something…

…is good code impossible in modern software development?

The Typical Project Proposal

As a full-time contract developer (and part-time), I spend my days (and nights) developing mobile applications for clients. And what I’ve learned over the many years I’ve been doing this is that the demands of client work preclude me from writing the real quality apps that I’d like to be.

Before I begin, let me just say it’s not for a lack of trying. I love the topic of clean code. I don’t know anyone who pursues that perfect software design like I do. It’s the execution that I find more elusive, and not for the reason you think.

Here, let me tell you a story.

Towards the end of last year, a pretty well-known company put out an RFP (Request for Proposol) to have an app built for them. They’re a huge retailer, but for the sake of anonymity let’s call them Gorilla Mart. They say they need to create an iPhone presence and would like an app produced for them by Black Friday. The catch? It’s already November 1st. That leaves just under 4 weeks to create the app. Oh, and at this time Apple is still taking two weeks to approve apps. (Ah, the good old days.) So, wait, this app has to be written in…TWO WEEKS?!?!

Yes. We have two weeks to write this app. And unfortunately, we’ve won the bid. (In business, client importance matters.) This is going to happen.

“But it’s OK,” Gorilla Mart Executive #1 says. “The app is simple. It just needs to show users a few products from our catalog and let them search for store locations. We already do it on our site. We’ll give you the graphics, too. You can probably — what’s the word — yeah, hardcode it!”
Gorilla Mart Executive #2 chimes in, “And we just need a couple coupons the user can show at the cash register. The app will be a throwaway. Let’s get it out the door, and then for Phase II we’ll do something bigger and better from scratch.”

And then it’s happening. Despite years of constant reminders that every feature a client asks for will always be more complex to write than it is to explain, you go for it. You really believe that this time, it really can be done in two weeks. Yes. Yes! We can do this! This time it’s different! It’s just a few graphics and a service call to get a store location. XML! No sweat. We can do this…I’m pumped! Let’s go!!!

It takes just a day for you and reality to once again make acquaintance.

Me: So, can you give me the info I need to call your store location Web Service?

The Client: What’s a Web Service?

Me: ………..

And that’s exactly how it happened. Their store location service, found right where it’s supposed to be on the top-right corner of their website, is not a web service. It’s generated by Java code. Ixnay with the API-ay. And to boot, it’s hosted by a Gorilla Mart strategic partner.

Enter the nefarious “3rd party.”

In client terms, a “3rd party” is akin to Angelina Jolie. Despite the promise that you’ll be able to have an enlightening conversation over a nice meal and hopefully hook up afterwards…sorry, it ain’t happenin’. You’re just gonna have to fantasize about it while you take care of business yourself.

In my case, the only thing I was able to wrestle out of Gorilla Mart was a current snapshot of their current store listings in an Excel file. I had to write the store location search code from scratch.

The double-whammy came later that day — they wanted the product and coupon data online so it could be changed weekly. There goes hardcoding! Two weeks to write an iPhone app have now become two weeks to write an iPhone app, a PHP backend, and integrate them togeth–what? They want me to handle QA, too??

To make up for the extra work, the coding will have to go a little faster. Forget that abstract factory, use a big fat for loop instead of the composite, there’s no time!!!!

Good code has become impossible.

Two Weeks To Completion

Let me tell you, that two weeks was pretty miserable. First, two of the days were eliminated due to all-day meetings for my next project. (That amplifies how short a timeframe this was going to be.) Ultimately, I really had eight days to get things done. The first week I worked 74 hours and the next week…god…I don’t even recall it’s been eradicated from my synapses. Probably a good thing.

I spent those eight days writing code in a fury. I used all the tools available to me to get it done: copy-and-paste (AKA re-usable code), magic numbers (avoiding the duplication of defining constants and then, gasp!, retyping them), and absolutely NO unit tests! (Who needs red bars at a time like this, it’d just demotivate me!)

It was pretty bad code and I never had time to refactor. Considering the timeframe, however, it was actually pretty stellar, and it was “throwaway” code after all, right? Does any of this sound familiar? Well just wait, it gets better.

As I was putting the final touches on the app (the final touches being writing the entirety of the server code), I started to look at the codebase and wondered if maybe it was worth it. The app was done after all. I survived. I SURVI-

“Hey, we just hired Bob, and he’s very busy and he couldn’t make the call, but he says we should be requiring users to provide their email addresses to get the coupons. He hasn’t seen the app, but he thinks this would be a great idea! We also want a reporting system to get those emails from the server. One that’s nice and not too expensive. (Wait, that last part was Monty Python.) Speaking of coupons, they need to be able to expire after a number of days we specify. Oh, and…”

Let’s step back. What do we know about what good code is? Good code should be extendable. Maintainable. It should lend itself to modification. It should read like prose. Well, this wasn’t good code.

Another thing. If you want to be a better developer, you must always keep this inevitably in mind: The client will always extend the deadline. They will always want more features. They will always want change — LATE. And here’s the formula for what to expect:

(# of Executives)2 + 2 * # of New Executives + Bob’s Kids = DAYS ADDED AT LAST MINUTE

Now, Executives are decent people. I think. They provide for their family (assuming Satan has approved of their having one.) They want the app to succeed (promotion time!). The problem is that they all want a direct claim to the project’s success. When all is said and done, they all want to point at some feature or design decision they can each call their very own.

So, back to the story, we added a couple more days to the project and got the email feature done. And then I collapsed from exhaustion.

The Clients Never Care As Much As You Do

The clients, despite their protestations, despite their apparent urgency, never care as much as you do about the app being on time. The afternoon that I dubbed the app completed, I sent an email with the final build to all the stakeholders, Executives (hiss!), managers and so on. “IT IS DONE! I BRING YOU V1.0!!! PRAISE THY NAME.” I hit Send, lay back in my chair and with a smug grin began to fantasize how the company would run me up onto their shoulders and lead a procession down 42nd street while I was crowned “Greatest Developer Ev-ar.” At the very least, my face would be on all their advertising, right?

Funny, they didn’t seem to agree. In fact, I wasn’t sure what they thought. I heard nothing. Not a peep. Turns out the folks at Gorilla Mart were eager to and had already moved on to the next thing.

You think I lie? Check this out. I pushed to the Apple Store without filling in an app description. I had requested one from Gorilla Mart and they hadn’t gotten back to me and there was no time to wait. (See previous paragraph.) I wrote them again. And again. I got some of our own management on it. Twice I heard back and twice I was told, “What did you need again?” I NEED THE APP DESCRIPTION!

One week later, Apple started testing the app. This is usually a time of joyousness but it was instead a time for mortal dread. As expected, later in the day the app was rejected. It was about the saddest, poorest excuse to allow a rejection I can imagine: “App is missing an app description.” Functionally perfect; no app description. And for this reason Gorilla Mart didn’t have their app ready for Black Friday. I was pretty upset.

I’d sacrificed my family for a 2-week super sprint, and no one at Gorilla Mart could be bothered to create an app description given a week of time. They gave it to us an hour after the rejection — apparently that was the signal to get down to business.

If I was upset before, I would become livid a week and a half after that. You see, they still hadn’t gotten us real data. The products and coupons on the server were fake. Imaginary. The coupon code was 1234567890. You know, phoney baloney. (Balogna is spelled baloney when used in that context, BTW.)

And it was that fateful morning, I checked the Portal and THE APP WAS AVAILABLE! Fake data and all! I cried out in abject horror and called up whoever I could and screamed, “I NEED THE DATA!!!!” and the woman on the other end asked me if I needed fire or police and so I hung up on 911. But then I called Gorilla Mart and was like, “I NEED DATA!!!!” and I’ll never forget the response:

Oh, hey there John. We have a new VP and we’ve decided not to release. Pull it off the App Store, would you?

In the end, it turned out that at least 11 people registered their email addresses in the database, which meant there were 11 people that could potentially walk into a Gorilla Mart with a fake iPhone coupon in tow. Boy, that might get ugly.

When it was all said and done, the client had said one thing correctly all along: the code was a throwaway. The only problem is it was never released in the first place.

Rush To Complete, Slow To Market

The lesson here is that your stakeholders, whether an external client or internal management, have figured out how to get developers to write code quickly. Effectively? No. Quickly? Yes. Here’s how it works:

  1. Tell the developer the app is simple. This serves to pressure the development team into a false frame of mind. It also gets the developers to start working earlier, whereby they…
  2. Add features by faulting the team for not recognizing their necessity. In this case, the hardcoded content was going to require app updates to change. How could I not realize that? I did, but I’d been handed a false promise earlier, that’s why. Or a client will hire “a new guy” who’s recognized there is some obvious omission. One day a client will say they just hired Steve Jobs and can we add alchemy to the app? Then they’ll…
  3. Push the deadline. Over and over. Developers work their fastest and hardest (and BTW are at their most error-prone, but who cares about that, right?) with a couple days to go on a deadline. Why tell them you can push the date out further while they’re being so productive? Take advantage of it! And so it goes, a few days are added, a week is added, just when you had worked a 20-hour shift to get everything just right. It’s like a donkey and carrot, except you’re not treated as well as the donkey.

It’s a brilliant playbook. Can you blame them for thinking it works? But they don’t see the god-awful code. And so it happens time and again despite the results.

Code Impossible

In a globalized economy, where corporations are held to the almighty dollar and raising the stock price involves layoffs, overworked staffs, and offshoring, this strategy I’ve shown you of cutting developer costs is making good code obsolete. As developers, we’re going to be asked told conned into writing twice the code in half the time if we’re not careful.

What can we do about it? Check out Is Good Code Impossible Part 2: Project Manipulation Patterns next.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit
2010
07.25

I was tuned in to the Three20 framework about 4 months ago just before we were to start work on an app for a pretty well-known sports retailing client. I was impressed with all the “goodies” it provided, specifically the photo browser, dashboard, and persistence system so that I could write an app that continued from where it left off when closed. I planned to have all of this in our new app, so I decided we’d base it on Three20.

There’s not a huge amount of material out there on the framework, so before you start wading through the Three20 documentation, separating the outdated material from the newer stuff, I hope to quickly review my experiences with the framework so you can decide if it’s right for you.

The Good

To start with, there’s plenty of GOOD in Three20. Actually, some of the best benefit is just going through some of the code. It’s pretty well-written and really flexes the iPhone SDK. But apart from that, there’s plenty of great stuff to use right out of the box.

URL Navigation

When you write your own iPhone apps, you may tend to have several areas of your code creating a UIViewController and pushing it on to the navigation stack. If you’re smart, you centralize this code so you can create settings pickers or photo albums in one place, even if you can navigate to them from more than one screen.

Three20 allows you to configure navigation maps that let you navigate easily via special URL’s which take care of displaying the appropriate screen. For example, you can set up tt://profile/photos to open and display a MyPhotoBrowser view controller.

It’s real handy. However, there are some complexities that may ding you later, especially in regards to providing arguments and sequencing several in a row. (All doable but have fun finding out how to do it.)

Useful Helper Methods

Three20 includes a large set of preprocessors, inline methods, and categories that really address the core of what you need to do often with the SDK. I wish a lot of these were in the iPhone SDK actually. Even when I decide not to use Three20, I’ve borrowed a lot of these for my own code (and added quite a few more!) My favorites include TTRectInset, calls that allow you to specify hex colors and, well, a ton more! You’ll just have to check em all out. ;-)

Overall, you’ll be inspired and become completely dependent on what’s in Three20. If you don’t use the library, it’s a great lesson to build your own!

Button Styles

Three20 comes equipped with a set of sample projects. One of those is TTCatalog, a great demo of everything in the library. When you go through it, you’ll find it impossible not to be endeared with the button skinning portion that lets you create buttons that look like they were iPhone native, all with variable sizing, arrow buttons, and more. It’s great work done by the team and easily the most useful part of the system.

TTImageView

Internally, Three20 has a module called TTURLRequest which leverages an even lower-level system to cache data that’s been downloaded. The combination of these two allows for the excellent TTImageView control to exist.

In short. TTImageView lets you to add an image to your interface that is loaded from the web. This is the simple kind of thing that almost every one of us needs at some point and it’s devilishly tricky to write correctly. TTImageView allows you to write this:

_logo.urlPath = @"http://www.raptureinvenice.com/images/logo-text-with-tag.png";

Why write your own? This one works and works wonders.

Views, Views, Views!

Three20 provides you with some pre-built screens that many of us require quite a bit:

  • A Photo Browser — Very similar to what’s on the iPhone.
  • A Photo Album — Displays multiple images in a grid space. Think: Photos app.
  • A Dashboard — A re-implemented iPhone Springboard.

The Bad

Despite all the good stuff, there’s some stuff Three20 just didn’t get quite right. It’s not much, but even if you use Three20 you may want to avoid it.

Stylesheets

This is hard for me to put here because it’s supposed to be one of the sweet spots of Three20. Imagine! CSS! On iPhone! Well, I just don’t feel it’s done right.

For one thing, you can’t specify all of your properties in one place. Say you have a UITextField and you want to specify the text color, font, background color and some other properties. In CSS, all of this is included in one stanza, and it’s kept together. It’s easy to update, too. With Three20, though, you have to specify all of these values in separate places. The code gets bulky and it can get lost, especially because you’re not going to want to write 120 different methods that return a Helvetica Font.

I’ll set some standard colors such as the standard nav bar tint color or standard text color, but I find I really don’t use stylesheets otherwise. You’ll also find CSS simply isn’t as valuable on iPhone because there’s very little repetition going on anyway. It’s too bad, it should be one of the big wins in the framework.

Status Bar Color

This drives me crazy. Three20 decided it would be nice to take over how you set the status bar color for the app. Where once before it was simple, Three20 has made it complex. You have to specify it for every screen, and the default always seems to be gray. Ultimately, until you get it perfectly right, you get the joy of seeing your status bar change from gray to black or translucent as you go between screens. Lame.

To top it off, they don’t document what you need to do real well, so beginners will spend a good chunk of time trying to figure out why their UIStatusBarColor property isn’t working. I only accidentally stumbled on the fact that Three20 has hijacked this system and I’m so glad I did or I’d have spent hours tracking down my problems. ERRGGG!

Lack of Good Documentation

And that speaks to Three20′s biggest problem — the documentation is very poor. You will be completely dependent on the sample apps. And when there *is* documentation, you’ll find it’s often out of date. The forums aren’t exactly bustling, etiher.

Bottom line, if you choose to use Three20, be sure to give yourself enough time to pour through some code and search for the docs you need. And, hey, if you can, contribute some documentation back! :-)

The Ugly

Aside from the bad, some stuff is downright ugly and deserves a callout.

New Project Structure

Three20 recently changed their project structure so that instead of a single Three20 XCode project to include with your app, you now get 7. Now, presumably they separated it this way to remove some dependencies and make builds easier. The problem is that you often need to look through the Three20 code to figure out what’s going on and, well, you never quite know where to look. So you have to open project after project looking for what you need. It was so much easier before.

I hate it.

Table View Controllers

Three20 changes how you use tables, too. They’ve adopted a style where you define your rows in advance, and then the table just uses what you gave it. At first, I found this much simpler. However, there are simply WAY TOO MANY things that become more complex or downright annoying when you do it the Three20 way:

  • Customizing individual rows – Forget it, it’s a nightmare.
  • Caching/Optimization – You lose the optimized way UITableViewDataSource re-uses rows. It’s gone. So, don’t be using this system if you have hundreds of rows to display.
  • Creating new row styles – Brutally obnoxious. The table framework has been over architected. You’ll find that you need to change the framework itself to add new types of rows. Really?

After my team finished work on our maiden Three20 app, we all agreed we wouldn’t use Three20′s table framework anymore. And we’ve been much happier since. U-g-l-y.

UI Persistence

It’s probably unfair for me to put this here. UI persistence is one of the great draws to Three20. Imagine, you get built-in persistence so that when a user closes the app, they start right back where they were later.

Unfortunately, it’s not the easiest thing to use in the world. However, put in some elbow grease and you’ll have it licked. No, the problem is that we don’t really need it anymore with iOS 4. Well, that’s not totally true, with Three20 you can always guarantee you will start where the user left off, regardless of how iPhone manages the lifecycle. But, really, it’s not worth injecting this much architecture into the task anymore.

So, use iOS 4 for your UI persistence, and leave Three20 behind.

My Overall Recommendation

Whether you use Three20 or not depends on what kind of app you need to create. Overall, however, I’d say skip it. You get a lot of useful stuff, but it’s so easy to cull a few ideas out of it and go it on your own that it’s not worth the added risk of running into a Three20 behavior that leaves you stuck to find a workaround. On top of this, the table architecture, UI persistence, and stylesheets are too bulky and too unusable to be polluting your code with.

The two pieces of Three20 I’d create for yourself are the preprocessors and the URL navigation. I’ve created my own preprocessors that go far and beyond what Three20 put in, and they are tailored to the things I want the most. So I no longer need Three20 for it. I recommend you do the same. (One day I’ll post mine perhaps.)

The one condition for which I’d recommend using Three20 is if you have a need for the several views they provide. Instead of writing your own springboard, use Three20′s. The photo browsing views are very well done, too. But, if you only have a need for one or two of these screens, or none at all, it’s more worth it to write your own. Taking a couple days to do it (or find another 3rd party version) is going to be worth the extra time you’ll need with Three20 later.

Conclusion

I hope this review has been helpful to you. If you haven’t used Three20, I recommend you at least check it out for a day or two. Every developer has their own preference. Mine certainly was with Three20 initially, but it just quickly fell out of favor.

And if I’ve misrepresented the framework here, please comment and let me know.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Twitter
  • DZone
  • LinkedIn
  • Reddit