You are browsing the archive for Hazem Saleh.

Back from ApacheCon North America 2016

May 18, 2016 in Apache Cordova, JavaScript, mobile

I just get back from ApacheCon North America that was be held from 11 May to 13 May @Vancouver, Canada. The conference organization was really great and there were a lot of attendees in the conference sessions.

HazemSaleh_ApacheCon2016

I had the chance to present “Advanced Apache Cordova” in 12 May, the session was interactive, contained three live demos and I was really amazed by the energy, enthusiasm, and responsiveness of the attendees during the session.

My session is uploaded below.

Finally, I would like to thank all the organizers of ApacheCon conference for making the conference looks so great.

Dagger 2, MVP and Unit Testing (Android DI) – Part 3

April 7, 2016 in Android

In the previous two articles, we had an introduction to Dagger 2 with simple introductory examples and know how to use Android Build variants with Dagger 2 to have different implementations that are switched automatically when the app is in the debug mode or in the release mode.

This article discusses using Dagger 2 with MVP (Model View Presenter) pattern, and unit testing our simple Dagger 2 app using Espresso.

MVP is a derivation of MVC (Model View Controller) design pattern, and its main purpose is improving separation of concerns in the presentation layer. In MVP, Model represents “Data”, Presenter talks with the model to get data then it formats the data to be displayed by the view, and finally View displays the formatted data and delegate event handling to Presenter.

We will modify a little bit the introduced app in the first two articles to allow the end user to enter whatever city name and his name to finally have a greeting message that contains the current weather information of his entered city.

App Structure

The following interaction diagram shows the main app flow in an abstract way.
Sample Dagger App Flow

As shown in the diagram, in order to get weather information for a user, MainActivity talks with MainPresenter. Then MainPresenter talks with MainInteractor. Finally, MainInteractor abstracts the calls to the app services (HelloService and WeatherService) and it returns the result to the MainPresenter that displays data on the MainActivity (which represents the View).

The next diagram shows the app structure, which is a self-explanatory.
App-Structure

Dagger 2 for Dependency Injection

Now, let’s see some of the important details of Dagger 2 components and subcomponents in our App. We mainly have a single Component (AppComponent), which is responsible for AppModule and ServiceModule modules. AppComponent class code is shown below.

@Singleton
@Component(modules = {AppModule.class, ServiceModule.class})
public interface AppComponent {

    MainActivityComponent plus(MainActivityModule module);
    Application application();
}

Dagger Subcomponent is defined using @Subcomponent annotation on an interface. The main difference between Dagger component and Subcomponent is that Subcomponent cannot live standalone and has to be defined as a method on an interface marked as @Component and that method should return the interface marked as Subcomponent. This is why MainActivityComponent plus(MainActivityModule module) method is defined in AppComponent since a Subcomponent will be defined for every activity in our app.

The next code snippet shows the AppModule class code, which provides instances of Application and Resources classes.

@Module
public class AppModule {
    DaggerApplication app;

    public AppModule(DaggerApplication application) {
        app = application;
    }

    @Provides
    @Singleton
    protected Application provideApplication() {
        return app;
    }

    @Provides
    @Singleton
    protected Resources provideResources() {
        return app.getResources();
    }
}

The next code snippet shows the ServiceModule class code, which provides instances of HelloService and WeatherService.

@Module
public class ServiceModule {

    @Provides
    @Singleton
    HelloService provideHelloService() {
        return new HelloServiceDebugManager();
    }

    @Provides
    @Singleton
    WeatherService provideWeatherService() {
        return new WeatherServiceManager();
    }
}

@ActivityScope custom scope is defined for every activity Subcomponent; the following code snippet shows MainActivityComponent code.

@ActivityScope
@Subcomponent(
        modules = {MainActivityModule.class}
)
public interface MainActivityComponent {
    void inject(MainActivity activity);
}

MainActivityModule will be responsible for providing instances of the MainActivity (which implements the MainView interface), and also instances of MainInteractor interface.

@Module
public class MainActivityModule {

    public final MainView view;

    public MainActivityModule(MainView view) {
        this.view = view;
    }

    @Provides
    @ActivityScope
    MainView provideMainView() {
        return this.view;
    }

    @Provides
    @ActivityScope
    MainInteractor provideMainInteractor(MainInteractorImpl interactor) {
        return interactor;
    }

    @Provides
    @ActivityScope
    MainPresenter provideMainPresenter(MainPresenterImpl presenter) {
        return presenter;
    }
}

Finally, the next code snippet shows the custom Application class code, which is used for initializing the AppComponent graph.

public class DaggerApplication extends Application {
    private static AppComponent appComponent;
    private static DaggerApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        initAppComponents();
    }

    public static DaggerApplication get(Context context) {
        return (DaggerApplication) context.getApplicationContext();
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }

    public void initAppComponents() {
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();

    }

    /**
     * Visible only for testing purposes.
     */
    public void setTestComponent(AppComponent testingComponent) {
        appComponent = testingComponent;
    }
}

Note that setTestComponent(AppComponent testingComponent) method will be used for testing purposes only to provide a mock implementation of the AppComponent class to test the app flow.

App Details

Now, let’s see some of the app details. The next code snippet shows MainView interface that defines the view methods of the MainActivity (MainView is implemented by MainActivity and extends OnInfoCompletedListener interface).

public interface MainView extends OnInfoCompletedListener {
    public String getUserNameText();
    public String getCityText();

    public void showUserNameError(int messageId);
    public void showCityNameError(int messageId);

    public void showBusyIndicator();
    public void hideBusyIndicator();

    public void showResult(String result);
}

OnInfoCompletedListener interface defines the information retrieval operation’s callback methods since this operation is asynchronous.

public interface OnInfoCompletedListener {
    public void onUserNameValidationError(int messageID);
    public void onCityValidationError(int messageID);
    public void onSuccess(String data);
    public void onFailure(String errorMessage);
}

The following code snippet shows MainActivity class. Note that ButterKnife provides @InjectView annotation. ButterKnife is a lightweight library that can be used for injecting User interface elements instead of doing this every time manually using findViewById() method of View class.

public class MainActivity extends AppCompatActivity implements MainView, View.OnClickListener {

    @Inject
    MainPresenter presenter;

    @InjectView(R.id.userNameText)
    EditText userNameText;

    @InjectView(R.id.cityText)
    EditText cityText;

    @InjectView(R.id.btnShowInfo)
    Button showInfoButton;

    @InjectView(R.id.resultView)
    TextView resultView;

    @InjectView(R.id.progress)
    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.inject(this);

        DaggerApplication.get(this)
                .getAppComponent()
                .plus(new MainActivityModule(this))
                .inject(this);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        showInfoButton.setOnClickListener(this);
    }

    // …

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnShowInfo) {
            presenter.requestInformation();
        }
    }

    @Override
    public String getUserNameText() {
        return userNameText.getText().toString();
    }

    @Override
    public String getCityText() {
        return cityText.getText().toString();
    }

    @Override
    public void showUserNameError(int messageId) {
        userNameText.setError(getString(messageId));
    }

    @Override
    public void showCityNameError(int messageId) {
        cityText.setError(getString(messageId));
    }

    @Override
    public void showBusyIndicator() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideBusyIndicator() {
        progressBar.setVisibility(View.GONE);
    }

    @Override
    public void showResult(final String result) {
        resultView.setText(result);
    }

    @Override
    public void onUserNameValidationError(final int messageID) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                hideBusyIndicator();
                showUserNameError(messageID);
            }
        });
    }

    @Override
    public void onCityValidationError(final int messageID) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                hideBusyIndicator();
                showCityNameError(messageID);
            }
        });
    }

    @Override
    public void onSuccess(final String data) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                hideBusyIndicator();
                showResult(data);
            }
        });
    }

    @Override
    public void onFailure(final String errorMessage) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                hideBusyIndicator();
                showResult(errorMessage);
            }
        });
    }
}

One important thing to note here is that in the activity’s onCreate() method, MainActivityComponent is initiated using DaggerApplication.get(this).getAppComponent().plus(new MainActivityModule(this)).inject(this). When the show information button is clicked, requestInformation() of MainPresenter is called.

The next code snippet shows MainPresenter interface which has only one method.

public interface MainPresenter {
    public void requestInformation();
}

MainPresenterImpl class implements MainPresenter as follows.

public class MainPresenterImpl implements MainPresenter {
    private MainView mainView;
    private MainInteractor mainInteractor;

    @Inject
    public MainPresenterImpl(MainView mainView, MainInteractor mainInteractor) {
        this.mainView = mainView;
        this.mainInteractor = mainInteractor;
    }

    @Override
    public void requestInformation() {
        mainView.showBusyIndicator();
        mainInteractor.getInformation(mainView.getUserNameText(), mainView.getCityText(), mainView);
    }
}

As shown in the MainPresenterImpl‘s requestInformation() method, it calls mainInteractor‘s getInformation() method passing user name, city name, and the class instance (mainView) which implements OnInfoCompletedListener interface.

The next code snippet shows MainInteractor interface.

public interface MainInteractor {
    public void getInformation(String userName, String cityName, final OnInfoCompletedListener listener);
}

The next code snippet shows MainInteractorImpl class, which interacts with HelloService and WeatherService interfaces.

public class MainInteractorImpl implements MainInteractor {
    private static final String TAG = MainInteractorImpl.class.getName();

    @Inject
    HelloService helloService;

    @Inject
    WeatherService weatherService;

    @Inject
    public MainInteractorImpl() {
    }

    @Override
    public void getInformation(final String userName, final String cityName, final OnInfoCompletedListener listener) {
        final String greeting = helloService.greet(userName) + "\n";

        if (TextUtils.isEmpty(userName)) {
            listener.onUserNameValidationError(R.string.username_invalid_message);
            return;
        }

        if (TextUtils.isEmpty(cityName)) {
            listener.onUserNameValidationError(R.string.city_invalid_message);
            return;
        }

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    int temperature = weatherService.getWeatherInfo(cityName);
                    String temp = "Current weather in " + cityName + " is " + temperature + "°F";

                    listener.onSuccess(greeting + temp);
                } catch (InvalidCityException ex) {
                    listener.onFailure(ex.getMessage());
                    Log.e(TAG, ex.getMessage(), ex);
                } catch (Exception ex) {
                    listener.onFailure("Unable to get weather information");
                    Log.e(TAG, ex.getMessage(), ex);
                }
            }
        });

        thread.start();
    }
}

When information is retrieved, getInformation() method calls the onSuccess() method of the OnInfoCompletedListener interface if the operation succeeds. If getInformation() method fails, it calls onFailure() method of the OnInfoCompletedListener interface.

Now, let’s look into the services part of the app. The next code snippet shows HelloService interface.

public interface HelloService {
    public String greet(String userName);
}

HelloServiceDebugImpl implements HelloService (Note that this implementation is active only in app debug mode. For the app release mode, HelloServiceReleaseManager will be the implementation of HelloService interface).

public class HelloServiceDebugManager implements HelloService {

    @Override
    public String greet(String userName) {
        return "[Debug] Hello " + userName + "!";
    }
}

The next code snippet shows WeatherService interface.

public interface WeatherService {
    public int getWeatherInfo(String city) throws InvalidCityException;
}

WeatherServiceImpl class implements WeatherService interface as follows.

public class WeatherServiceManager implements WeatherService {
    private static final String TAG = WeatherServiceManager.class.getName();

    @Override
    public int getWeatherInfo(String city) throws InvalidCityException {
        int temperature = 0;

        if (city == null) {
            throw new RuntimeException(ErrorMessages.CITY_REQUIRED);
        }

        try {
            city = URLEncoder.encode(city, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(ErrorMessages.INVALID_CITY_PROVIDED);
        }

        try {
            URL url = new URL("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22" + city + "%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys");
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

            httpURLConnection.setInstanceFollowRedirects(true);

            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");

            // Receive response ...
            int responseCode = httpURLConnection.getResponseCode();

            InputStream is = httpURLConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String line = "";
            StringBuffer sb = new StringBuffer();

            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }

            bufferedReader.close();

            String result = sb.toString();

            int startIndex = result.indexOf("\"temp\":");

            if (startIndex == -1) {
                throw new InvalidCityException(ErrorMessages.INVALID_CITY_PROVIDED);
            }

            int endIndex = result.indexOf(",", startIndex);

            temperature = Integer.parseInt(result.substring(startIndex + 8, endIndex - 1));
        } catch (InvalidCityException ex) {
            throw ex;
        } catch (Exception ex) {
            Log.e(TAG, ex.getMessage(), ex);
        }

        return temperature;
    }
}

What WeatherServiceImpl does is to get the weather information using Yahoo weather APIs.

Unit Testing App using Espresso

Now, let’s see how to unit test our application using Espresso. The next code snippet shows how we create our own test custom dagger component and use it instead of the original app component to test the app flow.

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
    private static String GREET_PREFIX = "[Test] Hello ";
    private static int MOCK_TEMPERATURE = 65;
    private static String MOCK_NAME = "Hazem";
    private static String MOCK_PLACE = "Cairo, Egypt";
    private static String MOCK_GREETING_MSG = GREET_PREFIX + MOCK_NAME;
    private static String MOCK_WEATHER_MSG = "\nCurrent weather in " + MOCK_PLACE + " is " + MOCK_TEMPERATURE + "°F";

    private static String MOCK_RESPONSE_MESSAGE = MOCK_GREETING_MSG + MOCK_WEATHER_MSG;

    private static String TAG = MainActivityTest.class.getName();

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new DaggerActivityTestRule<>(MainActivity.class, new DaggerActivityTestRule.OnBeforeActivityLaunchedListener<MainActivity>() {
                @Override
                public void beforeActivityLaunched(@NonNull Application application, @NonNull MainActivity activity) {
                    DaggerApplication app = (DaggerApplication) application;

                    AppComponent mTestAppComponent = DaggerMainActivityTest_TestAppComponent.builder()
                                                                                            .appModule(new AppModule(app))
                                                                                            .build();

                    app.setTestComponent(mTestAppComponent);
                }
            });

    @Singleton
    @Component(modules = {TestServiceModule.class, AppModule.class})
    interface TestAppComponent extends AppComponent {
    }

    @Module
    static class TestServiceModule {

        @Provides
        @Singleton
        HelloService provideHelloService() {
            return new HelloService() {
                @Override
                public String greet(String userName) {
                    return GREET_PREFIX + userName;
                }
            };
        }

        @Provides
        @Singleton
        WeatherService provideWeatherService() {
            return new WeatherService() {
                @Override
                public int getWeatherInfo(String city) throws InvalidCityException {
                    return 65;
                }
            };
        }
    }

    @Test
    public void greetButtonClicked() {
        onView(withId(R.id.userNameText))
                .perform(typeText(MOCK_NAME), closeSoftKeyboard());

        onView(withId(R.id.cityText)).perform(clearText(), typeText(MOCK_PLACE), closeSoftKeyboard());

        onView(withId(R.id.btnShowInfo)).perform(click());

        onView(withId(R.id.resultView)).check(matches(withText(MOCK_RESPONSE_MESSAGE)));
    }

}

In the test method greetButtonClicked(), a simulation for entering a username and a city is performed and then the show information button is clicked and finally the returned result is being tested against the mock message.

Check the app source code

All the source code of this Dagger 2 app can be found in:
https://github.com/hazems/Dagger-Sample/tree/dagger2-mvp-espresso1

Feel free to use and let me know if you have comments.

Finally, I hope that these three articles can provide a useful introduction to the cool Dagger2 DI framework.

An Introduction to Dagger 2 (Android DI) – Part 2

March 9, 2016 in Android

androidlogo1
In the previous article, we have a quick introduction to Dagger 2 with a simple introductory example. In this article, I will show you how to use Android Build variants with Dagger 2 to have different implementations (for the service interface) that are switched automatically when the app is in the debug mode or in the release mode.

First of all, under the release directory, let’s create a new component DaggerGraphComponent which extends from DaggerGraph as follows.

@Singleton
@Component(modules = {MainModule.class, ServiceModule.class})
public interface DaggerGraphComponent extends DaggerGraph {

    static final class Initializer {
        private Initializer() {
        }

        public static DaggerGraph init(DaggerApplication app) {
            return DaggerDaggerGraphComponent.builder()
                                             .mainModule(new MainModule(app))
                                             .build();
        }
    }
}

Secondly, create a service module which will be responsible for creating the instances of HelloService implementations (in debug and release modes).

For the release mode, ServiceModule provides only an instance of the HelloServiceReleaseManager class which implements HelloService.

@Module
public class ServiceModule {

    @Provides
    @Singleton
    HelloService provideHelloService() {
        return new HelloServiceReleaseManager();
    }
}

Below is HelloServiceReleaseManager simple implementation.

public class HelloServiceReleaseManager implements HelloService {

    @Override
    public String greet(String userName) {
        return "Hello " + userName + "! [Release]";
    }
}

Apply the same steps under the debug directory, in debug case, you can have a HelloServiceDebugManager class which implements HelloService interface as shown below.

public class HelloServiceDebugManager implements HelloService {

    @Override
    public String greet(String userName) {
        return "Hello " + userName + "! [Debug]";
    }
}

Make sure to have the following code hierarchy in release and debug.
Release Directory

Debug Screenshot

Running the project

Now, you can run the app in debug mode, and then enter some name and then click “Greet!” button, you will find the debug service response as follows.
Debug Mode

And then change the build variant to run the app in the release mode and do the same previous steps to see the results as shown below.
Release Mode

Checkout the code

Check the sample app code in GitHub:
https://github.com/hazems/Dagger-Sample/tree/dagger-sample2

What is next?

So in the next article, I will discuss how can we apply unit testing techniques for Dagger 2 applications. Stay tuned!

An Introduction to Dagger 2 (Android DI) – Part 1

March 5, 2016 in Android

androidlogo1
Dagger 2 is a dependency injection framework that is built on the standard javax.inject annotations (JSR 330). Dependency injection is a software design pattern that implements inversion of control for resolving dependencies. Implementing proper dependency injection in our apps allows us to have:

  1. Testable classes.
  2. Re-usable and interchangeable components.

In Android, there are a lot of dependency injection frameworks that you can use. However, one of the greatest advantages of Dagger is that is based on Code generation not on Reflection like Google RoboGuice which makes Dagger more efficient.

In Dagger 2, you can inject dependencies on fields and constructors as shown in the following examples. Injecting dependencies on methods is also possible.

// Field Injection Example
@Inject
HelloService helloService;
// Constructor Injection Example
HelloService helloService;
	
@Inject
public MyClass(HelloService helloService) {
    this.helloService = helloService;
}

In order to understand Dagger, it is important to identify Dagger main terms:

  1. Module.
  2. Component.

Module

Before defining what a Dagger module is and since this is a first basic example to show how Dagger 2 works, assume that we have only one simple service interface (HelloService) that is defined below.

public interface HelloService {
    public String greet(String userName);
}

HelloServiceManager is the simple implementation for HelloService interface as shown below.

public class HelloServiceManager implements HelloService {

    @Override
    public String greet(String userName) {
        return "Hello " + userName + "!";
    }
}

In order to inject HelloService interface implementation, we need to define a Dagger module.

A dagger module provides the way that constructs the objects which will be injected. In order to define a dagger module, create a class and annotate it with @Module annotation and define the provider methods that return the instances. Provider methods have to be annotated by @Provider annotation as shown below.

@Module
public class MainModule {
    DaggerApplication app;

    public MainModule(DaggerApplication application) {
        app = application;
    }

    @Provides
    @Singleton
    protected Application provideApplication() {
        return app;
    }

    @Provides
    @Singleton
    HelloService provideHelloService() {
        return new HelloServiceManager();
    }
}

Here in this module, we provide two singleton instances of an Android application class (DaggerApplication will be discussed later) and the HelloService implementation class.

Component

A dagger component can be seen as an intermediate object which allows accessing to objects defined in Dagger modules.

One of the cool functions of a Dagger component is that it allows injecting non private field members to provided object as argument. In some cases, constructor injection is not possible, for example, the instances that are created and managed by the platform such as Android activity.

This is why we need to create a component interface that allows describing for which types we want to use members injection as shown below.

@Singleton
@Component(modules = {MainModule.class})
public interface DaggerGraphComponent {
    void inject(MainActivity mainActivity);

    static final class Initializer {
        private Initializer() {
        }

        public static DaggerGraphComponent init(DaggerApplication app) {
            return DaggerDaggerGraphComponent.builder()
                                             .mainModule(new MainModule(app))
                                             .build();
        }
    }
}

A dagger component can be created by annotating the class with @Component annotation, you need also to specify the component’s associated modules which is a single module MainModule in our case.

Since we have a single activity, we will have a single inject(MainActivity) method in our Dagger component interface.

Once you annotate your component class with @Component, Dagger will generate a builder class for our component class with the prefix (Dagger). Using the builder class you can initialize the Dagger 2 dependency graph as follows.

DaggerDaggerGraphComponent.builder()
                          .mainModule(new MainModule(app))
                          .build();

Now, let’s see how to initialize dependency graph and consume services.

Initializing Dependency Graph

In order to initialize the Dagger 2 Dependency graph, we need to create an application class to call the component init() method for initializing the Dagger 2 dependency graph and to keep the instance of created graph throughout application’s lifecycle.

The code below shows our Android Application class.

public class DaggerApplication extends Application {
    private static DaggerGraphComponent graph;
    private static DaggerApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        buildComponentGraph();
    }

    public static DaggerGraphComponent component() {
        return graph;
    }

    public static void buildComponentGraph() {
        graph = DaggerGraphComponent.Initializer.init(instance);
    }
}

Do not forget to register the application class in AndroidManifest.xml as follows.

    <application
	...
        android:name=".service.di.DaggerApplication">
	...
    </application>

Injecting HelloService in Activity

Finally, in order to inject HelloService in your activity, do not forget to call DaggerApplication.component().inject(this) in the Activity onCreate() method as shown below.

public class MainActivity extends AppCompatActivity ... {

    @Inject
    HelloService helloService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerApplication.component().inject(this);	
	// ...
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.greet) {
            // you can call helloService.greet("user1") for example ...
        }
    }
}

Checkout the code

Check the sample app code in GitHub:
https://github.com/hazems/Dagger-Sample/tree/dagger-sample1

What is next?

So in the next articles, I will discuss how Dagger 2 DI can also be very useful if you are utilizing Android Build variants and how can we apply unit testing techniques for Dagger 2 applications.

iOS 9, Cordova, and jQuery mobile apps Integration tips

November 16, 2015 in Apache Cordova, iOS, JavaScript, jQuery Mobile

Unfortunately after having iOS 9 update, you may find your Cordova jQuery mobile app has the following problems:

  1. All of your app’s popups are suddenly closed after the first opening time!
  2. All your app’s back button are not working anymore!

The root cause of these problems is a bug in iOS9 UIWebView‘s window.location.hash as shown in the link below:
https://openradar.appspot.com/22186109

Fixes

In order to fix these issues, you can do the following workarounds.

Fixing the sudden closing pop-up

In order to fix this issue, make sure to set the data-history attribute of jQuery mobile popup to "false". An example of this is shown in the link below:
https://github.com/hazems/cordova-mega-app/blob/master/www/index.html

Fixing the broken back button

In order to fix this issue, make sure to disable the hash listening behaviour for jQuery mobile when the device is ready. You need to be careful when applying this fix, make sure that this fix will be applied for only iOS version 9 as shown in the code snippet below.

if (device.platform === "iOS"  && parseInt(device.version) === 9) {
  $.mobile.hashListeningEnabled=false;
} /* when the device is ready */

Checking a working Cordova jQuery mobile app in iOS 9

Finally, you can check a complete working Cordova jQuery mobile app in iOS 9. This app is one of the examples of the “JavaScript Mobile Application Development” book which can be reached at:
http://www.amazon.com/JavaScript-Native-Mobile-Apps-Development/dp/1783554177/
https://www.packtpub.com/web-development/javascript-native-mobile-apps-development

The example app uses Apache Cordova 5.3.3 and jQM 1.4.5. Enjoy!

Mobile and Cloud enablement in Nigeria

November 11, 2015 in Bluemix, mobile

nigerian-flag-waving
I just came back from a Mobile and Cloud enablement lectures that I conducted in Lagos, Nigeria 01-07 November 2015. The cloud event organization was good and there were about more than 25 attendees during the enablement sessions.

During these enablement sessions, I really enjoyed the passion of the attendees for creating their cloud apps powered by IBM Bluemix.
DevOps

I had the chance to show the attendees how IBM Bluemix can be a good fit for creating a plenty of applications on different runtimes (Java, NodeJS, Ruby, PHP and finally ASP.NET). I also had the chance to show the attendees the power of Bluemix DevOps to plan, develop, build, and deploy apps in the Cloud.
final

Deploying your existing StrongLoop application to IBM Bluemix

October 6, 2015 in Bluemix, Node.js

If you are not familiar with StrongLoop, you may need to check my previous post:
http://www.technicaladvices.com/2015/09/12/build-and-customize-your-first-api-with-strongloop-in-less-than-7-minutes/

Deploying StrongLoop applications in Bluemix is tricky and requires you to do some modifications to your application. This post discusses the steps required to deploy a StrongLoop application that uses MongoDB to IBM Bluemix.

1. Create your StrongLoop Application in Bluemix

Before deploying your local Strongloop application in IBM Bluemix, make sure to create a Bluemix “StrongLoop Arc” application from the Bluemix Boilerplates as shown below.
StrongLoop Arc App

Then create and bind a MongoDB Service to your created StrongLoop application in IBM Bluemix.
Bind MongoDB to Bluemix app

Then download the application starter code from "Start Coding" page, extract the zip file, and then get the manifest.yml file which is as follows in my case.

applications:
- path: .
  memory: 512M
  instances: 1
  domain: mybluemix.net
  name: iReport
  host: iReport
  disk_quota: 1024M
  services:
  - iReport-MongoDB

Copy the manifest.yml file to your local StrongLoop application’s directory.

2. Use VCAP_APP_HOST and VCAP_APP_PORT inside server.js file

In server.js file under the server directory, make sure to Use process.env.VCAP_APP_HOST and process.env.VCAP_APP_PORT as shown in the code below.

...
boot(app, __dirname, function(err) {
  if (err) throw err;
	
  //Use Bluemix host and port ...  
  var host = process.env.VCAP_APP_HOST || 'localhost';
  var port = process.env.VCAP_APP_PORT || 1337;
  
  app.set('host', host);
  app.set('port', port);  

  // start the server if `$ node server.js`
  if (require.main === module)
    app.start();
});

3. Use the “start” attribute in package.json

If you do not use the "start" attribute in your package.json file, you may face the following exception when pushing your application to IBM Bluemix.

[App/0]  ERR npm ERR! Linux 3.19.0-25-generic
[App/0]  ERR npm ERR! argv "/home/vcap/app/vendor/node/bin/node" "/home/vcap/app/vendor/node/bin/npm" "start"
[App/0]  ERR npm ERR! node v0.12.7
[App/0]  ERR npm ERR! npm  v2.11.3
[App/0]  ERR npm ERR! missing script: start
[App/0]  ERR npm ERR! 
[App/0]  ERR npm ERR! If you need help, you may report this error at:
[App/0]  ERR npm ERR!     <https://github.com/npm/npm/issues>
[App/0]  ERR npm ERR! Please include the following file with any support request:
[App/0]  ERR npm ERR!     /home/vcap/app/npm-debug.log
[DEA/14] ERR Instance (index 0) failed to start accepting connections

This is my package.json file which uses the "start" attribute as follows.

{
  "name": "iReport-Services",
  "version": "1.0.0",
  "scripts": {
    "pretest": "jshint .",
    "start": "node server/server.js"
  },
  "dependencies": {
    "compression": "^1.0.3",
    "cors": "^2.5.2",
    "loopback": "^2.22.0",
    "loopback-boot": "^2.6.5",
    "loopback-component-explorer": "^2.1.0",
    "loopback-connector-mongodb": "^1.13.0",
    "loopback-datasource-juggler": "^2.39.0",
    "serve-favicon": "^2.0.1"
  },
  "devDependencies": {
    "jshint": "^2.5.6"
  },
  "repository": {
    "type": "",
    "url": ""
  },
  "description": "iReport-Services"
}

4. Update datasources.json file under the application’s server directory

Under the server directory, there is a file called datasources.json which holds the application’s data source configurations, edit this file to point your application to the Bluemix MongoDB instead of your old MongoDB.

Below is my datasources.json file.

{
  ...
  ,
  "iReport-db": {
    "connector": "mongodb",
    "url": "mongodb://xxx"
  }
}

You can get the "url" attribute from the MongoDB Bluemix configuration as shown in the screenshot below.
Bluemix MongoDB

After doing the previous steps, you can finally, cf push [your local strongloop application] to IBM Bluemix,

These are all the steps you need to do in order to have your StrongLoop application up-and-running in Bluemix, Enjoy!

Build and customize your first API with StrongLoop in less than 7 minutes

September 12, 2015 in Node.js

The StrongLoop API Platform features the popular open source LoopBack framework. LoopBack enables you to quickly compose scalable APIs, runs on top of the Express web framework and conforms to the Swagger 2.0 specification.

In this video, I showed how to quickly build and customize a REST API powered by LoopBack. Some things to make sure that they are there before applying this video:

  1. The model object (Cafeteria) used in this API is persistent in MongoDB. So make sure to start MongoDB before applying this video steps.
  2. Make sure to create an account in https://strongloop.com/register/ because you will use this account to access the API Composer.
  3. Make sure to have Node.JS installed in your machine: https://nodejs.org/en/
  4. Install StrongLoop by executing the following command:
    $ npm install -g strongloop
  5. Know the purpose of the following commands:
    $ slc loopback
    

    This command creates a Node.js application using the LoopBack framework.

    $ slc arc
    

    This command runs StrongLoop Arc (which provides a GUI to define the app model), by default opening it in a web browser window.

  6. The last part of this video shows how to customize the Cafeteria RESTful API by implementing a new attribute status. The cafeteria status can be accessed using "GET /api/Cafeteria/status".

Enjoy watching the video:

Cordova jQM Plugin Integration with the IBM Mobile First Platform

August 29, 2015 in Apache Cordova, jQuery Mobile, Worklight

Cordova jQM npm plugin v0.1.6 is released yesterday with an important update which is the IBM Mobile First Platform integration as shown in the video below.

Now, you can quickly apply the plugin templates to your MFP Cordova apps.

[JavaScript Quiz #16] Smallest number of flights

August 15, 2015 in JavaScript, Quiz

Consider you have a set of places (CAI, FRA, MAD, NYC, SFO) and there are available flights between some of these destinations as shown below.

CAI -> FRA
FRA -> MAD
MAD -> NYC
CAI -> MAD
NYC -> SFO
FRA -> CAI
MAD -> FRA

Design and develop a JavaScript function that can get the shortest possible path from a destination X to destination Y if there is any.
.
.
.
.
.
.
.
.
.
.
.
.
.
In order to develop a JavaScript function which can get the shortest path between two destinations, first of all, we need to think about the proper data structure which can represent these places and the connections between them. If we think about it, we will find that these placed can be represented as nodes and the connections between these places can be represented as edges which is typically a Graph. We can represent this Graph as a 2D N X N array as shown below.

    CAI FRA MAD NYC SFO
CAI  0   1   1   0   0
FRA  1   0   1   0   0
MAD  0   1   0   1   0
NYC  0   0   0   0   1
SFO  0   0   0   0   0

The previous matrix can be translated to the following JavaScript code.

var mapping = {
    "CAI": 0,
    "FRA": 1,
    "MAD": 2,
    "NYC": 3,
    "SFO": 4
};

var routeGraph = 
[
    [0, 1, 1, 0, 0],
    [1, 0, 1, 0, 0],
    [0, 1, 0, 1, 0],
    [0, 0, 0, 0, 1],
    [0, 0, 0, 0, 0]    
];

After make the proper representation, we need to think about how to get the shortest path between any two nodes in this unweighted graph. Since this graph is unweighted, we can use directly BFS (Breath First Search) in order to get the shortest path. For more information about BFS, check: https://en.wikipedia.org/wiki/Breadth-first_search.

In order to implement BFS, there are some notes for our implementation below:

  1. We utilized the Queue data structure for storing the nodes in a first-in, first-out (FIFO) style, we explore the oldest unexplored nodes first. Thus our explorations radiate out slowly from the starting node, defining a breadth-first search.
  2. In order to keep track of the shortest path, we have a JavaScript map nodeParent object which stores the first visited parent of the current visited node.
  3. Finally, when the search finds the destination then we construct the final path from the nodeParent object and stores it in the finalPath array.

The code below shows our BFS implementation in order to get the shortest path between the start and destination nodes.

var ShortestPathFinder = function() {
}

ShortestPathFinder.find = function (start, destination) {
    var visited = {}; // A map containing all of the visited nodes ...
    var nodeParent = {}; // An map containing the node parents ...
    var queue = [start], i, found = false, finalPath = [], neighbours = [];    
    
    nodeParent[start] = null;
    
    var current = queue.shift();
    
    while ((neighbours = ShortestPathFinder.getNeighbours(current)) != null) {
    
        for (i = 0; i < neighbours.length; ++i) {
            
            // If we find the destination then exit these loops ...
            if (neighbours[i] == destination) {
                found = true;
                nodeParent[neighbours[i]] = current;
                break;
            }
        
            if (! visited[neighbours[i]]) {
                
                // Mark this node as "visited" ...
                visited[neighbours[i]] = true;
            
                // Add element to the queue ...
                queue.push(neighbours[i]);
                nodeParent[neighbours[i]] = current;
            }
        }
        
        if (queue.length == 0) {
            break;
        }
        
        current = queue.shift();
    }
    
    if (! found) {
        console.error("No path is found between " + start + " and " + destination);
        
        return null;
    }
    
    // Construct the final path from the node parent map ...
    current = destination;
    
    finalPath.push(destination);
    
    while (nodeParent[current] != start) {
        finalPath.push(nodeParent[current]);
        
        current = nodeParent[current];
    }
    
    finalPath.push(start);    
    
    return finalPath.reverse();
}

In order to get the neighbours of the current node, a simple function is implemented to get the neighbours from the routeGraph matrix as follows.

ShortestPathFinder.getNeighbours = function(current) {
    var currentIndex = mapping[current], i, result = [];
    
    for (i = 0; i < routeGraph[currentIndex].length; ++i) {
        if (routeGraph[currentIndex][i] == 1) {
            result.push(mapping.getKey(i));
        }
    }
    
    return result;
}

Finally, we can test our developed JavaScript function by having the following test cases.

console.log(ShortestPathFinder.find("CAI", "NYC"));
console.log(ShortestPathFinder.find("CAI", "SFO"));
console.log(ShortestPathFinder.find("FRA", "NYC"));
console.log(ShortestPathFinder.find("SFO", "CAI"));
console.log(ShortestPathFinder.find("MAD", "CAI"));

Below is the output of the console.

["CAI", "MAD", "NYC"]
["CAI", "MAD", "NYC", "SFO"]
["FRA", "MAD", "NYC"]
No path is found between SFO and CAI
null
["MAD", "FRA", "CAI"]

Attached below, the complete solution code for your reference, if you have comments or a better solution, feel free to comment below.

/*
CAI -> FRA
FRA -> MAD
MAD -> NYC
CAI -> MAD
NYC -> SFO
FRA -> CAI
MAD -> FRA

    CAI FRA MAD NYC SFO
CAI  0   1   1   0   0
FRA  1   0   1   0   0
MAD  0   1   0   1   0
NYC  0   0   0   0   1
SFO  0   0   0   0   0
*/

var mapping = {
    "CAI": 0,
    "FRA": 1,
    "MAD": 2,
    "NYC": 3,
    "SFO": 4
};

var routeGraph = 
[
    [0, 1, 1, 0, 0],
    [1, 0, 1, 0, 0],
    [0, 1, 0, 1, 0],
    [0, 0, 0, 0, 1],
    [0, 0, 0, 0, 0]    
];

Object.prototype.getKey = function(value){
  for(var key in this){
    if(this[key] == value){
      return key;
    }
  }
  return null;
};


var ShortestPathFinder = function() {
}

ShortestPathFinder.find = function (start, destination) {
    var visited = {}; // A map containing all of the visited nodes ...
    var nodeParent = {}; // An map containing the node parents ...
    var queue = [start], i, found = false, finalPath = [], neighbours = [];    
    
    nodeParent[start] = null;
    
    var current = queue.shift();
    
    while ((neighbours = ShortestPathFinder.getNeighbours(current)) != null) {
    
        for (i = 0; i < neighbours.length; ++i) {
            
            // If we find the destination then exit these loops ...
            if (neighbours[i] == destination) {
                found = true;
                nodeParent[neighbours[i]] = current;
                break;
            }
        
            if (! visited[neighbours[i]]) {
                
                // Mark this node as "visited" ...
                visited[neighbours[i]] = true;
            
                // Add element to the queue ...
                queue.push(neighbours[i]);
                nodeParent[neighbours[i]] = current;
            }
        }
        
        if (queue.length == 0) {
            break;
        }
        
        current = queue.shift();
    }
    
    if (! found) {
        console.error("No path is found between " + start + " and " + destination);
        
        return null;
    }
    
    // Construct the final path from the node parent map ...
    current = destination;
    
    finalPath.push(destination);
    
    while (nodeParent[current] != start) {
        finalPath.push(nodeParent[current]);
        
        current = nodeParent[current];
    }
    
    finalPath.push(start);    
    
    return finalPath.reverse();
}

ShortestPathFinder.getNeighbours = function(current) {
    var currentIndex = mapping[current], i, result = [];
    
    for (i = 0; i < routeGraph[currentIndex].length; ++i) {
        if (routeGraph[currentIndex][i] == 1) {
            result.push(mapping.getKey(i));
        }
    }
    
    return result;
}

console.log(ShortestPathFinder.find("CAI", "NYC"));
console.log(ShortestPathFinder.find("CAI", "SFO"));
console.log(ShortestPathFinder.find("FRA", "NYC"));
console.log(ShortestPathFinder.find("SFO", "CAI"));
console.log(ShortestPathFinder.find("MAD", "CAI"));
Skip to toolbar