MoSync is an open-source cross-platform mobile application development environment that makes it easy to develop apps for all major mobile platforms from a single code base.
MoSync provides a number of ways for creating user interfaces. You can choose one based on what your application requires and what you are most comfortable with. You can develop your MoSync applications with plain HTML/HTML5 UI or Native UI or Java based UI for older devices. Along with supporting multiple UI, MoSync also provides multiple libraries for implementing these UI.
This blog post discusses some of these methods, their pros and cons.
The Problem
When I started working with MoSync, I was working on a TMDB API based movie application. The target platforms were Android, iOS and Windows with native look and feel. You guessed it right! I had an option of using Native C++ library or Wormhole NativeUI JavaScript API or Widget C API.
The Native C++ library suffers the same problem as most of the UI libraries. It provides a number of useful classes, but you need to write C++ code to create your interfaces.
The MoSync Wormhole library provides a bridge between the HTML5/JavaScript and C++ layers of your application. Using the wormhole library it is possible to use HTML5 markup to create NativeUI interfaces. The HTML5 in this case is used more as XML markup, i.e. you create div tags for everything with some special data attributes to specify widget properties. MoSync creates a hidden WebView which parses the HTML5 markup, uses JavaScript to navigate the DOM and creates NativeUI widgets for each HTML5 element. I still couldn’t use this approach because:
- This approach is reported to be inefficient on some platforms e.g. Windows phone.
- The NativeUI widgets created this way are accessible via JavaScript just as a web page e.g. getElementById(), I would have had to write code to be able to access them from C++ code.
- The JavaScript-C++ bridge is not very intuitive. It just provides a way to expose functions and not objects.
- The life-cycle of widgets is out of control.
The Solution
In my case, the rest of the application was written in C++. All I wanted was to use some code-free markup to create interfaces dynamically at run time. What we required was:
- Ability to write some markup to define UI.
- Ability to load UI definition from multiple JSON files.
- Easy access to UI widgets from code.
- ove responsibility to create/destroy widgets to some low level class.
Similar methods are used by many frameworks and UI libraries e.g. MFC uses .rc resource files to define user interfaces, Qt uses .ui xml files. MoSync supports both XML and JSON parsing. Personally I am not a very big fan of XML so I went with JSON to define UI.
I wrote a class to dynamically create UI at run time from JSON files. The class handles the above scenarios and supports loading multiple JSON files. So, it is possible to define global properties in a separate file and keep UI for different screens in different files.
As for accessing the widgets easily, the class provides a getWidget() function, which takes the complete widget name as argument and returns the widget. Also, it maintains a map of name-widget pairs internally. If the widget already exists, it is returned otherwise the widget is created and returned. In case there are any child widgets, they are created as well and added to the widget map.
Regarding destroying any widget, the class provides a destroyWidget() function, which again takes complete name of a widget and destroys it. This function is used by another higher level class – ScreenManager. This class handles creating/displaying/hiding/destroying screens. When a screen gets lowered, it automatically gets destroyed to release any acquired resources.
Conclusion
MoSync is a very powerful framework to develop cross platform applications. Although it supports multiple UI solutions and libraries to implement them, there is still scope for making life easier for developers. The class I wrote works quite well for my requirements, but it can still be improved in both efficiency and functionality.