Last year I launched Codename One Academy and asked our community what they would like to learn as part of a survey. The response was was overwhelmingly how to build an app like Uber. At first I thought about creating something in the style of Uber but I eventually settled on building something that looks really close to how the native app looks. Almost a clone in some regards. My motivation was:
- I wanted the design to look professional and you can’t go wrong with a design from a top tier vendor
- People can learn a lot by understanding the decisions Uber made — I know I did
- If I would have built something different I might have given myself “discounts” that don’t exist in the real world
I used the word clone to indicate the similarity but not to indicate a 1:1 copy. Uber is a huge and nuanced app and I had only one week to write all the relevant applicable code… My goal was to do the “hard stuff” and gloss over some of the deeper details.
What I Learned?
I didn’t expect to learn much but a few things really surprised me. One such thing was the heavy usage of material design on iOS in the native Uber app. E.g:
Notice that this looks almost identical to the Android version of the app. You have staple Android UI elements such as the floating action button, material design text entry and arrow back button…
The Android version does indeed look almost identical!
Historically I always thought native widgets promoted engagement through familiarity. In fact, Chen and myself used to argue about this constantly. I pushed towards a more “native widget feel” approach while Chen pushed towards a single UI for all platforms.
It seems Uber sided with Chen. Uber has one UI design that is almost identical in iOS & Android.
This makes sense, they can reuse the design. Have one screenshot to support both OS’s in their training materials. As long as the app looks decent and everything is still in place this is still intuitive.
During the days of Android 2.x and iOS 6.x the differences between the OS’s were too big. Having a top left back button on Android would have been blasphemy...
Today convergence just makes financial sense even if you don’t use a cross platform tool.
Transitions are Still Different
I’m not sure if they did this by design but the transitions in the Android & iOS native versions are very different from one another. The Android version uses the material design style transition although I didn’t see “hero transitions”. iOS uses cover and slide transitions.
If this is on purpose it means “feel” beats “look”. I’m guessing it’s just something they didn’t care enough about but it’s hard to know.
Here is the initial native Uber login screen on Android:
The same screen on iOS looks similar but has a rendering bug:
In case you don’t see it look at the “Enter your mobile number” text.
I’m sure Uber has a lot of QA. I’m guessing this slipped because most of them are in countries that don’t have 3 digit dial codes. The Android version (and our version) handle this well. I’m guessing it was fixed on Android because of its global appeal.
Fixes made to the Android version don’t trickle into the iOS version.
Some Features are Harder on Android
If you run the iOS version of Uber and look at the login screen above you will see that the pattern in the background rotates. This is a great special effect that looks subtle and pleasant.
That’s why I was surprised that they didn’t do it for Android…
I doubt they lack engineers to implement this subtle feature.
After working a bit on Android it became pretty apparent why they chose to avoid this. Android has issues in the vector graphics department. When you try to generate this path and perform the rotation effect you get the error:
“OpenGLRenderer: Path too large to be rendered into a texture”
The only workaround I found is to disable hardware rendering in my case by drawing onto an image surface.
The point that sucks about this is that it’s really hard to know what went wrong. Rendering a path doesn’t throw an exception, it just doesn’t show. So I can’t fallback dynamically to software rendering and I’m not sure what’s wrong in the path?
Coordinates out of bounds? Number of coordinates?
Looking at the Android code responsible for that message didn’t help much either.
Regardless it’s a bit frustrating that in an otherwise identical UI iOS has features that are lacking in Android.
They Don’t Intercept SMS’s on Android
The thing I love most about Android is the low level of control you get as a developer. This is a double edged sword but in some cases it beats everything else…
One great example is SMS interception support. When you have an SMS activation process Android can grab the incoming SMS and skip the need to type it in.
Amazingly the native Uber application doesn’t do that. They don’t use a native Android SMS activation.
After reading a bit it seems that Uber got a lot of flak over the years for “too many permissions”. I think they were just concerned about a permission for making phone calls…
I’m not sure if this would apply as much with API level 23 (where Android switched to permission prompts). Either way I added this functionality in our version of Uber and it makes the signup process much smoother on Android.
They Portrait Locked the App
This is a personal pet peeve of mine. I love apps that rotate properly to landscape and Uber blocked that.
I understand why they did that. Supporting landscape would mean a lot more work as some forms like the login form I mentioned before would need a complete overhaul for landscape.
The thing it says though is interesting: rather than spend manpower on doing these things. Uber would rather focus on functionality than support landscape orientation. I can respect that.
I think this and all of the above show clearly that Uber believes in function over form. They reduce features & bloat focusing heavily on the core functionality.
They Change a Lot
I never noticed how quickly things change in Uber’s UI until I started replicating it. When I started the history buttons were circles in the bottom of the display and now they are pull downs from the search area.
The ability to move quickly and experiment with design decisions is crucial for an app like Uber.
With a few Services You can do Most of the Work
I didn’t build anything remotely as elaborate or nuanced as the full app but the people who built 90% of this are the guys at Google.
I used the native Google Maps widget and a few Google webservices (directions, places, geocoding). I also used Twilio & Braintree for SMS/billing respectively. With all of these you can get the big pieces of Uber functionality in less than a week!
With some help from existing tools building an Uber like app is actually not that hard.
The main problem would be the level of support you can get for an API like Google Maps within the cross platform tool.
I have a tremendous amount of respect for the Uber engineers. It’s a HUGELY complex app whose nuances are sublime.
I think innovation comes from building something new, but not completely new. We improve on the last generation and build something “better”. I think that by making the process of building an app “like Uber” simple. We’ll see apps going well beyond Uber.
Here are the things I learned:
- Uber has one UI design that is almost identical in iOS & Android
- Fixes made to the Android version don’t trickle into the iOS version
- It’s a bit frustrating that in an otherwise identical UI iOS has features that are lacking in Android
- They don’t use a native Android SMS activation
- Uber believes in function over form
- The ability to move quickly and experiment with design decisions is crucial for an app like Uber
- With some help from existing tools building an Uber like app is actually not that hard
If you want to learn more about this check out our blog.