Hiltmon

On walkabout in life and technology

TimeToCall - Shipping

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 10, the last part in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iOS app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 9 or start at part 1 first.

Is It Ready to Ship?

Probably the hardest part of the process to craft a quality application is to decide when to ship it. This is because there exists a tradeoff between whether to ship the application with its current feature set or whether to delay shipping to add new features.

In a way, the decision is easy:

Good developers develop,
Great developers ship.

But most developers have a hard time getting there.

Why would it not be ready to ship?

I mean, you’ve gone through all the time, effort and cost (part 1) to design, build (part 2), think through (part 3, part 4, part 5), sweat the details (part 6), polish it (part 7), add some MacGuffin features (part 8), beta test it, set it up on the app store and create the collateral (part 9). What could possibly be the holdup?

The most common reasons are shipping fear and feature creep.

Shipping Fear

Up until now, only a handful of your peers have seen and used the app. They have been supportive, helped you test and provided constructive criticism. You have been living and working in a bubble.

But now it’s time for the app to leave the nest.

And we developers worry. What if there are bugs we don’t know about? What if the public does not like it? What if the data in it is wrong? What if there is a better product out there? What if the Apple reviewer rejects it? What if we get sued by a patent troll? What if we did all of this and it does not sell any? What it it crashes on everyone else’s device? What if they hate it?

Shipping fear affects all developers, we are perfectionists and we never believe our own products are finished or even good enough to go out the door. We need to face our fear and know that we can, and will, correct anything that got past our eagle eyes and the brutal test by our Beta users. We can always issue an update.

Or recite the Dune Litany of Fear to get through it:

I will not fear.
Fear is the mind-killer.
I will face my fear.
I will let it pass through me.
Where the fear has gone,
there shall be nothing.
Only I will remain.

Feature Creep

This reason delays more shipping than anything else. We decide to add just one more feature before shipping, and then another. Oh, and this user might need another MacGuffin feature so we’d better add that, too.

Or we see a competitor product has a feature that we lack, and feel that we need to have it in order to compete. We fear the feature comparison.

What we forget is that we’ve already chosen the initial release feature set, made it great and are ready to ship. If the missing feature is real and not a MacGuffin, we’ll hear the need loud and clear from potential customers and can add it in the next release. There is no point adding features that real users do not need, just to make someone happy or cross an item of someone else’s checklist.

There is a huge list of features that could be added to TimeToCall, some my ideas, some from my Beta testers. These include:

  • Adding dates to a TimeToCall so you can set reminders in your calendar.
  • iCloud sync between devices so all your installs of TimeToCall have the same data.
  • Weekly alerts when a call time comes up using built-in notifications.
  • Call or meeting durations to ensure that the end of the call does not fall into a ‘bad’ time.
  • Add phone numbers to calls so the user can just tap a phone number at the Time to Call to make the call.
  • Add attendee names to each location in the Time to Call so you know who is where.
  • Pop up an alert when daylight savings changes in a Time to Call so users know to ’play’ again to find a new optimal time.
  • Create a ‘floating’ location that uses the GPS as source for all calls, with a reminder to ‘play’ with time each time the ‘floating’ location changes.
  • Add a view in the App to market me and my company so I get more business

But I have added none of these.

Yes It Is Ready!

At some point, the product needs to ship. To repeat, the key is to find the minimal feature set to ship at version 1.0, and then add additional features afterwards.

This does mean that the product may be missing significant functionality on initial shipping compared to its competitors. As a developer, you need the confidence and the courage to ship and know that you can add features later. As a client, you need the app out there to help you get things done. Both parties need to get over shipping fear. Stand up, put your shoulders back, raise your chin, bring up your best steely gaze, recite the Litany of Fear and ship.

You and the client will then need the thick skins to deal with people who will tell you that they will not purchase your product because something is missing, or its too expensive, or there is something wrong with how you do things. But you have to get it out there for this conversation to even start.

And all that criticism is actually not a bad thing. The more folks complaining that something is wrong or missing, the more you get feedback on what to work on next. It does not mean you have to do what they want, but if their need happens to be on your to do list, you surely can use their commentary to re-prioritize.

At the end of the day, you cannot sell the product and start to earn the return on your investment unless you ship. You cannot build a buzz or market your or your client’s services until you ship. The effort is done, the cost spent, so ship it, start earning the return, start supporting real paying customers, start the conversation in public, and start working on the next features to ship.

I shipped TimeToCall. You can buy it in the App Store.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Dawdle to the Finish

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 9 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 8 or start at part 1 first.

Dawdle To the Finish

The end is in sight. But the light at the end of the tunnel is dim. There are many miles to go before TimeToCall can ship. Enough bad clichés.

We all believe in a “sprint to the finish”, but the reality is it’s more a long, slow slog to the finish. You need to nail the last bugs and usability issues, and that means a Beta test. You need to prepare a lot of stuff for the App Store. You need to create the support web site and optionally, the app web site as well. And if you like, you can go all the way and make a press kit and marketing plan, but I’ll leave that out for now.

Beta Testing

Up until now, the developer, and maybe a few friends and colleagues, have been the only people who have seen and touched the product. To paraphrase Helmuth von Moltke the Elder, no application survives contact with real, live users. You need to expand the testing group to a bunch of opinionated people outside your comfort zone. People with different experiences and expectations, people who would use your application, but maybe in ways you never dreamed of. And people who are not afraid to constructively criticize the app.

And honestly, as a developer, you don’t always see what you are missing. It’s why writers have editors, sports people have coaches, and I guess we all have parents.

TimeToCall is a simple app, but I still ran a Beta test. It was short, just 2 weeks. In that time, I issued six releases. Yes, for a simple, 4-view app, there were a lot of changes. Many have been described in Sweating the Details and Polishing the App, but here area few more ‘gotchas’ found:

  • The ‘playing’ with time slider worked great on all hardware except the original iPad. Somehow the clock animations were locking up the main thread and making the slider “sticky”. I dusted off my old iPad 1 to test. Yikes! It was worse than sticky, the slider was completely unresponsive. But I wanted iPad 1 users to be able to run the app. Since UI drawing on iOS needs to be on the main thread, I made it work by adding a delay in the animation start when the user finishes moving the slider, and I kill animation as soon as the slider is touched. It works better on the iPad 1, but feels worse on all other devices that can handle real-time updates.
  • The app did not rotate on iOS 5.1 iPads (I disabled rotation on iPhones). Since all my usual devices are iOS 6.x, I had not noticed this. On the original iPad, no iOS 6.x, no rotation. Since I had developed this app using the iOS 6.x libraries, the calls to accept rotation had changed. So I added them in.
  • Our Japanese users sometimes searched for places in English, but because I had replaced all English city names with their Japanese counterparts, it did not work. As a result of Beta feedback, I made both available.

To simplify the process of Beta testing, I used TestFlight without it’s API, just to create a team and share the updates with them. It sure made the process of distributing betas and getting feedback easier. Their API adds the ability to get analytics from within the app as well as crash reports back. I felt that this app was too simple to need that complexity, so I did not use the API this time.

I think that for bigger commercial-grade applications, I would use the paid HockeyApp product for better production-level analytics and crash logs.

Prepare for the App Store

You cannot ship an iOS app without setting it up on the App Store (unless you are a large corporation). And there is a lot of work to do there as well.

Firstly, you need to sign up for a $99 a year developer account to enable you to sign and ship software through it. You also need to issue the developer certificate, ad-hoc certificate (for Beta releases) and distribution certificate for the final release. And if you use iAd, in-app purchases or Game Center, you need to set those up as well. And you need to register the Beta user’s devices so that they can test the app.

Secondly, you also need to set up the application itself in the store too. Create the name, set the app id (needed for the certificates) and input the basic information, including:

  • Choosing categories of the application, so people can browse to it
  • Setting up keywords to help people search for it
  • Providing contact information for reviewers
  • Setting the age rating
  • Picking a price for the app

Then you need a whole bunch of collateral to go with the app on the store, including:

  • A massive 1024x1024 image for iTunes Artwork (and a 512x512 one too). Apple uses these in the store and, if you are lucky, in their marketing too.
  • A textual description, “elevator pitch” or marketing blurb to describe the app to potential buyers.
  • And a set of 3-5 screenshots for each of the iPhone, iPhone 5 and iPad in Retina resolutions to show the app off.

Seems reasonable, but you also need for each localized language:

  • Another well phrased marketing blurb that expresses exactly what the app does in that language.
  • Another set of 3-5 screenshots for each of the iPhone, iPhone 5 and iPad in Retina resolutions in that language.

Be sure that the tone and content of each blurb matches the tone expected by folks in that region. My slightly humorous English blurb does not work in the Japanese market where the customer prefers a more serious and detailed explanation of what the app does.

Support On the Web

One thing you really do need on the App Store is a link to your support page. And, if you have a product marketing page, a link to that too.

One of the biggest problems in the App Store is that our customers don’t really know about the support link. As a result, if there is anything wrong with the app, they write a scathing review and give it one star. And other potential customers see the low star count and scathing reviews and do not purchase the app. Many a great app has failed because the reviews were really support calls and customers did not hit the support link.

There is nothing you can do about this. Except issue a new release. Apple’s App Store by default only shows reviews for the current version of the app. And most people never look at the all versions reviews. Which means that, as a developer, you need to get ahead of your reviews if they are bad and get a new release out without the problems very quickly.

But more experienced users of your app, or of iPhones or software in general, will look for the support link. Not only do they expect to see it, but they also expect it to work. Create a page somewhere that enables users to email you or fill in a web form to tell you what they are thinking. And monitor that address. And always respond to a support message.

One thing that static screenshots do not do is show the user how the application works, just how pretty it is. It is therefore recommended that you create a product web page that contains more information about the app. The best thing you can do is to create a short video that shows people actually using the app in the real world. There have been many occasions where I have made my purchase decision based on the video alone.

For TimeToCall, I am running a “teaser” page until the app is released, at /timetocall/. As soon as it’s released, I intend to replace the “teaser” page with a video demo and a bunch more irreverent text. Lights. Camera. Action!

Not a Sprint

The last few steps in the process of making an iOS app are basically paperwork, running the Beta test, setting up the store and setting up the web collateral. But they too need to be designed, planned, reviewed, checked for accuracy and correctness, and that too takes a lot of time that needs to be budgeted for. Fortunately, much of this time can be spent while the Beta is in progress.

Remember this, a great app with a terrible blurb, no support and no web site, will not sell. Unfortunately, the reverse may be true too. You really do not want to put all that time and money into an app and not get the bugs squashed, app store interesting and support available.

With all these steps complete, are we finally going to ship? Find out in the final part tomorrow.

Next: Part 10: Shipping.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - the MacGuffin

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 8 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 7 or start at part 1 first.

The MacGuffin

Not all the work Sweating the Details and Polishing is about making things better, correct or even perfect. Sometimes it’s also about personality, giving the application some character, or throwing in a MacGuffin or two, features that are expected, hidden on purpose, and not really needed.

The point of this post is to show that all software has features that user’s expect, demand and will most likely never ever use. But you still have to think about it, design it, program it, test it, sweat its details and polish it. It adds time and cost to the application, but just as the MacGuffin is a useless plot point that sets up a movie, so these features are needed to ‘complete’ the application, compete in the market on feature comparison lists, or just check the customer’s “I must have this” list.

The optimizer in TimeToCall is my MacGuffin feature, it’s expected to be there, but not useful at all. The purpose of the app is to ‘play’ with time, not solve it for you. And an optimizer cannot really pick the best time anyway. So, instead of developing a cold, boring, and logically correct one, I intentionally developed and shipped a faulty, opinionated one. It does not crash, it just picks the wrong times with regularity.

The Optimizer

As you by now know, the primary purpose of TimeToCall is to help people figure out the best time to call other timezones such that all participants are involved at convenient time in their locations.

The user can figure this out by ‘playing’ with time to see when these moments occur.

The idea of an optimizer is to come up with the single best Time to Call given an arbitrary source and destination set. That would not work as the optimal time is somewhere within a window of time, from a certain hour to certain hour.

Instead, I decided to find the earliest best time and latest best time to call, the ends of the window. But I needed to set some constraints to ensure these times were ‘good’. I did not want the earliest calls to happen before 7AM as that’s just too early, nor did I want the latest calls to happen after 10PM. Constraints set.

The optimizer logic is simple. The earliest optimizer finds the location furthest west, bumps it to 7AM, adjusts the remaining times and presents that as the best early time to call. Actually, it adjusts the source time such that the westernmost location is at 7AM. Tap the AM button to see it in action.

The latest optimizer does the same with the easternmost location, bumps it to 10PM and calculates back. Tap the PM button to see it in action.

Not bad. But not good either.

It has three glaring faults. Do you see them?

  1. It fails to optimize across the date line.
  2. It still optimizes to ‘bad’ times
  3. The edges of the ‘good’ window are generally the least-‘good’ Times to Call.

Optimize across the date line

Try Los Angeles and Sydney and optimize. The PM optimizer picks Sydney at 10PM making LA 3AM, yet optimally 10AM in Sydney is a great time to call LA at 3PM.

This happens because the starting point of the optimizer is the east/west divide, or GMT. It goes west of GMT and east of GMT. It should, instead, use the ‘distance’ in hours from a calculated midpoint, not east and west. An optimizer like that would pick better call times for the example set.

But I chose not to implement it. I wanted a faulty optimizer. This is the app’s MacGuffin feature, it can’t work, and it’s not supposed to work.

Optimized to ‘bad’ hours

Try Los Angeles, Sydney and London, hit PM and Los Angeles is in a ‘bad’ time to call (Sydney gets 10PM, LA is 3AM).

So why the ‘bad’ time? The time excluded by the optimizer’s constraints is three hours longer than the ‘bad’ hours (see Good and Bad Times to Call). It means that there are sets of locations such as the above where at least one location will have a ‘bad’ time picked by the optimizer.

This issue is also easy to fix. I could adjust the optimizer’s constraints to be 6AM on the earliest and 12AM on the latest, and it would work much better (all ‘good’ times to call). But in reality, even though the hours are ‘good’, they are not the way people normally work and think. I tried the change, and it made the app feel soulless and mechanical.

A faulty, or worse, optimizer just felt better. Then again, it is the MacGuffin feature.

Optimize to the Edges

The earliest best time and the latest best time are both valid times for the optimizer, but are pretty useless to the user. Times somewhere within the time window are going to be much better. The question is which time within the window is best?

I don’t know.

It depends on the user’s schedule, the people they are calling’s schedules, the day of the week, differing office hours, meetings, commute times, habits, etc. It may even change from call to call as people’s lifestyles change. There is no way for this simple app to know.

I could have written the optimizer to pick the middle time in the window. One could argue that logically that’s the best Time to Call given no other knowledge. But that is Vulcan thinking, not human.

Since we do not know the people involved’s schedules, the optimizer can only be a MacGuffin feature.

Shipping the Optimizer Issue

So I left the optimizer with its smaller constraint window, faulty starting point and edge seeker as is. But why?

One, it makes the application feel and work more naturally for the vast majority of timezones combinations, especially the closer ones. It only screws up when the locations are too far apart or there is nothing near GMT.

Secondly, the goal of the app is to enable the user to ‘play’ with time, not solve it for them. Moving the time slider up and down is interactive, fun and helps the user achieve their goal of choosing the best Time to Call. It really does not need an optimizer, but should have one, hence the MacGuffin.

Thirdly, I wanted my users to know they are smarter than the app. I hoped that my test users would not notice these intentional screw-ups. And I received no feedback on it during the beta. Instead, something amazing happened. My users gained a feeling of superiority, reward and achievement, because they could and did find a ‘better’ Time to Call than the software.

Fourthly, users want a suitable Time to Call within the ‘good’ window, not at the edges that are found by a mechanical optimizer. So they ‘play’ with time to find it. And optimizer really does not help here, it gets in the way (even a perfectly correct one) and that is why I made accessing it less intuitive.

And finally, the optimizer cannot choose suitable. The best Time to Call from the user’s perspective is somewhere inside the ‘good’ window, but where inside that window is a subjective decision, a user decision. You can’t write an optimizer to pick the best subjective time for call without access to everyone’s schedules. Which makes this a truly MacGuffin-esque feature. But since it is expected, best to give it quirks and a personality.

Once the application is released and in the wild, I will continue to monitor. I’m treating the optimizer as this application’s MacGuffin feature. I expect this MacGuffin will forgotten as people ‘play’ with time. If I get feedback that the optimizer is useful and not a MacGuffin, and my users want a less faulty one (note I did not write ‘correct’ one), I will release it in an update. If I get no feedback at all, which I expect to be the case, I will leave it as is, or even remove it quietly later.

Next: Part 9: Dawdle to the Finish.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Polishing the App

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 7 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 6 or start at part 1 first.

Polishing the App

An application is not finished and ready to ship when the screens work and it does not crash. An application is not finished when the animations and art are completed and the details sweated. It still needs to be polished. There still needs to be some serious work done.

Sweating the Details is all about making it work right. Polish is all about the invisibles, making it feel right and be useable by everyone. Polish makes the application be the way users expect it to be.

VoiceOver for Unsighted Users

Not all users of iOS applications have perfect vision. iOS enables them to use the iPhone using VoiceOver whereby the device says what the person is touching. They can then double-tap to activate that function.

Try it. Go to Settings / General / Accessibility and turn on VoiceOver. I have it set as a triple-click on my home button. Then try to use your iPhone (and close your eyes).

A good app supports VoiceOver. I needed to add the speakables to each element of the app so unsighted people can use it.

Internationalization away from English

And not all users of iOS apps are native English speakers either, so apps need to be translated into the local language for each market. The process is called localization and requires the developer to pull out all the strings in the app and get them translated.

Actually, Apple makes this really easy in Xcode, you just create a .strings file and then add languages to your app. Xcode creates the language versions of each for you.

For TimeToCall version 1.0, the only language I can localize it to is Japanese, so I did that.

But internationalization is not just a straightforward word for word Google translate. If you do that, you app will look terrible, and your users will notice it. You also need to take into account the nuances and conventions of each language and its culture. In TimeToCall, the terms used in the Japanese translation are not the same terms as per the English original, but are far more recognizable by Japanese users than the English translations.

Fonts and Sizes

The thing is, when you internationalize an app, the size of fields changes. Words that are short in one language may be long in another, and Kanji (or Chinese) characters are usually rendered larger than English capital letters. Which means that a label that looks right in one language may get truncated or cropped in another.

iOS has an autolayout feature that helps, but it’s new and confusing and only works on iOS 6. For TimeToCall, I wanted it to run on iOS 5.1 so I could not use autolayout. Instead, I polished the app by changing a field sizes and font choices by language to make sure the Japanese text was just as readable as the English and still looks balanced.

Fixing the Edit Field

I placed the name of a TimeToCall in an editable field inside a table cell on the Edit view. If the user taps the name, the keyboard springs up and the user can change the name. By default, the app uses a “Call from <Location>” placeholder, which is quite long. Deleting it takes time. So I added the clear field icon to make deletes quicker.

To edit in the middle of the name, though, you need to slide your finger along the text to move the caret to the chosen position. Now, your hands may be steady, but mine aren’t, so sometimes the whole row would scroll away. Polish means that that row does not scroll while you are editing it.

Polish also means that the keyboard should go away as soon as you are finished editing the name. This happens by default on the iPhone, but not on the iPad. It took me a long time, and a good few StackOverflow searches, to find the solution. It is sufficiently important to hide the keyboard that I needed to add a Objective-C category to UINavigationControllers just to make this happen. But from the user’s perspective, the application behaves as they expect it should.

New TimeToCall Entry

The conventional Apple approach to creating new records is for the user to tap a + button and a new item, filled with nice defaults, pops on the top of the list. Then the user has to tap again to show the detail, and tap again to edit it to set it up. This leads to many copies of the default entry being left in the list and too many steps to create a new entry.

So, when polishing the app, I set the + button to launch the edit window directly and to present a default Time to Call. If the user hits Cancel because they did not want a new one, no new one is created. If they tap Done, then a new row is added.

One tap to add new. Much better.

When to Scroll or Search

The Pick a Place view lists all places to enable users to browse and find a place they need. It also has a search bar to help them get there quicker.

To add a new place to a Time to Call, using standard behaviors, you would tap on Tap to Add a New Place and the picker would come up displaying the list at A. You would then have to tap the search field to bring up the keyboard, then search, then choose a place. Again, too many taps.

After polishing, if you tap on Tap to Add a New Place, the app focusses on the search bar and has the keyboard up and waiting. Lovely.

But what if you already have a place in that row and want to change it. What should the app do? Well, if it follows the ‘add’ idea above, the app would jump to search, the user would not be able to see which place was being edited, and has to cancel to browse. Not optimal. Instead, it should show the user the current place in the list so they can decide whether to change it or leave as is.

That is what users expect, so that’s what it does.

And that is why we spend the time and effort to polish.

Next: Part 8: The MacGuffin.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Sweating the Details

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 6 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 5 or start at part 1 first.

Sweating the Details

Once the core product is written and the design implemented, the next step is always to sweat the details, making sure the little things work right, aligning the planets and making the experience that much better. User’s don’t, and should not, notice when you have sweated the details, but it is glaringly obvious to them when you have not done so.

Sweating the details and polish (see a later post) are the activities and time spent that add the essence of quality to an application. It takes time and thought and iteration, but you cannot produce beautiful software experiences without it.

There is no one right way to sweat the details, the only approach I have ever used is to use the app a lot, show it to my friends, and see what breaks, annoys, or just does not work right. Then work it until it does.

Here a some of the details in TimeToCall that were sweated, and solutions chosen.

Slider Accuracy

Initially I had the time slider set up so that it represented every minute of every day. Logically, this makes sense since we’re trying to ‘play’ with time in the app. But the problem was that my fingers on the tiny iPhone screen were never able to drag the slider to exactly the time I wanted. It was always off by a few minutes. It was less hard to hit a chosen time on the iPad as the slider is bigger, but still hard.

I considered snapping the slider within a few minutes of the ten minute mark, but that missed quarter hours, and 5 minute snaps were too small to hit too. So I changed the slider to snap to 15 minute increments. It’s now easy to hit a ‘round’ time, and who really schedules calls at 9 minutes past the hour anyway. The result was as intended, it is now easier to drag the time slider to a more accurate time on all devices.

Double Tap for Now

During the beta, one of my testers wanted to know at-a-glance what the time would be if they called now. The idea being that they already have a scheduled call group, but were wondering if they could call the group out-of-band now.

So I added a double-tap on the slider handle to jump it to the current iPhone time. Nice, but that changes the original scheduled time. So I enabled double-tap again to set it back. Now you can toggle between scheduled and now easily.

The Clock Animation

Originally, when you set the time, I just blitted the clock hands to the correct time. The clock hands would then flash-jump to the correct time. I hated that experience. Real clocks in the real world don’t operate that way and users did not see the clocks change.

So I animated the hand movement, I made the hands ‘spin’ to the correct time. The hour hand would animate to the correct hour and the minute to its. But that too was disconcerting because analog clocks are based on physical gears and the only way to move the hour hand to the right place is for the minute hand to spin all the way around. That’s the ’natural’ movement for an analog clock. So I changed the animation to act as if gears were involved and the minute hand now spins around the face for each hour moved.

But this animation happened so fast that it was still jarring. In the real world, you spin the hands quickly until you get close to the right time, then slow down to be accurate. So, to implement that experience, I animate the hands at ludicrous speed until they get close to the time, then slow it down as if it’s trying to be more accurate. And I think this experience feels right.

Delete on the Master Cell

When you hit edit on the Master View to delete a Time to Call, iOS displays a red roundel in the left of the cell to be tapped to delete the cell. This roundel pushes the content of the cell over to the right. Which means the third location graphic and my custom disclosure image get arbitrarily cut off on the right. That looks bad.

If the user then taps the roundel, iOS confirms the delete by drawing a delete button on the right of the cell, on top of everything else. Now it looks worse.

So I started to play with what to do when the delete imagery was present. First, I tried just hiding the third graphic and disclosure indicator. But that meant you saw less information when deleting, which made it harder to be sure you were deleting the right cell.

So I started to shift things around. Eventually, I came up with hiding the clock face as it has the least information when deleting, and sliding the remaining items to the left so that they can be seen by the user. That then also made sufficient space for the delete button if the user needs it.

I then animated the return of each to their correct position when the user cancels or finishes editing.

Drag to Order

The default behavior of the app is to add new times to call to the top of the list in the Master view. This is fine, but users probably want to have the most important ones first and less important ones below the fold.

The same applies to places inside a time to call. I assume the user wants the most important places in the call first (and visible on Master) and the less important ones last.

So both the master view in edit mode and the editing screen support the dragging and dropping of lines to change the order of items, which, of course, is saved.

Changing the Call From Location

What if you have a call with several destinations and would like to view it from one of the destination’s perspective?

You could edit the Time to Call, pick a new source location, and then replace one of the destination locations with your current source location. Or create a new one. Basically do it manually.

Too many steps.

So I set it up that if you just used ordering and dropped a destination on the source row, the app would swap the two, and adjust the times accordingly. Much easier and more intuitive.

And if you do it by accident, it is easy to just drop the old source back.

Using the GPS

What would be nice is if the app used your current location as the source when you create a new Time to Call. Well, iPhones and iPads have GPS so I can get the latitude and longitude from the device. And I have the latitude and longitude of each place from GeoNames. And Apple’s location libraries have a distance function for comparing the two. This should be easy, no?

Except for one thing. The GPS takes time, sometimes many many seconds to get a useable starter location to work with. You’ve seen it in the maps app where it starts with the world, then zooms in and then shows a blue dot and a big blue circle that slowly gets smaller as the GPS gets better data. See how long that takes?

I can’t have my users waiting that long for the GPS every time they launch TimeToCall.

I needed a plan B. On first launch, when the app has no GPS data, it creates a single entry to start the user off. This initial entry uses New York in English and Tokyo in Japanese. In the mean time, the GPS is working up a location and finding the nearest city. As soon as it has something good, the GPS shuts down to save battery (another detail sweated), and saves the city.

The next time the user creates a new Time to Call, the app uses this saved city as the source location, which means the user can focus on destinations and ‘playing’ with time instead.

If the user quits the app and starts it using it again later, the GPS starts hunting again, another delay. But if they create a new Time to Call before the GPS is ready, no problem, the app uses the saved location.

This GPS compromise means that the first-run Time to Call is always from New York or Tokyo, and every subsequent new Time to Call will from the users closest large city. And the assumption is made on next launch that they are still in the same general vicinity. It’s not perfect, but it works the best given the constraints.

Next: Part 7: Polishing the App.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Good and Bad Times to Call

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 5 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 4 or start at part 1 first.

Good and Bad Times to Call

The purpose of the TimeToCall application is to help the user see what time it is in a set of destinations when they call from a source location at a given time. The primary interaction with the application is then for the user to ‘play’ with time to find the best, technically optimal, time for everyone.

I wanted to make it easy for the user to understand when were ‘good’ times at each destination and when were ‘bad’ times to call.

But when is ‘good’ and ‘bad’, and how to display it intuitively? These were the next design decisions.

Defining ‘good’ and ‘bad’ times to call

I started by trying to determine ‘good’ times to call people. At first blush, standard working hours (9AM - 5PM) seem to be very ‘good’ times to call. But this window of time is too narrow, it’s only 8 hours out of 24. As a result, it’s not possible to overlap working hours with a location more than 8 hours away. I tried to expand this window by a few hours each way, but it remained too narrow.

So I went in the opposite direction, I tried to determine when is a ‘bad’ time to call? For me, it is when people are sleeping, say 10PM to 6AM. But that too is still an 8-hour window, and you still cannot to find overlaps with locations on the opposite side of the world.

So I compromised. I chose 12AM (midnight) to 6AM as the ‘bad’ time. I believe people will generally not mind staying up late for a call, but hate to have their REM sleep interrupted, or have to wake up too early for a call. And I’m old enough to still believe that the 12AM to 6AM calls are the scariest, because those are usually bad news calls.

How to present ‘good’ and ‘bad’?

OK, so ‘good’ is after 6AM until midnight. That’s settled. Now how to present it? Some of my silly ideas included:

  • Red and green traffic lights, red for ‘bad’, green for ‘good’, amber for iffy. But traffic lights are so 1980’s, hard for colorblind people to read, and are useless for VoiceOver.
  • Ticks and crosses, tick is ‘good’. Symbols are easy to recognize, but they do not tell you how ‘good’ the time is. I mean, 11AM and 11PM are both ‘good’ times to call, but we all prefer to receive 11AM calls (they are ‘better’).
  • Displaying a percentage ‘goodness’ was a silly idea, as what does 78% mean in terms of ‘goodness’ to call? Seriously though, I did take the time to calculate an Isosceles Trapezoid (or Trapezium) graph that went from 0% for ‘bad’ to 100% for ‘good’, with the 100% edge being working hours.
  • And my next doozy of an idea was using bars like your phone shows signal strength. It looked great, but again, 3 vs 4 bars means exactly what?

So back to the question of ‘good’ times to call, how do we determine ‘better’ times within that period. Well, we could say that work hours (9AM - 5PM) are best, 6AM - 9AM are not as ‘good’ hours (wake up and commuting times), 5PM - 8PM is okay (but you may interrupt dinner) and 8PM to midnight is late but doable. Great, I had unintentionally broken the day into periods.

And the light went on.

I realized that by knowing the period in the day, the user gets a better feel for the state of mind of people in that time zone. In the early morning, you can expect people to be dopey; during the day, busy; evenings socializing or late at night trying to settle down. I realized that this kind of information is great for the user of the app, and I wanted a way to show it.

And that is how I came up with the time period imagery for each time shown so you can get a feel for what is happening then. It enabled me to create, using color and art, a unique representation of each period, and to enhance it with words for non-seeing users.

The result was this, a color spectrum book-ended by night imagery, darker blue in the morning, orange sunset in the evening and bright, bright days:

  • Midnight to 6AM: Before Dawn, dark sky, stars, sleeping folks.
  • 6AM to 9AM: Breakfast, orange sun rising, coffee being brewed.
  • 9AM to 12PM: Morning, bright morning sun, blue skies, great time to call.
  • 12PM to 3PM: Lunch, brightest sun at its peak, may be interrupting lunch or siesta.
  • 3PM to 6PM: Afternoon, sun moving on, also a great time to call (so I made it a reflection of the morning image).
  • 6PM to 9PM: Dinner, reddish sun sets, people still awake, still okay to call.
  • 9PM to Midnight: Late at night, lights are on, folks chilling and getting ready for bed.

So, the design to help users to get a feel for when is a ‘good’ Time to Call while ‘playing’ with time is a combination of an easy to read clock face and bright, color shifting images. On top of that, the user can at a glance also estimate the ‘mood’ of people in each place. Lovely.

Next: Part 6: Sweating the Details.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Presenting the Clock

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 4 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 3 or start at part 1 first.

Presenting The Clock

The second biggest design decision in TimeToCall had to be the clock and its face. The application is all about ‘playing’ with time and time is intuitively associated with clocks.

And clocks are cool.

So, what kind of clock?

Yes, friends, what follows is almost 1,000 words on choosing a best way to show time for a simple, 4 view app. As if humanity has not being doing this for thousands of years!

Digital Media, Digital Clock?

Since a day is 24 hours long, and I wanted users to know when it was day or night elsewhere, I initially went with a digital clock face design. I liked the idea of big, fat LED-style numbers and a blinking colon so it looked like one of those cheap digital clocks you get in hotel rooms or on old VCR’s. I thought that 24-hour digital time would be easier to read at a glance.

But that idea died very quickly.

The first problem is that most people still talk in AM and PM. Most countries have settled on the 24-hour time for official business, you can tell because your computer will show 24 hour time for your locality (except America, Canada and Australia, they still show as 12 hour time). All military, police and other official conversations are all 24 hour time worldwide, “I arrived at the scene at 14:53.”. But most people still say “3 o’clock” instead of “fifteen hundred”. And most people still prefer to run their diaries and calendars in 12-hour time. A 24 hour digital clock is correct, but not very user friendly.

The second problem is that digital faces I started to draw looked terrible. Not the design or color, they were great, but in the app it looked like the time information was just being repeated for each destination. I am sure this is because my old eyes just struggled to see the time differences at a glance. It looked like one of those spreadsheets full of columns of numbers that we all glaze over. Not cool.

Not only that, I could not find a nice way to show the time changing when the user ‘plays’ with time. I tried flashing the time, annoying, I tried the airport departures-board style flip animation, but that was hard to follow, I even played around with a matrix-like transformation when time warped and changed. All awful. There was no feeling of movement in time.

Digital media, sure, digital time, no.

So Analog It Is

So I switched to an analog clock display. Analog clocks are good because they are simple, easy-to-interpret displays of information and given that we are all so used to the form, easy to read the time at a glance. On experimentation, it turned out that a stack of clocks with different times were easier for my old eyes to differentiate. And then I could animate the hands when time changes, which makes clocks cool.

AM/PM

But there be dragons. A day is 24 hours long, and an analog clock has only 12. Without context, how do you know when the analog clock is showing 3AM or 3PM? Think about it, normal clocks do not help, they require the viewer of the clock to be aware of their own time context in order to determine morning or night when reading a clock. I needed a solution where the user could see at a glance whether the time was AM or PM.

So I experimented there too.

Apple, in its clocks app, inverts the clock when its night time (6PM to 6AM). So I created a clock where the background was white during the day, gray in the morning and evening and dark at night. It was nice, especially when ‘playing’ with time as the backgrounds got accordingly lighter and darker. But the darker clocks were harder to read against the dark app background. And both 6AM and 6PM has the same gray. There had to be a better way.

I tried a version where a sun would rise and rotate around the face for day time and a moon for rise and fall at night, but that was confusing and garish. I tried a version where the backgrounds I use for indicating the period of the day (morning, dinnertime, etc) were placed behind the clock, but that made the hands harder to read. There had to be a better way.

So I settled on subtlety instead. I placed an AM and a PM on the face and made the active one red and the inactive one gray. Red AM, gray PM means morning, gray AM, red PM means afternoon. I found it easy to determine when the clock was showing AM or PM. And the hands never get confused and the clock faces still stand out on the screen. But how would it work out there in the real world? I tested the clock face on a few friends and they subliminally knew the AM or PM of the time without being aware of the AM/PM image switch. It worked.

I now had a design form for the clock, but I was not done. The rest of the work involved choosing the face number font, setting font sizes, drawing the major and minor tick marks, picking the color scheme and creating the clock face style. I prefer a simple clock face, so that it would be both recognizable and easy to read. Yet I also wanted classic looking numbers and classic hands that would not confuse readers. So I went with a paper textured face, tiny bezel, black minor tick marks, the same red for major tick marks, and classic hands with transparency and a shadow so you can see the minute hand behind the hour hand. And then put my name on it for fun.

I think the clock face turned out well. It is easy to read, differentiate and animate. So well that I just had to use it for the app icon.

Next: Part 5: Good and Bad Times to Call.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - the Biggest Design Decision

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 3 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Back to part 2 or start at part 1 first.

Two Views or One

The biggest design decision made in TimeToCall was whether to have a separate Edit view from the Detail view, or whether the Detail view should also be the one to edit a Time to Call.

I chose for them to be separate, but placed the time slider on the detail view. Here is is how I came to this design decision.

Edit and Detail in One View

The benefit of having a modifiable Detail view is that the user of the application can directly interact with the data as it is presented to them. From a user’s perspective, if you can see it, you can touch it and ‘play’ with it. This is the perfect touch tablet approach. Users could then rearrange places, switch the source place with any of the destination places, change the time, edit the name and do all they can interactively on a single screen.

However, the negative of this combined view approach is that it becomes too easy to change the data. Sure, it is fun, but there is no clear way (without implementing an ugly undo button which is not HIG compliant) to ensure that fat fingers or experimentation do not change a Time to Call into something unrecognizable. I don’t want users to accidentally or unintentionally change the data. Further, I assume that the user of the application is going to spend little time creating and editing Times to Call and more time just looking them up or ‘playing’ with time. I did not want users to be afraid to open up the application.

Separate Edit and Detail Views

On the other hand, the benefit of a separate Edit view is that the user has to actively declare they want to change things. I can also make the Edit view look so different that users know they are changing things, and I can put up a cancel button (which is HIG) in case they want to revert. The Detail view then becomes a “Show Me” only view, a little more boring and flatter, but it does give the user a feeling of comfort and safety when looking at a Time to Call (as well as more detail about the Time to Call).

But then the app looks and feels less cool. First-time users will try to rearrange places, hunt around for a way to add new places or change the places they see, and become frustrated when the UI does not respond. Only when they eventually find the Edit button will they realize that is where to go to change things. And that’s not optimal either.

Of course there is a third option, having a Detail view with an Edit button that transforms into edit mode and out again, just like the Contacts app on iPhone and iPad. It works well on iPhone, but unless you are using a seriously skeuomorphic design on iPad, I think it looks awful. No dice.

Choosing the ‘Right’ Design

There is no ‘right’ way to do this, different applications and different designers made different decisions. But I think it’s important for a software designer to create opinionated software, and therefore every design decision, good or bad, should at least have a reason.

Since I really wanted users to be okay with handing their iPhones or iPads over to friends and colleagues to show them Times to Call without worrying that they would accidentally change, I chose the separate Edit view in my design. I also chose to make sure it looked very different so that the user, at a glance, can tell when they are editing and when they are ‘playing’ with time.

But, if I followed this model religiously, there would be one pain point. The one thing that the application excels at is enabling the user to ‘play’ with time, to visualize when is the best time to call. But this ‘play’ would be hidden away on the Edit screen in a canonical implementation. It would be frustrating to have to edit the Time to Call each time just to find the best time. Since the whole point of the app is to enable users to ‘play’ with time, that should be the front-and-center feature, and so that belongs on the Detail view.

As a result of this decision, other opportunities arose. It enabled me to create the possibly unintuitive, but fun way to trigger the optimizer by allowing users to tap the AM or PM markers to get the optimal earliest call time and optimal latest call time. And it enabled me to create the double-tap on the slider to go to ‘now’ and double-tap to go back.

My point is that it did take me a while to make this decision as it affects the entire core code base and architecture. What really pushed me to this design decision was that the key feature, ‘playing’ with time, needed to stand out. First-time users of the app instinctively grab the slider and drag it around to see what happens, just as I, the designer, intended.

Next: Part 4: Presenting the Clock.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

Clothes Make the Man

We all know the old English proverb, “Clothes don’t make the man“, declaring that we should not judge a person by their appearance.

Yet we do continue to judge people, just these days it’s by their devices.

That person is a Apple fanboy with their walled garden white earbud iPhone and shiny MacBook Air. That person is an open-source neck-beard with their incomprehensible 1976 vintage text editor running on a cheap ChromeBook. That person is a fuddy-duddy corporate-drone Windows user dodging updates and viruses and popups while using PowerPoint for everything. And over there is the rare and exotic Blackberry holdout, spinning their nipple and clicking hopelessly on a thumb sized keyboard.

The reality is that we’re all wrong to judge. Each of the above common misperceptions is so badly wrong.

Everybody uses MacBooks and iPads now, from children to old folks to lawyers, not just creative types or mad fans. Some of the most progressive and leading-edge developers I know live on Linux, and they are serious, clean shaven, collared shirt wearing, money-making entrepreneurs. There is a whole generation out there that sees Windows as computing, are very happy and productive with it and see no need to change, and why the heck should they? And I have yet to see anyone race through emails and send messages and be more productive on mobile better than Blackberry users.

Maybe Mark Twain said it best:

Clothes make the man. Naked people have little or no influence on society.

We should go back to judging people by clothes, because devices tell us nothing.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.

TimeToCall - Building the Core

TimeToCall is a simple, universal iOS application I developed to help people choose the best time to call when calling internationally. This is part 2 in a series of posts about the thinking and work done. My goal is to share just how much effort it really does take to craft an iPhone app and ship it. I hope this series helps you to understand why it costs so much and takes so long to create beautiful software. Read part 1 first.

The Core Was Easy

Building the core code for TimeToCall was most certainly the easiest part of the whole process. The iOS libraries are spectacularly easy to work with and the architecture of the application is very simple.

In this post, I’ll give an overview of the default app that Xcode provides and the areas customized. Although this part of the series may be the most technical, I hope show that there is a lot of work that needs to be done to change the default app into something beautiful.

If I had to pull out a lesson from this, I would say that I spent too much time at the start worrying about the core and estimating that, and not in investigating the nuances and customizations required.

The Core Program

TimeToCall started life as a standard iOS “Master-Detail Application”, universal (so iPad and iPhone), ARC enabled, with StoryBoards and Core Data off. I turned Core Data off because the data model is too simple, and I turned StoryBoards off because I used them in the last project and was planning on writing this one without Xib files (think of these as visual GUI files, but they are a whole bunch more).

Without writing a single line of code, this standard iOS app gives you a Master and Detail view controller, rotation, popovers, iPhone and iPad Xibs and a simple array of objects as the data model. That’s brilliant.

So all I had to do in the core was build the flow.

The core flow consists of four views:

  • A main view controller that manages the display of the list of Times to Call
  • A detail view controller that displays the current Time to Call and allows you to ‘play' with time or run the optimizer
  • A view controller for editing the Time to Call, and
  • A view controller for picking places.

To support the views, I created the original model code:

  • A class to represent a CallZone (name, source location, time and list of destinations)
  • A class to store and search the timezones for the picker
  • Some code to load and save the array of CallZones
  • Some code to display the time shifts for each destination

That’s all there is to the core of the application. I developed the views using standard iOS components in a few hours, and the model code took a few hours more. By the third day of part-time development, I had a working app.

Making it Pretty

But the default iOS look and feel does not cut it these days. People expect colors and fonts and animations and shapes and images. Default apps look old and boring. Kinda funny considering that iOS is only 5 years old.

So, I needed more classes to customize the presentation of the data:

  • A Custom Table View Cell for Master to display each CallZone and some of their times
  • A Custom Table View Cell for Detail to display each destination’s time
  • A Custom view to present the clock

Each of these has an iPhone and an iPad version. But I got smart and reused the same View Controller code, so I felt I was ahead.

These custom view classes are hard to design and easy to code. How to present the data? How to make it cool? How to make understandable? That used up a lot of hours and I’ll go into the thinking behind these in later parts of this series.

So, surely I was done. The core was written, the app ran and looked reasonable.

Not So Fast

It was not all smooth sailing, easy peasy or whatever the best phrase is for nothing going wrong. Even the simplest applications have hidden complexities. The place data was awful, the time conversion code was a mess and I had so much code copied and pasted throughout the core that it was difficult to make changes across only four simple views.

Lets look at each in detail and the lessons learned:

Never Make Assumptions

When I kicked off the project, I assumed that the city names I needed would all appear in the standard Unix timezone database, because “how else does Apple handle the city to timezone mapping on iOS” in setup. I even loaded the database into BBEdit and searched for a bunch of major cities and they all came up. So I wrote the core around this data set.

How wrong was I.

There are only 411 entries in the TimeZone database, but a lot more major cities.

I had forgotten to follow my own rule: Never make assumptions.

I needed a database of places that we humans think of with a mapping to timezones that the product can use. Fortunately, it exists, and it did not delay development to get it. I downloaded the GeoNames database, and created a script to pull out all cities where the population is over a certain size. With a little experimentation, I settled on 100,000 population and used that as the place model data (4,184 places). Just to be sure, I then checked that each of these cities had timezones that existed in the timezone database so that the mapping would work.

Standardizing the Data Model

TimeToCall’s computation is quite simple, it takes a time in a given timezone and displays the same time in other timezones and calculates earlier or later for optimization. To make it even easier, the iOS libraries have NSCalendar, NSDateFormatter, NSTimeZone, NSDateComponents and NSDate classes that can be combined to do this conversion and presentation.

Or not.

Because the NSDate is immutable, you can create it, and use NSDateFormatter to present it, but you cannot change it. Which means you cannot just change the NSTimeZone on an NSDate to see the new time. Thats okay, you can use a different NSTimeZone in a NSDateFormatter to present the new time. But that produces strings, and I also needed numerics to determine earlier or later.

Skipping the boring details, I found that I was writing a lot of code that switched the user’s call time between timezones to calculate offsets. In essence, I had a timezone and an NSDate in too many places, in the source timezone (calling from), in the NSDate object that stores the call time and in each timezones that you are calling to. I wrote a lot of code to ensure that the NSDate timezone in the main object used the right timezone, and the calculated NSDates for display used the appropriate ones for each call-to, and used these for offsets.

Too many conversions, too many opportunities for things to go wrong. And they did.

So I simplified it by making the internal NSDate object’s timezone null (or GMT). Which meant that I would only ever have to do a single conversion, GMT to timezone, or back to GMT for computation, which happens to be available through NSDate . It means that the optimizer and the debugger log GMT times when debugging, but the code is a lot smaller, slimmer and less failure prone.

Pulling Out the Model

The primary object on the system is a CallZone, consisting of a user supplied name, source place, call time, and a list of destination places. All else is calculated on the fly. I save and load an array of these into a standard .plist file in the app. A very simple data model.

The default iOS application’s model is an array of generic objects, and this is instantiated in the Master view controller (where you see the list of CallZones). The older version of the default iOS application had this in the Application Delegate, a class that kicks in when the app launches and quits. Both approaches work, but require you to pass this array between all controllers as you need them, and to have access to the ‘owning' controller to trigger saves (or use NSNotificationCenter).

So is the Master View the model? Or is the Application Delegate the model? Since the 1970’s, we software types have been following Trygve Reenskaug’s famous Model-View-Controller design pattern, yet the default iOS app seems to break this.

I prefer the right approach, to separate the model from the controllers and to use objects, not collections of native types for data. A True Model-View-Controller architecture. So I moved the array of CallZone objects and the load and save operation to a NOVApplicationData singleton class. I chose the singleton pattern for this as there can be only one set of data in this app, singletons are easy to access from anywhere and I do not have to pass the model around all the view controllers, they can all call up the singleton. And most importantly, I have a separate class for the model data and its operations.

Refactoring Duplicated Code

If you look at the app, you’ll see that both the Master and Detail views present data for a CallZone. They both display the clock, they both display the adjusted times, and they both display the images for the day period (morning, night). I had not created custom views for each because the layout of each was different. But I did have the same code in both of these views to determine what to display. Which meant, as I was iterating, that I would always have to change code in two places.

For a simple app like TimeToCall, that’s not really a problem. For a more complex app, duplicated code becomes a maintenance and iterative nightmare and actually increases to time to develop it. You have to remember to make the same change all over the place.

So I created another class to help with the presentation of a CallZone, with tools for displaying the time, managing the clock face, and displaying the image and time of day for each destination. This helper class is used by all tableview cells. With this modularized code, I can use the same class to help display the CallZone consistently without having to duplicate code in views. It also meant I could iterate on the customization a lot faster and get the product completed a lot quicker too.

Next: Part 3: The Biggest Design Decision.


 
TimeToCall can be downloaded from the App Store for 99c.

I hope you enjoy this series of articles on what goes in to the design and development of an iPhone or iPad application, and have a better feel for why these things take so much time and cost so much. If you like them, buy TimeToCall from the App Store, it helps me continue to write, and please tell your friends about these articles and this product.

Follow the author as @hiltmon on Twitter or @hiltmon on App.Net.