Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

Wednesday, January 26, 2011

Hey Bing, iOS isn't Windows Phone 7

The Bing app for iOS was decent, until recent updates. It looks like someone at Microsoft decided they needed to make the Bing app for iOS look and feel more like a Windows Phone 7 app. So they did, and the result is an ugly, unusable disaster.

On Windows Phone 7, buttons look like traditional 'labels', but in lower-case font. Clickable elements are very subtly different from text, but yet it's obvious what is clickable and what isn't. The hardware 'back' button, standard on all phones, is used to dismiss modal dialogs. That's how the native interface of the phone (called 'Metro', I believe) is, and it all comes together quite beautifully. Here's what a menu on a native Windows Phone 7 app looks like:



On iOS, buttons looks like, well, buttons. Clickable elements have depth and curves and are strikingly different from text/labels. There is no hardware back button, so Apple has provided built-in buttons with system fonts and colors which are placed on the top right corner to dismiss modal dialogs. Just like Windows Phone 7, it's well thought out, coherent and comes together beautifully. Here's how menus, buttons and dialogs look on iOS.





Good apps follow Human Interface Guidelines of the platform they're built for, which gives them consistency with the rest of the system and makes interactions with the application intuitive. For some reason, the developers/designers of the Bing iOS app decided to follow the Human Interface Guidelines for Windows Phone 7 for their iOS app, instead of following the iOS HIG guidelines, and the result is just awful.

Below is what a modal menu on the Bing app looks like on my iPhone (the rest of the app looks similar, and has the same flaws). I have been using apps on my iPhone for two years and yet it took me several minutes to figure out what I needed to do on that dialog. It wasn't obvious how to toggle options on the menu, nor was it obvious how I could dismiss the dialogs. It took me a good two minutes to realize that the 'done' label was infact a button, and that almost everything on that screen was clickable, except the tiny header that reads "MENU". The font size on that label (page header) is smaller than that on the label-buttons, which sounds inverted, and makes the page look ugly.





Compare this with the image below and notice how obvious and beautiful some of those same options are on the native iPhone mapping application. (This isn't a modal dialog on the native app - if it was, I can guarantee that there would be a blue 'Done' button in the top right corner).





In fact, the entire experience of using the Bing app is so jarring that I refuse to use it at all, in spite of some of its nifty features. And I would be very surprised if I'm the only one who feels that way. It literally feels like Microsoft ported an app that is likely beautiful and usable on Windows Phone 7 to iOS without putting any thought into iOS usability. In fact, my guess is that the developers spent more time trying to make those buttons and table-views looks like Windows Phone 7 than they would have if they just used what the system provided with minor tweaks.

I cannot come up any reasonable explanation for why the designers of Bing chose to do this. If they want their application to be used, I sincerely hope they fix it soon.

Friday, January 21, 2011

On Mediocre Software - Where is the Love?

A recurring theme in some of the feedback we've seen for Audiogalaxy in reviews and direct feedback from users is how surprised they are when everything just works. A lot of the praise that the product has received goes something like this:

"Having tried and failed with several similar products I was shocked that when I used Audiogalaxy, it worked! No long delays, no dropping back to the initial screen, no anything wrong, just the music playing for as many hours as I needed."

"It does exactly what it's supposed to do. How often do you see that?"

"I never write reviews because most apps usually suck, but this is... different."

I won't feign modesty - we've worked pretty hard to make sure that Audiogalaxy works well. But that's not the point of this post. What statements like the ones above imply is that users are accustomed to underwhelming software. Most people, it seems, approach new software products with skepticism and wariness. Having been bitten by bad software several times in the past, they have become conditioned to assume the worst, and to be surprised when software works as it's expected to. While this might be true of other things too, in this case it points to a collective failure of the software development community. Commoditization of software developers/development and easy software distribution channels seem, on the surface, a boon to the software industry but are also a root cause for this mediocrity that people seem to now expect.

A telling sign of how extensive this perception is the following email I received from a friend after he used Audiogalaxy:

"Frankly speaking, my expectations were not very high. I was like, 'it's gonna be yet another process sucking the life out of my machine'. I was expecting to spend at least 30 minutes configuring everything, but was pretty much done in a couple of clicks and listening to music in a couple of minutes. It blew away my expectations in terms of how light weight it was (like 5 MB of memory and close to 0-1% cpu) and also super responsive in the browser to!!!"

On the surface, this comment seems to fall into the same bucket at the others above. However, this friend is actually a really good software developer himself. So this default notion of 'crappy software' isn't just users' perception. It is a dirty insider secret - we know about it, we expect it and yet we just suck it up and deal with it.

It's time to fix this, my fellow software geeks. You may say that people will vote with their money, and that bad software will fall by the wayside, and that the wheat will separate from the chaff, yada yada... All that may be true. But by producing crappy software, we're diluting the value of software as a whole, which eventually trickles down and affects each one of us.

Now this is the part of the post where I really should offer a silver bullet that will 'fix it all' and permanently change users' perceptions. Alas, I'll leave that to folks who are smarter than I. The one thing that I've learnt in my short career, and the only advise I can offer is this:

Build software with love, nurture it with care, take pride in its successes and share blame in its failures.

This mantra won't make you write bug free code or automatically make your software user friendly overnight - that's what experience, skills, iteration and good engineering practices are for. Heck, no software developer is anywhere close to writing 100% bug-free code. However, it will guide you in making decisions that lead to good, solid software which does what it says and says what it does. After all, software isn't just code - it is the culmination of every decision made in its journey from its inception to its current state.

A world where bad software/technology is an anomaly, not the norm, would be a good world - and it starts with us.

Thursday, September 9, 2010

Google Instant's biggest win? Teaching users to search better

The biggest impact of Google Instant is that it teaches users how to search more effectively. Based on these dynamic results, users can tweak their query such that it helps them find the exact answer they were looking for, even if they started with a bad query. Teaching users how to improve their search query is huge. The immediate impact is that it improves users' perception of Google's search results. Same with speed - users will perceive Google as being much faster than anything else out there because of the instant results.

Perception is reality. Speed and relevance are a search engines bread & butter. I think Google just upped the ante by a lot.

Credit to Microsoft though - this probably wouldn't have happened if it weren't for Bing's recent gains. Proof that competition provides the best kick-in-the-pants needed to innovate.

Friday, September 3, 2010

Integrating Core Data into your Three20 App

The Three20 library for iPhone app development is pretty cool - it take care of a lot of the 'mundane' code that you might need to write to accomplish basic tasks. Apple really should include some of the functionality of Three20 in the iPhone SDK itself, specially the Network stack.

As I built a more advanced app using Three20, I realized that it would be great to be able to persist to a database to make loading quicker when state on the server is unchanged. I needed some pretty basic Core Data integration in my app, and it was a little annoying that Three20 didn't have a Core Data-backed implementation of TTModel built into it. It seems like a lot of people want this, but there isn't any good post about it I could find. Jeff Verkoey, who currently maintains Three20, started writing a Core Data based tutorial but didn't get around to actually doing much with it. And there are a few threads in the Three20 Google group but nothing too comprehensive.

Having built this for my app, I figured I would post some more concrete information here for others who might find it helpful. I really want to just contribute a clean cut of this code as a TTCoreDataModel with unit tests to the Three20 source, but I don't have the luxury to spend time on it currently.

So here's a quick step-by-step on how to modify your existing Three20 based app to add basic Core Data support. The specific example I use fetches data from a server using TTURLRequestModel and writes it out to SQLite using Core Data entities. When displaying data to the user, it fetches data from Core Data using a NSFetchedResultsController, which efficiently interacts with Core Data.

Step 1:
Add CoreData.framework to your list of dependencies. Then, add the Core Data stack. Usually, you would do this in the AppDelegate. Jeff's AppDelegate files have this implemented, if you want an example. In my case, I wanted different databases for different Models, so I had these in my TTModel implementations.

Step 2:
Create your model. Add a new file of type "Data Model" in XCode (available in the 'Resource' section). Make sure the .xcdatamodel file gets added to your Target so that it's compiled into your binary. Look here for information on using the modeling tool. Once you've created your model, import the code for the Entity objects into your project. Now you're ready to start using Core Data.

Step 3:
Update your TTURLRequestModel implementation. Let's assume you're simply downloading some JSON and want to write it out to Core Data as an Entity you created in Step 2. Update your (void)requestDidFinishLoad:(TTURLRequest*)request implementation of TTURLRequestDelegate as follows:




A few notes about the code above:
  • DBResource is my simple entity containing an "id" and a "name".
  • The NSAutoreleasePool helps clean up memory allocated in this tight loop here
  • -reseting the context makes sure that the data faults in as needed instead of staying in memory when you read it using the NSFetchedResultsController
Step 4:
In your TTTableViewDataSource implementation, create a NSFetchedResultsController and configure it to fetch your Entities as needed. Then, override the (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)indexPath method to return a TTTableItem built using the Entity you fetched from Core Data




Now, your TTTableViewDataSource is configured to read results from the DB you created and display them in your view. Remember that tableViewDidLoadModel can be called multiple times, so clean up any previously allocated NSFetchedResultsController if you need to.

Step 5:
Implement your logic to delete/update your Core Data entities. Depending on how your app uses data persistence, you want to ensure that you update/delete your entities from Core Data. For instance, if you always want to fetch data from the server and load them into Core Data on first run, then update Step 3 to first delete all entities. If you wish to show local data when available but fetch when not, then update Step 3 to not hit the server before checking locally. When deleting entities, remember that Core Data only lets you delete a single entity at a time (so you must fetch all and loop through each to delete it). If you want DROP TABLE ... semantics you're going to need to maintain different NSManagedObjectContent and NSPersistentStoreCoordinator for each such table, and then simply delete the database file.

So, this isn't too hard really. Assuming you're familiar enough with building your Three20 app, my notes above should help you get started with integrating Core Data into your app. My app uses a TTSectionedDataSource, and with a few tweaks to NSFetchedResultsController it's simple to do that too.

Wednesday, December 23, 2009

Browser history navigation bug in Chrome and Safari

I've been seeing some odd behavior in Chrome - occasionally browser history would get hosed pretty badly. When I noticed the same issue navigating the website I'm working on, I ended up spending a bunch of time trying to get to the bottom of the issue. Initially I suspected it was something wrong with the site, but I was eventually able to create a stand-alone repro for Chrome (v3 and v4) as well as for Safari (v4). I suspect this might be a WebKit thing, which both browsers share, but I don't know enough to be certain.

The problem seems to occur when you spend time moving around fully ajax sites that contain one or more iframes (I've seen this on GMail as well). In my case I worked around this issue by not using iframes but I imagine that's not always possible. Anyways, this is now Chromium bug 30693.