Expectation management is a big part of software delivery. Unless you write software for a living, it’s hard to appreciate how much work goes into the little white box you see on the Google search screen, or the math and physics behind a game like Angry Birds.
Having just finished my first iPhone app, even I was surprise at the amount of work it took to take a few pictures and generate an email to send to a couple of friends.
Building on this post from Kent Nguyen, I thought it would be fun to share some of the behind the scenes magic that makes these simple apps work.
The app itself is pretty simple. It’s called takemystuff (sorry not available in iStore yet) and it basically helps people give stuff away to friends.
Basically, you take pictures of stuff you’d like to give away.
Select the friends you’d like to tell.
And then it builds you an email combining the images and tagged with the friends you selected.
That’s it! Pretty simple eh? Here’s some of the stuff that’s going behind the scenes.
1. Taking pictures
To build a screen that takes pictures and then displays thumbnails in a table
you need to:
- Tag images as they are taken (to separate yours from those taken with the regular camera).
- Track which ones are selected/unselected, and
- Save that information something to be accessed later.
That’s the minium amount of work required to just make it work. Here are some of the wrinkles.
Image capturing is asynchronous
iOS saves images you take with the camera asynchronously. That means when you take a picture, it’s not instantly there for you to display. You have to wait.
Then when the worker thread is done, you are free to refresh the table on the screen.
Not a big deal, but it complicates things because you need to put refreshes in the appropriate places and it’s not always obvious where. It also requires a lot more manual testing (more on than later) and a fair bit of trial and error.
Table cells are pooled and reallocated dynamically
The engineers to Apple have gone through great lengths to make the iPhone fast. One way they do that is to dynamically allocate and reuse cells used for rows in tables.
For example you might have x100 photos ready for display. But when you bind them to a table, a much smaller number gets shown.
That means you need to create data structures outside of the table itself to track which photos are displayed and whether they are selected.
It’s not super hard but it’s non-trivial work.
And if you collect a lot of metadata for each picture you’ll either have to make use of something complex (like CoreData) or track and synchronize these data structures yourself (through things like Arrays and Dictionaries).
Location services are what the iPhone uses to tell apps where they are. Foursquare, Weather, and Maps are obvious services that could use this kind information.
But cameras can use this information too. And while I didn’t require location services but your app might.
That means you need to check at runtime whether the service is turned on, and inform your users of what they should do if it isn’t.
Now let’s take a look at some of the things you need to deal with when compiling a list of friends.
2. Selecting friends
Selecting and adding friends on a simple table like this is a bit of work. You need to:
- Pop open the address book and detect which friend was selected
- Extract the friend data and handle all the edge cases of there not being a first or last name, or even an email address
- Add logic to make sure choosing a friend on screen is synchronized with friends chosen in your data structure
- Add logic to delete (right swipe) or remove a friend from your list (and again synchronize that with your data source)
- Handle all the refreshes from your data structure changing to that on the screen
Then you need to popup and hide the appropriate alerts and error messages if your users have data you either didn’t expect or can’t handle.
Again, a fair bit of work for what looks like a dead simple screen.
Now let’s take a look at what it takes to bring it all together in an email.
3. Building the email
Here we grab the photos selected by the user from the first screen and combine them with the email addresses selected from the second. Here’s how that works:
- First you need to walk the assets library and extract all the photos you tagged with your application (more asynchronous programming).
- Then you need to grab and parse the email address of the friends.
- Then you need to combine those and create the email.
- If they choose not to send the email, you need to handle the ‘Cancel’ button being pressed and make sure you transition them back to their previous views (which you also need to track.
And then you need to handle the cases of where they didn’t select any photos or they didn’t select any friends.
Other stuff that needs to be done
This application doesn’t have a lot of of art but I still needed to create some icons for the tab bar and one for the application itself.
Deploying to the app store
This was (still is) probably the most painful part of the iOS development process. Trying to get your work on other peoples devices.
I won’t go into all the details but you need to jump through a lot of hoops just to test your app on another device.
- You need to get their device ids.
- You need to create certificates.
- You need to create deployment profiles
- You need to copy/email files around with complex instructions for how you testers are supposed to load you app.
- And then after doing all that it still doesn’t work with little or no feedback as to why
It’s a tough, frustrating process it’s no wonder startups are forming just to help you deploy your iOS application.
If that’s not a wake up call to Apple that their deployment process is overly complicated I don’t know what is.
A lot more manual testing
With so much application code directed to the UI, mobile apps require a lot more manual labor intensive testing.
Yes there are frameworks and tools that can help but I have yet to see anyone favor these over repeatedly clicking through your app and making sure everything works.
And while you can unit test, it doesn’t deliver the payback we’ve grown accustomed to on server side frameworks like Rails and Java/.NET.
And we aren’t even doing anything complicated!
This app doesn’t do any:
- custom graphics
- sound and audio
- custom UI
- push notification
- in app purchases
All areas of hairiness and complexity and hairiness. Not to mention that there’s no backend to this app. It’s all local to the phone (which simplifies things greatly but limits what the app can do).
Writing great software isn’t cheap or easy. It takes a lot of hard work, dedication, and persistence.
And everything I’ve said here about mobile apps applies equally (though in different ways) to enterprise apps and backend systems (just imagine the complexity Google or the guys at DropBox regularly handle).
So the next time someone tells you that building that screen shouldn’t take more than a couple hours, smile, be patient, and understand where they are coming from. To our users much of what we do is magic. It looks easy and they expect it to work.
Explain to them some of the challenges. Be upfront and honest about the cost. And know that you are not alone. Managing expectations is a big part of being a software professional and setting expectations on software projects ain’t easy (though I know a book that can help).