Next TTC follow-up + TACOW Meet-up tomorrow

It’s been a long day and I think I’ll *just* make the deadline for my #idevblogaday post. This morning, Toronto Transit Commission (TTC) released the much anticipated bus data for their Next Vehicle Arrival Service (NVAS), which previously only included streetcar arrival time predictions. Read more about the app my previous Next TTC: Behind the Scenes.

In anticipation of the release of the bus data, I had done some updates for my app, including hosting some of the data on my own server for speedier transfer, etc. However, with a jump from 300KB to nearly 4MB of data for the initial config XML file, I have some work ahead of me to improve the app and it’s handling of the data. Furthermore, some of the bus routes also have a bit of different configurations, in terms of their route format (some routes have a/b/c/etc. directions/destination for the same route), so I have to change the parsing up a bit to properly display this to users on those routes. I also have to change the way I store data and access it on the fly, so lots of work ahead of me this week! I need more time in the day!

But, apart from the slowness of the app (until I finish the update), it’s been pretty good today. I was able to update to include the new data this morning, which meant I got some good press today.

I was mentioned in National Post, CP24, CityTV, and finally interviewed for a great article in Globe and Mail which was posted tonight (hopefully making it to press for tomorrow’s paper!). I’m really happy about these mentioned. As far as I could see from my app’s ranking (went from ~#30 in Navigation to #2 in that category, and made it into Top 100 overall – both for the Canadian App Store of course, which is quite different from the US Store, in downloads) sales have been pretty good today, but most exciting is all the awesome feedback I have been getting from users who are ecstatic about finally being able to use the app for their bus commute (and night buses and streetcar, not previously included).

All in all, today’s made me pretty excited about my app again. You always end up getting a bit tired with a project after staring at the code for a long time, or literally using every aspect of your app possible, or painstakingly tweaking every little pixel of the UI if you’re me. I have a bunch of ideas on the table that I want to do after fixing what needs to be fixed. And I can honestly say, it’s made it a bit more interesting now there’s finally a larger user-base to cater to – and more copies to be sold.

Finally, if you’re in Toronto and free tomorrow night, I am presenting at tomorrow’s TACOW (Toronto Area Cocoa and WebObjects developers group) meet-up. I’m doing a presentation on Core Location, how-to-use-it-basics plus some insight/tips and experiences from myself using it. Should be fun! The details for the meet-up is on the website, and we’ll be heading out to a pub afterwards for some drinks.

 

Next TTC: Behind the scenes

Last week, I released Next TTC 2.0, a major update to my real-time arrival predictions utility app for Toronto’s streetcars (buses to be added by Toronto Transit Commission (TTC) soon).

Today, I’d like to discuss how I went about dealing with the data that is provided through the API and which UI/UX choices I made based on the data and how it would be used.

Bit of background

Data is provided for Toronto’s public streetcar transportation system through the nextbus.com API. Basically vehicles are outfitted with a GPS. Based on their location and proximity to a certain stop, the API provides arrival time predictions. So for example, if a streetcar is 1.2 km away from a XYZ stop, based on the average speed and time it takes from the streetcar to arrive at XYZ it will tell you that the streetcar is arriving in 4 minutes and 43 seconds. This can however change if the streetcar is backed up in traffic or suddenly able to travel at faster speeds, or make less stops en route to stop XYZ.

The data

TTC provides up to 5 arrival time predictions for the requested stop and/or route.

By requesting data for a stop only, you’re provided with all routes and their arrival times for that particular stop. Depending on the stop, this may be one or several routes at once. You’re also able to request stop and a specific route, which means the API just returns arrival time predictions for that route.

Furthermore, for TTC, some streetcars make short-turns. For example, route 501 westbound has two end destinations. The streetcars are on the same track for most of the way, but every few streetcars will stop at an earlier station. This means the API also returns predictions for each route-short-turn.

The data may appear as such:

  • Route 0
    • Destination 0
      • Prediction 0
      • Prediction 1
      • Prediction 2
      • Prediction 3
      • Prediction 4
  • Route 1
    • Destination 0
      • Prediction 0
      • Prediction 1
      • Prediction 2
      • Prediction 3
    • Destination 1
      • Prediction 0
      • Prediction 1
  • Route 2
    • Destination 0

In the above example we have requested data for a stop. This stop is serviced by 3 streetcar routes. Route 0 is currently in service and we are returned 5 arrival time predictions. Route 1 is also in service and has two destinations (or short-turns) for which we are returned results for both. Route 2 is currently not in service (some streetcar routes only run during rush hour) and we are not returned any arrival time predictions.

So as you can see, we are potentially dealing with a great deal of data.

Scope

Version 1 of the API provided less amount of data and details, so in Next TTC 2.0 I wanted to upgrade as well, while still retaining the basic user experience of the app.

The basic scope of the app is to launch the app and instantly get arrival time predictions for the stop nearest your current location. In essence this is pretty easy with Core Location. Once you have a user’s location, loop through all stops to find the nearest stop and request the data for that stop.

But how do you retain a simple user experience as required by the scope when you’re dealing with potentially lots of varied data?

UI/UX decisions

In Next TTC 1.x, if a stop had more than one route, I prompted the user to select the desired route – or telling them Route X and Route Y service this stop but only Route Y is currently running. While it was the only app allowing the user to view other routes at the same stop it was intrusive and quite annoying.

Alert prompt in Next TTC 1.x to select route for stop at user's current location

With version 2 of the API returning multiple destinations (short-turns) for one route there was more data to present.

My goal was to present all the data possible without any interruptions, while also making it extremely easy and quick to change between the desired data. So in 2.x I added the trust navigation bar (I also went from not having the status bar visible, to making it visible, so the user could see the current time), which allowed me to added a UISegmentedControl to quickly switch between routes for the stop at the user’s current location.

Next TTC 2.0 provides as easy way to switch between routes servicing the same stop in the navigation bar as well as switching between a route's short-turns

With a checkmark, I also visualize whether a route is running. While the returned data is a bit scrambled, I chose to sort the segments in an ascending order. Furthermore, the selection defaults to the first route in the segmented control that is in service, so the user isn’t initially presented with an empty result for a route they most likely wouldn’t care about, since they want to know when the next vehicle is arriving at their current location.

In the screenshot, you can also see another row of segments: All, Long Brand and Humber. These are the short-turns. As we saw earlier, the API would have returned two destination. I then present these two selections above the route button along with a combined set of predictions for both the short-turns sorted in an ascending order. In this case, 501 Queen is a long route, going from east of Toronto to west of Toronto. Both destination short-turns are quite far out of downtown, so if you’re going to a stop way before that, you wouldn’t care which one of the upcoming streetcars you can take, because you know you’re getting off before that. At the same time, if you’re going to Long Branch station, selecting Long Branch will provide you with upcoming arrival time predictions for that location, which could save you lots of time waiting or getting on the wrong streetcar (Long Branch is further than Humber. Unfortunately the API doesn’t sort the destination short-turns in order of proximity, so it’s not possible to present them in a sorted order at this time).

Example of a stop serviced by up to 5 different streetcar routes

While it’s recommended in the API documentation not to show seconds, I felt it was appropriate to show it because “1 minute” may be 1 minute and 20 seconds or less than a minute. If you’re running to catch a streetcar, 30 seconds precision matters a lot. Luckily, lots of users love this feature over other apps that provide the same basic use-case. I only show it for the upcoming streetcar, while the subsequent cars are displayed in minutes. The app auto-updates the predictions based on calculations for the count down time, so the user is always shown the most accurate prediction at any given time. It feels kind of awesome standing at a stop looking up from your iPhone running Next TTC and seeing the streetcar arrive exactly as predicted in the app :)

Core Location

Anyone who’s ever had to work with Core Location probably agrees with me when I say it’s a bitch. While the API is great, it was a challenge to find a balance between very accurate location results and also being able to locate the user when location accuracy is very low (no GPS for example). With Next TTC, I wanted to be able to locate the user quite precisely and quite quickly to find the nearest stop, and not find a stop 500 meters away or more.

All devices cache the user’s location and when initially prompting for a user’s location that’s exactly what you get back. It might be an extremely accurate location, but it may also be very old and inaccurate. If you’ve ever opened the Maps app, and seen the blue dot move over a large area before locating you, or having the circle around it cover a very large area, this is exactly what I am talking about.

So in dealing with this challenge, I initially did a whole bunch of stuff in code to try and figure out whether the location was usable, whether to continue trying to find a new, better location, etc. It turned out quite difficult so in Next TTC 2.0 I went back to the basics, but made it possible for the user to quickly re-locate themselves and request new arrival time predictions for their updated location. In Next TTC 1.x I had a GPS arrow button, but it turns out, even though Apple uses this, most users don’t understand the icon. Since I had worked so much on getting a good location initially (which sometimes took several seconds; way too long) I didn’t really make it possible to re-locate oneself, other than picking another stop manually and then hitting the GPS arrow button again. Poor UX, Rune!

Main screen in Next TTC 1.x using user's current location (GPS arrow)

So as dicussed, in Next TTC 2.0 I got rid of lots of code for my Core Location class, and implemented a much easier way to get an updated (and more accurate location if available) if the initial location wasn’t satisfactory. I implemented the pull-to-refresh paradigm, which works wonderfully for my app.

Example of my custom "pull-to-re-locate" implementation of Pull-to-refresh seen in lots of apps

Clutter or not?

When dragging the bottom view down, it reveals a button to add a stop to favourites. When this button is hidden, I added a small light that allows the user to quickly see whether it’s a favourite (light is on) or not (no light), without having added yet another button that takes up a bunch of screen real estate and doesn’t get used 90% of the time if that much!

Extra hidden menu bar reveals "Add favourite" button

The great thing about this extra menu bar is that I can add features/buttons in the future without cluttering up the UI more, leaving the user to focus on the most important thing to them: “When’s the next streetcar arriving at this stop?”

I did add a button in the centre of the toolbar, to open/close the hidden menu. Based on beta tester feedback, it wasn’t obvious enough that dragging/pulling down on the picker view would reveal the extra menu bar.

Next TTC 2.0 has the same grey noise background as Next TTC 1.x as well as light letters. When I released the app back in February it was winter and the sun wasn’t shining very much. As the months passed and spring arrived, I started receiving feedback from users that the UI was too dark and very hard to discern in bright sunlight. Sure enough, I tested it and the only thing I saw on my iPhone screen was my own face reflected on the glass screen.

Based on this feedback, I added a “Dark on Light UI” setting in the app, which changes the background to a noisy off-white with dark text, making it much easier to read in direct summer sunlight.

While not as pretty as the default setting, the "Dark on Light UI" setting makes it possible for Next TTC users to easily read the content on the screen in bright sunlight

Wrapping up

I hope you’ve enjoyed a bit of insight into the choices that went into the user experience and design of Next TTC 2.0. Here’s a few points to wrap up what I think you should take away from it:

  • While you may have a UI in mind early on, UI and UX design is closely related to the data you need to present. While considering your UI, really dig through your data and decide early on what’s important and what parts of the data you want to present to the user, or what takes precedence.
  • Create a scope early on. This will help you on your path to completing the app and provide clear guidelines for designing and coding your app, since you’ll have the data and the user in mind.
  • Revise, revise, revise. Don’t settle on a particular design just because it looks great. If it doesn’t work well in terms of usability or if it doesn’t allow you to present the data or the user to interact with the data in an appropriate manner, scrap it and figure out a better way of making this possible.
  • Don’t be afraid to make big changes. Next TTC 2.0 was a huge update for me. I completely rewrote the core of the app and redesigned 80% of the app. I consider it a brand new app (which also made it painful in deciding it’s a free update to the thousands of current users who’d this awesome update for free, only having paid a dollar for the previous version).
  • Listen to tester and user feedback and make appropriate changes to your app. Something might appear important to you, or easy to use from a UX point of view, but if several users tell you it’s not, listen to them.

WWDC in Pictures

What a week. Yesterday I returned from a fantastic week in San Francisco attending WWDC and related parties and events. I met some incredibly talented, incredibly interesting and incredibly fun people throughout the week from all over the world. While it’s stressful and tiring, I wish I had more time to meet even more awesome people. Thanks to everyone who were part of making my second WWDC attendance a blast!

Days have been packed full of amazing and interesting sessions and evenings running to dinner, parties and bar hopping. For this reason, I haven’t managed to prepare anything great for this week’s #idevblogaday post. But I took some pictures throughout the WWDC week, so I thought it would be fun to make a small “WWDC in Pictures” post. The photos are all taken with my phone, so don’t expect amazing shots. But I’ve tried to include various shots of things you don’t necessarily see in the press for example.

Enjoy.

Sunday registration

Snack tables were always a big hit. Probably the only thing at WWDC without line-ups, surprisingly!

Typical line-ups for a session. And I was in the front of the line. In the background is another line-up coming towards us.

View going up an escalator of one of the many WWDC banners

Always busy and buzzing in the lobby of Moscone

Line-up for one of the more popular sessions in Presidio

Waiting for a session to begin

Drinks at The Chieftain. Loren Brichter is in this shot.

T-shirts were a big thing this year. Here's an awesome one I got from Mike Piontek (@robotspacer)

TestFlightApp.com's t-shirt. If you wore one in the Keynote line-up you got free breakfast. Awesome marketing.

Great line on the WWDC Bash wristband

Random WWDC Bash photo. Lots of food and drinks!

As Michael Franti & The Spearhead entered the stage everyone was like "Who?". I personally hadn't heard of them but enjoyed the music way more than OK GO. Rock just doesn't do well live if you don't know the songs.

I love this guy. Seriously. He's my hero.

Beach balls!!!

Everybody enjoying the Bash

Line-up for the men's wash room. Worse line of the week - I had had four beers at that point. They even started letting guys into the women's wash room.

Waiting for Wednesday's lunch presentation to start.

Buzz Aldrin's presentation was followed by a Q&A. Notice the patriotic lighting.

Stump the Expert is always a blast.

My last WWDC beer Friday evening at Jillian's watching Canucks beats Bruins with my new German friends from iosphere GmbH. What a week.

Introducing GiftKit – gifting made easy

I love Appirater and enjoy how simple and easy the process of letting users easily review apps in the App Store.

In a previous #idevblogaday post, I wrote about how to get your users to spread the word and their love for your app in a post entitled Assisted word of mouth: Get users to sell your app.

In this post, I wrote about App Store Gifting and how awesome it actually is. To recap: You’ve already sold your app, the user loves it and wants to share his/her love for it. Gifting is a great way to share the app, and once a user has spent $X.XX, they’re usually more apt to want to Gift your app to a friend or someone in their family. Read the post for more insight.

While Gifting was just one of the ideas I included in my post, Gifting really seemed to be the key idea that most people loved and many wanted to include in their apps.

So, today I am releasing GiftKit. It’s basically Appirater, but for gifting.

GiftKit is a small utility class that allows you to prompt your users to Gift the app via the App Store, spreading the love to their friends and family.

Simply add GiftKit to your iOS project and call one of the various methods to increment uses and launches and eventually prompt the user to Gift your app via the App Store.

Simply add GiftKit to your project and call one of the methods provided. Change days/uses/alert text in GiftKit.h to suit your needs.

Optionally, add a Gift this app to allow the user to Gift more times in the same version – or without having to wait for the prompt! Call [GiftKit giftApp] to jump directly to your App’s App Store page.

By default 5 days must have passed before the alert appears. Furthermore, either 15 uses and 25 significant events must occur before the alert appears.

Add -1 to significant events in the header file if you only care about the launch method calls.

Here’s a screenshot of the UIAlertView in action:

Clone the repo here: https://github.com/runmad/GiftKit

Be sure to check for updates, as I might try and improve it a bit later. If you have any ideas feel free to comment or help out on Github :)

Follow me on Twitter: @runmad and be sure to say “hi” at WWDC next week if you’re there!

ColorKit: A Color Assessment Utility App

For this week’s #idevblogaday post, I’ve written a small utility app that’s freely available for download on github.

ColorKit is a tiny iOS app (iPhone) which allows for quick and easy color-sampling for a UINavigationBar + UIToolBar. It allows developer to easily assess the appearance of tintColor on the device.

Last week, I talked about adding textures and depth in your app, in particular to a UINavigationBar. While this effect is great when used appropriately, UINavigationBar’s tintColor property is extremely handy and useful to give your app a unique look with one line of code.

Finding the right colour for your app can be a bit of a hassle, especially due to differences in colour appearance depending on which monitor or device you’re using. Furthermore, UINavigationBar and UIToolbar are coloured with a gradient and has a glossy shine, so knowing exactly which RGB value to use is often impossible.

ColorKit builds and runs right on your iPhone and makes it extremely easy to quickly play around with various RGB settings to find the perfect colour for your app.

Inside the app is a UIImageView which allows you to add a screenshot from your app to better see how the colours may look with your UI.

You can download a copy of the code here: https://github.com/runmad/ColorKit

Pro-tip: Do not use bright colours. Play around with the values to create more “faded” colour. Brighter colour wash out the title text and generally look horrible.

Faking depth and textures in your app

I just returned from vacation, so this won’t be a huge blog post. I’m making a pretty sweet offer at the bottom of the post, so be sure to check it out at the bottom!

In this post I will address how you can use simple techniques to create a sense of depth on a flat touch screen device and a “visual tactility” to your app – and without going completely overboard with textures. While I like to create unique examples, I’ll be using examples from existing apps and talk about what effects are used, what’s good about them and why you should stay away from some of them.

What’s too much?

You might be familiar with the Game Center app. While the design is great and I can appreciate they were going for a pool table-look or poker-table look with wood grain navigation and tab bar, and a green fabric background, but I personally think it’s all too much.

Gloss on top of wood (navigation and tab bar) just doesn’t work, and it really makes it look more fake than real. The horrible font and it’s weird shadow are also not working. And the shadow is depressed into the background as well? Weird. Furthermore, notice how some items in the main view are raised from the background, while others appear to be depressed into the green background. And why is there a shadow coming from the navigation bar only and not the tab bar? The navigation bar is raised from the background, yet the identical looking (texture-wise) tab bar is on the same plane as the background.

Needless to say, this is a great example of what’s too much.

Textures that work

Groceries is a great app from Sophia Teutschler. Here’s a screenshot taken from the App Store page for Groceries:

Notice how this app uses lots of textures, yet they make the app more appealing, and when you view it on your iPhone it really looks and feels great. Groceries also uses a wood grain texture for the navigation bar and tool bar. The background (more visible on first launch of the app) is a cork board texture, which matches the two bars. The table resembles a piece of note paper stuck to the board, with the top edges torn and casting a soft shadow on the background.

Now, while both Game Center and Groceries share some major similarities, why does it work for Groceries and not for Game Center? As I mentioned earlier, gloss on wood doesn’t work. In Groceries, Sophia uses a soft white-to-transparent gradient that helps fake a soft light from the top, making the bars seem 3-dimensional. The colours of the text match in the bars the wood grain much better compared to the Game Center app. Both the navigation bar and tool bar cast a soft shadow on the background and paper creating a nice depth in the UI.

Groceries is a great example of how extensive, yet careful use of textures in your app’s UI can compliment your app’s content and not desperately steal away attention from it like in Game Center.

Shadows create depth

Using shadows, you can easily create a 3-dimensional effect. As seen above, you can protrude and depress views when using shadow effects on views and texts.
For UILabel, see the properties shadowOffset and shadowColor. I suggest you use these for most text in your app. As a general note, do not use it with longer text, such as in a UITextView or where not approrpriate, such as in a UITextField. I briefly talked about how to appropriately use colours and offset in this post: http://runmad.com/blog/2010/11/random-tips/ (Tip #4). Have a look at the above screenshots and see how shadowOffset is used.

Some points from this post:

  • Don’t go crazy with textures. Subtle is key and more is never the answer!
  • Use textures and colours that compliment each other.
  • While you want to go for real-world look and feel, creating completely “realistic” interfaces often never works. It’s all about finding an in-between state, where it’s appropriate for a non-tactile, touch screen device, yet still has a 3-dimensional depth to it.
  • Shadows create depth in your UI

For further reading, Mike Rundle posted a nice post, Crafting Subtle & Realistic User Interfaces, where he talks about gradients more in depth as well as tips for using materials in your UI design.

Assisted word of mouth: Get users to sell your app

You can spend lots of money and time advertising and promoting your app. Advertising your app through social network sites and Admob and the like is pretty well the most wasteful and ineffective way of spending your money, in my opinion.

Spend your money and efforts in developing an amazing and great-looking app that will naturally attract users to your app. Spend the money on hiring a graphic designer or other efforts that goes directly towards making your app better.

Most users find out about your app from friends

In this post, I will detail another great addition you can add to your app, which will help sell more copies, let’s call it: “Assisted word of mouth.”

While everyone strives to reach top App Store ranks and have their app featured on various lists, only a select number of apps reach the top rankings, and mostly only for a somewhat short period of time. The top ranks and featured lists are a great way of attracting new users, but these spots are mostly occupied by the same apps week after week.

Consider how often you have heard “Check out this app I just got!” or “Can I check out what apps are on your iPhone?”… That’s right, lots and lots of iOS users hear about apps from their friends, a reliable source they can rely on for input about the latest and greatest apps. A lot of users also get a kick out of being one of the first users of an app, or the one to discover a new great app. “Check out this app, I have discovered.”

Let’s assume your app is great, your users simply love it and you could potentially sell a lot more, if only more people knew about it.

Gifting

I suggest that you include an easy way for your users to to share the app and their experiences with the app via email, SMS, Twitter, Facebook and most importantly through gifting.

I have a feeling lots of App Store customers do not know about the gifting feature. Imagine if you’ve already convinced one person that your app is awesome, they’ll actually purchase your app again and give it to their friend/family. You’ve just saved yourself having to try and get that person’s attention and convince them why they should buy your – their friend and your current user just did!

While this isn’t factual, I actually think users find it much easier spending another $1.99 (or whatever your app costs) to give a great app to a friend, over buying the app without knowing anything about it. Once the user is hooked and love your app and want to share the experience with their friends, they’re more prone to purchase to app again for a friend.

Sharing options

Following in the footsteps of my previous #idevblogaday post, App support: What’s it worth?, I suggest that you place a simple link in your settings view, or perhaps on your main screen if your app is a game, calling it “Share [APP NAME] with a friend” or just “Share App” if you’re using a smaller button.

When tapping the button, bring up a UIActionSheet with your sharing options. In this example, I am not including Facebook, but add it if you want to. Note: Be sure only to display those options available on the device (so no “Email” option if the device doesn’t have an email account setup, and no “Text Message” option if the device does not support text messaging).

Custom, direct-to-App-Store URL

Create a custom bit.ly (or other) to your app, so it’s easily read and remembered. For example, I created http://bit.ly/NextTTC for my app Next TTC.

Make this link directly to the App Store, not your website. You can only assume that a user will share the link with someone they already know have an iOS device, getting them one step closer to a purchase when they don’t have to visit your website, however great it may be. When they open the link on their iOS device or desktop, it will automatically open the App Store (or iTunes preview site if iTunes isn’t installed).

Use the link in all the sharing options even use it for the gifting option, since it allows you to track clicks. Or use in-app analytics, or create several custom URL links for each option if you want to see stats for each.

Use a short and catchy tagline to use in text messages and Twitter, so it fits within a tweet and text. The users can add/erase text if they want. I use the following: “Get instant, location-based TTC streetcar arrival predictions with Next TTC for iPhone http://bit.ly/NextTTC”.

For the email sharing option, consider creating a nice template instead of just “Hey check out this app {link}”. Mike Piontek (@robotspacer) from June Cloud uses a beautiful template when sharing deliveries (and it’s also a great way to share a link to his app) in his app Delivery Status. MFMailComposeViewController takes HTML and CSS, so you can get pretty creative.

For Twitter either use have the user select their preferred app, or just link to Twitter (twitter://post?message=TEXT) or another app like Tweetbot (tweetbot://screenname/post/TEXT) or just the Twitter website (http://twitter.com/?status=TEXT).

Lastly, the gifting option. As I mentioned earlier, this feature is somewhat unknown to lots iOS users, so if the user selects this option, a brief description in a UIAlertView is probably a good idea.

Once all this is done, you should be all setup and hopefully see some additional sales without a lot of additional effort!

A few points from this post:

  • Traditional marketing and advertising efforts can be expensive and exhaustive
  • Word of mouth is the most effective advertising you can find!
  • Give the user several options/ways to share a link with their friends: Twitter, Text Message, Email, Facebook and App Store Gifting
  • Use a custom URL which links directly to the App Store, so you don’t create an extra step to your website where you potentially loose their interest
  • Consider tracking effectiveness of each option. If gifting is pretty effective, maybe place it in its own option right on your About/Main/Settings screen
  • If you got the time and skill, create a nice email template
  • For the gifting option, briefly explain to the user what will happen and what steps are required to gift your app, since gifting isn’t a widely known feature of the App Store

Hope you enjoyed this post! By the way, I’ll be at WWDC again. If you’ll be there too let me know. Follow me on Twitter (@runmad) and let’s meet up!

App support: What’s it worth?

Hello again! I previously wrote a number of entries for #idevblogday last year and am happy to be back (especially with the new bi-weekly format). Since I last posted I’ve released a new app, Next TTC, a location-based arrival prediction app for Toronto’s streetcars (soon buses). Check it out if you live in Toronto and ride the TTC :)

In this post, I’ll be talking about customer support/service and what it may mean to you, your customers and your sales. I had been drawing blanks for a subject, so it’s based on a suggestion after discussing this with a friend. Skip to the end if you’re pressed for time for a important-points-summary of today’s post.

In-App Support Emailer
I always add an in-app email feature to my apps, where my customers can easily and painlessly email me on a support email address I have set up for this purpose. When the user taps the feedback/support button, I display the following alert:

This generally help establish a purpose and set some general expectations for the feature. I also take the chance the automatically add some variables that may be of use if I need to debug a problem the user has, saving me and the user time emailing back and forth to establish which device the have, what version of the app and OS they run, etc.

While this feature is great for all apps, you may want to leave it out in a free app, depending on it’s features or purpose. If you have IAP, go for it, but if the app makes you no money whatsoever, perhaps reconsider adding the in-app emailer – because you will have to do some support work!

The reason for this is that you will get more emails than if you made it harder for the user to contact you (via support link in the iTunes App Store, etc.). However, in my experience, they’re often just short emails, asking for a specific feature, asking for help on something, and it often takes me very little time to answer them. Most of the time, I am able to copy a previously sent answer, since a user may have had the exact same question or issue. For example, in my app Next TTC, I’ve had more than 20 customers email and ask me why they cannot get arrival predictions for the streetcars that run at night. While this is stated in the App Store description, it is perhaps annoying to answer the same question over and over, but it’s easy if you can copy previously used answers, and I’ve had a lot of great feedback from customers who are genuinely happy about my prompt replies, even if it wasn’t exactly what they were hoping for (unfortunately data isn’t provided for the nightly streetcars at this time, if you were wondering).

In-App FAQ/Help article
Another quite helpful and fairly painless feature to add to an app is an “FAQ” or “Help” section. I won’t discuss the technical part of integrating this, but a solution could be local plist (or server-side) or through a UIWebView using jQTouch to make it look somewhat native.

While an FAQ or Help section is great and useful for anyone in the beginning, my suggestion is to not spend a lot of time on this feature (or the content) until you actually have an idea of the most frequently asked questions. If you combine it with the above in-app support email feature, you will quickly get an idea of what your users ask the most from the emails you receive.

This way you won’t be spending time on FAQ content that nobody will read anyway. I’ve seen apps with help sections that explain the most basic parts of the apps UI, such as how to go back in a UINavigationController stack (obviously without the technical terms), and other completely standard things that almost all iOS apps that use UIKit have. Even if you’re using custom UI or gesture-based UI interactions, consider whether it’s completely necessary to spend your time writing all that content. Besides, your UI and interaction with it should be intuitive and require no explanation at all, but come naturally at least after a few uses ;)

Once you have an idea of the most asked questions, comments, etc. through the in-app support email feature, put together some articles that your customers can read. If you still receive emails about a questions answered in an FAQ article, simply refer to the article in your app in a friendly manner and let them know they can email you back if they still have any questions or concerns.

Games should usually include a tutorial or guide, which does the job of Help articles. You can always add an in-app support emailer or help articles as well, of course.

How much support does $0.99 buy a customer?
Well, technically you only get 70 cents. Or 70% of however much your app costs.

It’s up to you to decide how much support you want to provide for your customers. If you’re finding you’re receiving a lot of emails regarding bugs or issues with your app, you’re definitely doing something wrong and you need to address the issue with your app. If your UI or a feature isn’t self-explanatory and easy to use and confuses your customers more than it helps them, remove it or change it.

In my experience, answering support emails can be done fairly quickly (for most devs, unless you have a best-selling app with huge amount of users). I usually take a small portion out of my day and answer all emails (if any, I may add) quickly and painlessly. If I only get one a day or so, I’ll just do it whenever I get a chance, on the streetcar, on the couch or during my lunch.

Be careful answering your support emails from your iPhone. Depending on the length and answer, answering it on your iPhone really does show in your language. Sitting down at your computer to type out a proper answer is always a better idea, and it also makes it possible to use signatures as a quick way to answer a frequently asked question.

What does great customer support buy you?
While support requires a bit of work on your behalf, one might wonder if it’s worth it. Basically you’re offering free support to customers who have already paid for your app. Your time spent developing the app is already more than what $0.99 should buy and I think many will agree.

From personal experience, a number of my support communication emails have lead to some great word of mouth and some great reviews from highly satisfied customers. I have even had customers where I have simply not been able to help them (it’s been an issue with the data, their device specifically or something else completely out of my hands), but because I have been honest, friendly and prompt, my customers have responded extremely positively and are generally always happy with my support, regardless of whether I was able to solve the issue immediately, or bring them good news about upcoming features.

I’ve also taken the opportunity a few times to tell the user they’re more than welcome to add a quick rating/review in the App Store. You’ll have to judge the situation and please don’t add it in your first response. If you’ve been emailing back and forth and the customer seems happy, go ahead and ask. Otherwise let the user judge and review/rate if they find it’s worth it.

A few points from this post:

  • You might be a developer, but you’re also expected to provide some level of support.
  • Remember, these people (usually) paid for your app. Regardless of the cost, you have their money and they deserve some support – especially if your app isn’t working as expected.
  • Don’t get cocky or disrespectful, no matter what the customer writes. If their email is hurtful and you cannot say anything nice, don’t reply. It’s not worth it, and you’ll piss them off even more and waste your time (the user can threat you with a bad reviews, or get upset and just do it anyway). I know you’ve spend weeks if not months and many long nights coding your app, but do not take it personally. Unfortunately the most happy customers and users are usually the least vocal majority. Move on and focus on all the positive things people are saying about your app!
  • Add an easy way for your customers to contact your for support within the app, and remember to add anything to the email body that may be useful for your debugging (without being intrusive and adding sensitive user data).
  • Based on FAQ through your in-app support emailer, add a FAQ/Help section.
  • Take your time to reply back to your support emails. Preferably use a computer (or an iPad with a bigger screen), because it may show in your writing style if you reply on your iPhone. Don’t let support emails sit for days. The longer you wait, the more time you give that user to submit a negative review as a way to report the bug, and they may not remove it even if you reply and resolve their issue.
  • In-app support email and FAQ section will increase your app’s rating score. If your customers cannot contact you easily to complain about bugs or issues with your app, they will definitely do it with a one star review, which can really hurt your App Store ratings!
  • On the other hand, if you provide great support, customers will return the favour (even if you don’t ask them to) and submit a positive review for your app and help spread the word to their friends on Twitter/Facebook.

Hope you enjoyed the post. Feel free to add your comments from your experiences dealing with your customers and app support. If you’ve got some great tips, even better!

Social game marketing

I’m not a game developer and was actually not planning on doing a game-related post for #idevblogaday, but I’m currently reading Game-Based Marketing about how marketers can use game mechanics to create and foster long term customer loyalty. Basically think frequent flyer programs, points cards and any other type of loyalty program out there.

As a marketer, the premise of the book is quite interesting, and today almost any major chain will have some sort of loyalty program – even in smaller businesses you will find sorts of loyalty program through which you can earn points, loyalty and status amongst peers (much like achievements, leaderboards, etc. that you’ll find in games).

It got me thinking a bit about how game developers should try and utilize the same kind of systems that are in place for loyalty programs. For example, a big part of loyalty programs is earning points, achievements and essentially status within a certain program. People love showing off and they love earning points and higher statuses – even if it doesn’t really get them anything in return.

So in this week’s post I’ll discuss various ways game developers can implement different strategies that are found in loyalty marketing. I’ll discuss features that are well known and quite common in most top 25 App Store games, but at the same time, I hope to bring to light some aspects of these features.

Leaderboards
If you’re currently reading this and have a game in which you do not have a leaderboard, stop right now and start integrating one immediately.

A great part of the fun of playing games are being able to share with your friends your scores, points, etc. Also, being able to compare yourself directly with other players or friends playing the game is an important part of the fun.

The best way to do this is through an integrated leaderboard system. This allows the player to easily keep track of their score and abilities and compare them with their previous scores and how they rank amongst their friends and other players worldwide (or perhaps even cities, states, countries, etc.).

Game Center, OpenFeint, etc. provide easy-to-implement and solid foundations for leaderboards. These are also awesome (and free) marketing tools. For example, I have found myself looking through my GC friends games lists to find new games to play. It has also kept me coming back to certain games because GC has provided an opportunity to indirectly challenge me to continue playing the game to beat certain friends scores. This in return provides you as a game developer to cross-advertise your new game releases or sales for your other games.

Although competition is great, I wish more developers would integrate GC or OF (which also offer built-in GC integration), instead of trying to roll their own or using a less popular social game network. For example, when GC was released, I found myself revisiting old games to beat my friends’ scores or earn achievements. Those games that still do not offer a widely-used system just doesn’t draw enough attention, and I cannot be bothered to find out my friends’ usernames on the not-so-well-known social game networks.

Achievements
Achievements are also a great way to provide a leaderboard-type system in your game. It also helps prolong the experience and fun with your game.

A few examples of use of achievements in games:
• Achievements provide an opportunity to easily reward the player throughout the game. Levels, new upgrades, etc. This helps create a path for your game and a path for completion.
• Think of achievements that would require more practice or more time playing, basically ones that would prolong the game for players for after they’ve finished all levels. For example, Cut the Rope could use a timer and an achievement for finishing certain levels in certain amount of time, instead of just the three stars. You do earn more points for finishing a level fast, however this isn’t apparent, and after finishing the levels I cannot see how much faster I should have been in order to earn more points. Another example of achievements is Trainyard, which could give an achievement for finishing all stations in one city by using only X amount of tracks. These two examples provide a way to challenge the more hardcore players since they’re considerable more difficult than pure completion of a level, and it also does not hinder the completion of the game for the more casual players.
• Be careful not to make achievement nearly impossible to obtain. For example don’t make an achievement for “Played 100 hours” if your game basically takes an hour or two to finish all levels. Unless there’s a lot more to your game after having finished it, you can’t expect anyone to want to spend so much time playing it – even if they love going for those achievements.

Again, Game Center and OpenFeint provide great frameworks for integrating achievements as well as achievement leaderboards and friending systems. Use one or both of the solutions and think of ways to achievements into your game to make it more fun and challenging. They’re completely free and helps save you a ton of work instead of trying to roll your own.

Small side-note to leaderboards and achievements: Add a button somewhere in your games’ menus that let’s the user see their scores and/or achievements. Both GC and OF offer modal views for these. This way the user doesn’t have to leave the game to check an achievement or whether they’ve now trumped their friend’s top score, and you also help bring them right to the information they’re seeking – not leaving them to go to GC via the app itself, for example, and drill through the view hierarchy in order to find what they’re looking for.

Social Sharing
Sharing high scores, achievements, etc. is great opportunity to advertise your game and something that players love to do!

However, instead of just providing a Facebook and Twitter button for sharing a score or achievement, why not go a littler further and help the player out with deciding when it’s appropriate to do so? For example, what might seem like a low score to one player, may turn out to be in the top 5% of the leaderboards. After completion of a level or game, the developer could integrate a system that looks up the score and based on various factors it may say something like “Holy shit, your score was super high, you’ve just entered the top 10%, you should totally brag about it on Twitter and/or Facebook!” – or something like that. This helps the player realize the worth of their skill and score and may actually be more effective than just having a button that enables sharing of a score on social networks.

Also, don’t just tweet a score plus a link. Players will look through this as a pathetic attempt from you to get some free advertising out of them. They already paid you money, why should they help you out more, even your game is the most awesome one ever made?

I realize you don’t have a lot of characters to work with on Twitter, but including more than just the score is important. If I see “John just scored 13,453 in [some game]!”, I don’t really know whether it’s a good score and it doesn’t provide me with a way of relating this score to my own skills (unless I have played it). However, if I see something like “John just placed in the top 5% in [some game] with 13,453 points!” I would be more interested and perhaps more inclined to try out the game and beat John’s score if I know we have similar skill and scores in most games. It also gives both John and his friends a better understanding of just how awesome getting 13,453 points is. Without relating the points to anything, no one can see whether it’s actually a good score if they don’t know the premise of the game and the value of those points. John might actually be tweeting a super low score (compared to his friends’ scores), so helping John decide when it’s an appropriate time to share his score helps him save the embarrassment of tweeting a humiliatingly low score.

Basically, adding more substance to your sharing feature gives you more respect from your user (surprise and delight) and also makes them more likely to actually indirectly want to help you advertise (which you have to admit; you’re adding this feature more for yourself to advertise than actually just scoring some random score).

Another great way of sharing content from your game is something like Matt Rix‘s Trainyard solution sharing system. It works both as a way for players to show off their skills, but also helps more casual players progress through the game. Hardcore players love showing off and it also provides a way to prolong the game for hardcore players as they may try and find new solutions that haven’t yet been done. Linking this with the previous paragraph, one thing the game could do was to provide a small notification if a solution is 100% unique by saying “You have created a unique solution not yet available on Trainyard.ca, would you like to share with the community?” This helps the player realize their skill compared to others and again provides the more hardcore gamers with replay value, as they may go back to some levels in order to make new solutions, not yet seen by the community. That in itself could create a separate leaderboard for players which shows the top 50 players who have come up with and shared unique solutions, again improving the experience and loyalty further for those committed to the game and the community that surrounds it.

Game save syncing
This is as much of an idea as it is a request to all game developers out there.

Universal games are starting to become more common, now with iPhones, iPods touches and of course iPads selling like crazy. I own both an iPhone and an iPad and love when developers take a bit of extra time to release their game as a Universal game – even if the iPad is pretty much the same as the iPhone game, just larger. Of course, not all games scale as easily from iPhone to iPad in terms of the experience with the extra space, but for games that I play both on my iPhone and iPad, I would love to see server-based game save syncing or whatever you want to call it. However, this doesn’t just go for Universal apps, since many people have several devices. If they have the same game installed on both their iPhone and iPod, why not make the game experience more fluid?

The premise of this idea is dead simple: I play a game on my iPhone on the subway home from work. When I get home and hit the couch later that night, I want to reach for my iPad on the coffee table and play the exact same game, from the exact point I left off. I don’t want to start over from level one. I don’t want to have to earn the exact same achievements I just unlocked four hours ago (especially since they’ll appear as unlocked just fine if I head into Game Center).

Again it might be something 80% of users wouldn’t need. You may never have had to bring your game saves on your Wii controller to your friend’s place or transfer your PS3 game saves to your buddies PS3 so you can show of your collection of sweet cars in GT5. But it’s something we have now seen in console games for well over a decade now. As much as it may be a less used feature, it’s something I just don’t understand why is missing on such a portable platform.

It could be somewhat simple, depending on what your game exists of. When you start adding stuff like specific amounts of bullet ammo left, percentage of health left, points in each cleared level, etc. we’re getting a bit more advanced, but it’s definitely possible, regardless.

Game saves could be saved on a server and retrieved using an email and password. I don’t know the exact workings of GameKit, but maybe a successful login to Game Center could prompt a “It appears you have a game save available in the cloud based on your GC username, would you like to sync this device and keep your progression in sync?”. (If anyone at Apple is reading this or if you know someone working on GameKit, please let them know to consider adding game save-syncing to Game Center :))

Or even something like bluetooth sharing of game save states, bumping devices, or sharing via a unique code displayed on one device and entering the code on the other device would retrieve whatever was just uploaded to the server.

Just a few ideas of how you may be able to work it out, but seriously, this is such a great feature that would really set your game apart from others (apart from being a unique experience in itself, of course) and your users will love it.

I have yet to come across a single iOS game that does this, so if you know of one, please do share it in the comments, so other developers can check out and perhaps get some ideas for their own game.

Wrapping up
I hope I have sparked some ideas into your head as to what you can do to enhance the experience with your game and creating some loyalty amongst your customers. Some of the above ideas definitely will enhance and prolong the game experience, adding value to your game from what is actually very little work in most cases, implementing GC or OF or enhancing score-sharing on social networks.

Thanks for reading and please do leave a comment!

Random tips

I was expecting this blog post to be about something completely different, but I’m still out of the country and have come down with a bad cold, so it’ll be a bit of a short and simple.

I’ve decided just to a few coding tips, I have come across and though might be useful for other devs, especially if you haven’t worked much with UIKit before in your development, or perhaps just these areas below. (At the bottom of this post is an Xcode project file which includes examples of the tips below).

Tip #1: Check for URL scheme and open correct app from your own
You’ll probably run into having to link to another app, for example your company’s Twitter account. Instead of just linking to the Twitter website, you can do a quick check in code and open the Twitter app instead. You can also do it with other Twitter client apps as well, however, not all have URL schemes setup (that I could find), and most users will probably be using the official one anyway. Regardless, the code is good to do the same check for other apps, or if Twitter.app doesn’t exists on the user’s device, you can try another Twitter client app, or use a UIAlertView to ask the user what else they’d like to use (depending on which ones are possible to open using the URL scheme).

Basically, all you have to do is ask whether UIApplication responds to the URL:

BOOL twitter = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://user?screen_name=runmad"]];
if (!twitter) {
	[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.twitter.com/runmad"]];
} else {
	[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://user?screen_name=runmad"]];
}

List of URL Schemes: http://wiki.akosma.com/IPhone_URL_Schemes

Tip #2: Getting a free UINavigationController in your UIViewController
I have seen some apps that use a UIToolbar as a navigation bar, and this just doesn’t work. If you compare the two, they’re actually a bit different, and this really shows when put in the wrong place.

If you’ve got a UIViewController, turning it into a UINavigationController is really easy:

RootViewController *rootViewController = [[RootViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self.navigationController presentModalViewController:navigationController animated:YES];
[rootViewController release];
[navigationController release];

Tip #3: Getting a free UIToolbar in your UINavigationController
This one I only just recently found out (thanks to @auibrian)
. UINavigationController actually comes with a UIToolbar. It’s property is set to hidden:YES by default, so all you have to do is override this property when you load the view.

[self.navigationController setToolbarHidden:NO];

Note: I have seen some weird behaviour when pushing view controllers onto the screen (buttons not getting a pushing animation, just appearing in the toolbar in place). Also, you will need to hide the toolbar if you’re popping or pushing to a view controller that you do not want to show the toolbar (because with pushing you’re reusing the same navigation controller). In my opinion it’s not a very good way, I wish the view controllers were more separate for this.

Tip #4: Use shadowColor and shadowOffset appropriately when faking text indention
One thing that bugs me are improper use of a UILabel’s shadowColor and shadowOffset. When using these, one has to pay attention to the colour of the background as well as the text colour. In the below example (when we’re going for the look where text looks carved into the display, used by Apple across the entire UI), we’ll see that when using darker text, use a lighter colour for the shadow and a positive value for the offset.

When displaying lighter coloured text, use a darker shadow colour and a negative value for the offset, which in both cases create the proper indented or “carved” effect.

Using the wrong combination doesn’t create this effect and makes the text appear raised from the rest of your UI, which is most likely not what you should be going for in most cases ;)

I’ve made a small Xcode project you can download here, which has the code examples from tips 1, 2 and 3 and I suppose #4 as well, since navigationItem.title is using text indention.

Again, apologies for a bit of a short and simple post due to being under the weather and traveling.