Using the hybrid over a native approach is more challenging but can be advantageous.
Target group
You have an idea for an application and decided to do it yourself, either alone or with a small group of people and your app development is not organized professionally. Then this article fits perfect for you. The context above is exactly the situation in which I have implemented a native ios app and afterwards a hybrid cordova app. Knowing this context and the following article you might be able to better judge the feasibility of implementing a hybrid app yourself.
Motivation
At some point on your way to your own software product you will face the decision on how to deliver the software to your customers. I would call this one of the very fundamental decisions during a software project that can’t be easily changed afterwards - at least it would cause remarkable effort and costs later on. Therefore aspects like the following should be thoroughly thought threw before going in the one or the other direction:
- is the software used in a mobile scenario?
- is the support of different operating systems and devices needed and how should this be achieved?
- are central services or storage of data needed?
- does the software need device specific functions?
- is (constant) internet connection required?
I have answered these and more questions for two of my software development projects.
| For a tiny tool the DSTimeK, used in the context of Scrum, the decision was made to deliver it as a mobile native ios application. See here the blog which summarizes the learning. |
|
With the experiences of the first project and answering the same question catalogue for FlAuMoQ (learning software used in the context of chemistry) the decision was made to deliver an hybrid application which runs locally on mobile devices. See here the blog with more information on that decision. |
This article takes a close look on the hybrid application approach used for FlAuMoQ and in the end reflects if it was the right approach. I will not talk about general (and abstract) differences. It uses concrete requirements and explains the options you have for implementing them. Basically you can follow parts of the journey to build an hybrid application facing different challenges.
Technical components used in FlAuMoQ
Based on the decision to use the hybrid cordova approach the components below are used.
In general and independent of the target delivery platform:
- using the open source library openui5-runtime-mobile-1.24.6 which is based on HTML5 and Java Script.
As a side comment: for the app it was as well decided to use openUI5, but generally any other library like bootstrap could take over its part. The openUI5 library is intended to be run in the web browser, but also could be run hybrid (see here). - NetBeans as development environment
- these artifacts are executable in any web browser
For iOS:
- framework: cordova -v: 5.1.1 with cordova platform version ios: 3.8.0
- XCode as development environment
- device test on iPhone 5s with ios Version 8.4.1
For Android:
- framework: cordova -v: 4.3.0 with cordova platform version android 3.7.1
- Android Developer Studio as development environment
- device test on Samsung Galaxy S2 with Android Version 4.1.2
For Windows:
- framework: cordova -v: 4.3.0 with cordova platform version windows wp8
- Windows Visual Studio as development environment
- device test on Windows Lumia 640 with Windows Phone 8.1 Update 2
Depending on the platform different further cordova plugins have been used. Below, pictures of real devices with FlAuMoQ running on them.
Challenges during hybrid app development
The hybrid app development starts as usual. With the library (in my case openUI5) you choose as well your development and runtime environment. The library offers a special set of features with which you can realize your requirements. After implementing and testing the app in the web browser the artifacts are build with the cordova framework to make them executable on the different devices. The implementation process using the combination of the mentioned technical components is more iterative compared to native development. Just because of the indirection with using a framework. Along this way different challenges have to be overcome.
Freedom of choice vs freedom from choice
The following list shows the different options you have for fulfilling the requirement of sending emails:
- The obvious way to handle this requirement is to use the library you have chosen for your app. For sending emails openUI5 has the method...
sap.m.URLHelper.triggerEmail(sEmail?, sSubject?, sBody?, sCC?, sBCC?)
...(check the API reference here). Using this method in the web browser opens the operating system email client. After building the application on android it turned out, already in the android emulator, that triggerEmail is not working. Sometimes this is only a strong indication, but does not necessarily mean that is doesn't work on the device itself. But also on the device with the given components and their versions it didn't succeed.
At this point already the idea matured that for sharing there is more than email and that sharing via cordova methods might be advantageous.
- The next way sending email can be achieved are the "exits" of the library. In openUI5 (other libraries have this as well) there is an HTML container in which HTML like this...
<a href="mailto:me@me.com">email me here!<a>
...can be passed. Also, there is the chance to code this directly on Java Script level with...
window.open('mailto: me@me.com?subject=subject&body=body');
.... Both are not interpreted on android emulator.
- Cordova offers access to device specific functions by the usage of its core plugins (see here). Examples for plugins are "Device orientation", "Camera" or "Contacts". Unfortunately sending emails is not part of that. The custom plugin de.appplant.cordova.plugin.email-composer has helped out. With calling the following code on the android device...
cordova.plugins.email.open({ subject: sEmailTitle, body: sEmailText});
... this is shown, which overachieved the requirement:
- Now, one could think that the requirement is fulfilled but tests have to be executed as well on all other supported platforms that are part of the delivery. On the ios device the custom plugin is not working, since it was mainly build for android. Because of that depending on the platform different email share methods are called. In case of ios triggerEmail is working on the device and shows this:
It doesn't show such a nice Open With Dialogue but the requirement for sending emails is met.
In the end this meant that depending on the device different calls have to be made. Also, here there are different ways to go. It can be achieved easily via calls like this...
if ( sap.ui.Device.os.name === sap.ui.Device.os.OS.ANDROID ) { ... do this ... }
... directly on level of the library.
Another example of iterating through the different options is the requirement open an URL in a new window. The challenge here was that most of the calls ended up in "InAppBrowsing" which is not the desired behavior. The app should stay open if supplementary information like FAQs are opened by the user. To make a long story short, these are working:
- in the web browser:
sap.m.URLHelper.redirect(url, true);
- on the android device:
navigator.app.loadUrl(url, {openExternal: true});
A core cordova plugin function that is supported only by the android platform.
- on the ios device:
window.open(url, "_system");
A Java Script Standard.
- on the windows device:
window.open(url, "_system");
The difference to native development is that (e.g. with using ios only) you don't have that many choices and might not have alternatives when ios is not supporting something. At the same time it can happen that a native development environment offers more ways to e.g. send an email or opening an URL.
So I would end up with: hybrid leaves you with the freedom of choice on different levels of the used components and probably more ways to solve a requirement. It adds complexity which must be handled.
Debugging & Testing
Using the hybrid approach makes debugging and testing necessary on all levels. First debugging and testing of the library in the chrome web browser, using the chrome developer tools and. For android - then in the android emulator and later on the android device doing Java Script debugging which is possible with chrome and chrome://inspect or weinre (see here). On windows and ios it's not much different.
Doing the same with a native application is a bit easier, but both ways are fine.
A big advantage using hybrid is that third party testing of the core application is a lot easier. For doing tests the artifacts e.g. *.app for ios have to be accessible to testers. The testers of natively developed applications need a user to be able to download the artifacts from the stores, the artifacts need to have the correct signature (certificates/provisioning file), their devices are registered as test device and so on. The hybrid way of testing is just to put the web sources on a web server and send around an URL to all testers. The disadvantage of this is that only the core (web) application can be tested. Since the device dependent part and interaction with the device for FlAuMoQ was not that much, this hasn't been a problem.
Dealing with complexity
Due to the freedom of choice, debugging and testing and all the effort comes along with this, I (as a one-man-show handling all the IT part of the project) sometimes reduced the scope to the minimum which was required. Below you see an overview of the screens built for FlAuMoQ. Since every cordova or device specific detour means additional effort when adding another platform and device testing, the whole displayed functionality is covered with the core web application.
Sometimes knowing the sheer complexity of a requirement lead to just not try to do it. An example here would be a complex logic of adverts integration. When implementing the ios DSTimeK the following logic has been applied. When the app is opened an interstitial advert is opened and a banner is always shown below the functionality. When the user clicks on a "special temporary free functionality button", another adverts is shown and in the end the adverts are removed for 4 hours. This meant doing the complex choreography of sending and validating requests with the apple store, saving a timer and dynamically show the adverts or not. Not talking about platform specific differences.
For hybrid doing the same was just to challenging because of which I ended up just showing a simple banner of google adverts below the functionality.
Main message here: as an non expert hybrid cordova programmer you tend to leave stuff out just because it’s not that simple and intuitive to program and means high effort.
Rendering or WYSIWYG
In the app at some point there is a selection in a dropdown box used. The used control on the level of the library is called sap.m.Select. When showing the control in the web browser or with using cordova and platform windows it opens as a small frame covering only parts of the window.
When cordova is interpreting the control and running it on an android or ios device the control is covering the whole screen when opened. This is the behavior which I experienced at a couple of other places as well e.g. using the SplitApp control - which also takes the full screen even I configured it to slide in/out with a fix width.
The hybrid approach using frameworks adds logic on how to render platform independent controls on the corresponding device. The rendering might be different to the one specified originally. When using native development there are native controls which have only one renderer, e.g. the ios environment, and therefore there is only one way they look. What you see (once) is what you get. Furthermore natively, the look & feel is a bit smoother.
Program once, run anywhere - Example: Integration of analytics
Integration of google analytics is very easy to enable for a web site or on ios. Just by calling the Java Script "www.google-analytics.com/analytics.js" and then at different places (mostly during navigation) calling "ga_storage._trackPageview('/start);" this is comparable easy doing it hybrid. The difference is that for hybrid you have to do it once and it is working on all devices. See the first results showing the page access during the app testing period:
Of course, this advantage of re-use is not only valid for the integration of google analytics, but for the whole implementation. But this is worthwhile mentioning since it impressed me a lot that it was working out of the box without any device specific detours.
Additional delivery channel options
And, there is another advantage by having a such a re-usable web application . The app, at least the core functionality could in the end also be offered just on a web page, even if this wasn't intended right from the start. Just put the sources on a web page to be displayed on any web browser. Of course then, to reach (at least a bit) feature parity with the app stores, with an own payment process and needed security and authentication process coming along.
The same is valid regards to the effort of adding more platforms. At the very end I decided to add windows phone 8 to the delivery. The effort in regards preparing the app artifacts for windows meant doing the following:
- learn to handle a new development environment
- adding icons for all required sizes
- testing on the app, especially the device dependent parts
- changing the cordova configuration files to use the new icons and some windows specific settings
When you now think that for example amazon fire would get interesting as a platform or others you could just add it later, with only a minimum effort.
In Conclusion - LEARNINGS AFTER BOTH PROJECTS
With having the knowledge of both approaches I wouldn't program the DSTimeK again natively. In general, the less complex a software from its functionality is, the more probable the implementation as a non-native application gets.
The thing which makes it complicated is, that you don't know the scope and all the requirements to the app from the very beginning. The importance of animations, performance, multiple platforms, high expectations to graphics, smooth usability, using device functions (Camera, GPS, Animations, store data …), interact with app stores, using (constant) internet connection, maintenance effort and all this general native vs hybrid qualitities play a big role here.
Since for FlAuMoQ the complexity was relatively low, the approach turned out to be better than the native one. The app could even be run completely as an web app or as an hybrid app using native web containers - with no interaction with the device. In these both alternative cases the app would run on the server and would be rendered in the mobile browser. The used hybrid approach allows using the app offline, having the library embedded in cordova locally on the device (which increased performance) and can use device functions which made it better or more complete then the alternatives web app or as an hybrid app using native web containers.
If I wouldn't care for time, money and resources, I would build natively, just because the rendering is very accurate, feels smoother during usage and offers more individual controls. But as this is not the case I would recommend anybody in my context to also go for the platform independent programming.
Other Resources
- openUI5 - Build enterprise-ready web applications
- yaazone.com/software/flaumoq - DOWNLOAD page for "Anion Cation Finder (FlAuMoQ) - guides you step by step through your inorganic qualitative ion analysis" for different platforms (ios, android and windows)
- yaazone.com/software/daily-scrum-time-keeper - DOWNLOAD page for "Daily Scrum Time Keeper (DSTimeK) - helps you stick to your allotted time for speaking" for ios only