busbud/coding-challenge-native-a — pull request #5 by jeanbaptistemorin (2014-11-22 23:21:09+00:00)
Title: JBM - busbud

# Solution

This is my way to solve the coding challenge (time spend : 7 hours).
Most of the error cases are handled, but I did not process an advanced QA testing.

## Global configuration

The solution is for Android. Tested on Nexus 4 only.
The solution has been developed on AndroidStudio with gradle.
This app is only traduced in French and English. All the texts are in dedicated files. For the API, we use the current device language code (lang parameter).

I started with a basic fresh Android app. To simplify dependencies for this PoC, I used:
- minSdkVersion 16
- targetSdkVersion 21

I used support lib and AppCompat, but I didn't test on older devices.

We basically need to have two mains permissions:
- Internet access: to access the API
- Geolocation: As we don't need to have a very accurate position, I used Coarse Geolocation that costs less in battery than the GPS and that is faster.

## Solution

Globally, we have a search API that is called in a specific way. The API is a basic HTTP - REST JSON API.
Of course all the calls has to be done in a background thread in order to not block the UI.
I used a singleton to abstract the X-BusBud-Token long live token (BBHttpHelper.java). The singleton also handles a unique HTTPClient. We are on mobile, let's reuse, reuse, reuse. There is a small helper that is dedicated to parse the JSON.
The only model object is the BBCity.java that is parcelable to be passed through screens. I added a getShortName() to display a title on the Result WebView screen.

For the UI, I used AutocompleteTextView, and I tweaked a bit the behavior, but a good approach is to re-implement a full search screen with nicer UX, a bit like: http://cyrilmottier.com/2014/05/20/custom-animations-with-fragments/

I started by added some key classes to make the API calls. And I wrote some unit tests to check that the API responds the way the README.md describes.

Then I started a small UI implementation using fragments:
- TutorialFragment: to explain the app, only if you never clicked on "Search bus tickets" before
- SearchFragment: to locate the user and let him search
- ResultFragment: WebView with two BBCity object parameters to display the results

The search fragment is the one that is listening to the location. Once the location is found, we make an asynchronous call the the API to find the closest origin city.
While we are looking for position and getting the closest City, the edit text inputs and search buttons are diabled.
As we don't use GPS, but coarse location, it's really fast.

Once the city is found, the inputs are enabled to the user. We set the "from" field to the found origin city and the focus is on the "to" field.
There are some errors cases that are basically handled:
- no location service on device (can happen on Android)
- API issue or no connectivity

The user can then search for a city into the second input text area.

NOTE: I extended a bit what was asked: the user can change the origin city. In that case the destination city input is erased. And once a new origin city is used, the origin_id is also changed in all API calls.

If the users have selected two valid cities, the search will open the web view.
Otherwise a toast is displayed.

There is a loader while the web page is loading, because it's very long.

And then... Here we are.