Monday, January 1, 2018

Building a website wrapper in Cordova

A friend of mine asked me to build an app for his company which has all its business logic implemented on a website. Besides me not being able to spend enough time to build native apps for Android and iOS for him, there was no API implemented anyway (website was all server-rendered). I decided to go with an approach that I already used for my previous company: enhance an existing website with native features using Apache Cordova.

Let's start with the easy part:

Wrapping a website with Cordova

That's easy! Create a new Cordova project and change config.xml as follows:

  • change src-attribute of content-tag to your website, e.g.
  • add a new line below content-tag: <allow-navigation href="*" />
Now... no wait, we're done! I told you it was easy. What you get now is an app you can install on your device and eventually release on app stores*!
To make it even more appealing, your app will automatically benefit from changes to your website, since it is basically just a camouflaged browser accessing your website. No need to worry about updating the app separately.

Add native features to your website

This is where it gets interesting: we can leverage Cordova to add access to native device features like GPS, camera, sensors, files and many more. You may also use it to better interact with the system. For example you could make use of a seamless Facebook login if the user has the app installed on his device.
  1. To do this, you have to first install the plugins you plan to use as per the documentation and build your project afterwards
  2. If everything went well you should be able to copy the folder located at platforms/android/app/src/main/assets/www and host it somewhere (e.g. where your website is hosted too)
  3. Next include a script-tag on your website to load the cordova.js-file located in this directory
    • Make sure to only load it when your website is being accessed from Cordova! For example, you could load your website with an app-specific query parameter and store a cookie based on that.
  4. The last step is to call the Cordova plugins you installed as per their documentation and make use of them!
    • Again you should only attempt to call those plugins if your website is being accessed via your app. You could use feature detection to achieve that, i.e. check if the global variable of a plugin exists.
Using this approach you are able to create a hybrid app which shares the same codebase with your website. I would not recommend to do this for big projects, but for small companies which can't afford (money and timewise) to build a full-blown native app.

So let's recap what we have now:
  • An app that is ready for release without investing too much time. I was able to pull this off in one weekend (I spent two thirds of the time on figuring out how to do this - you won't have to do that yourself)
  • Reuse current codebase of an existing website, but enhance it with access to native features, therefore providing a better user experience
Check out my other blog post for some reasons why you would want to keep your hands off of Cordova!

*Apple might reject your app at this stage. You might be able to workaround this by adding native features to your website as described above!

Lessons learned using Cordova in 2017

I would not refer to myself as an expert in Cordova, but I already had the pleasure to work with it (extensively) in a few occasions over the last few years, including but not limited to prototypes for weird would-be projects of friends of mine, production apps for my own company, plugins for products of a company and production apps for other companies. Sounds like a lot? Well, no - most of those projects were based on a technique to wrap an existing website in Cordova drastically reducing the amount of code that needed to be written from scratch. But I can tell you tales of suffering from those projects - because Cordova is not pleasant to use in most cases. But it gets the job done... eventually. I guess.

Here's a few of the things that I learned:

Most updates break something it a plugin, the build process or something else. If you're working with other developers it is crucial to use the same version of Cordova on all development machines! I should mention that this experience mostly comes from my projects being several months or years apart, which of course leads to breaking changes when updating from one major version to another. But that brings me to my next point:

Outdated plugins and documentation

There is a lot of very popular plugins that are simply no more maintained by the original author. The one that I had most problems with was phonegap-facebook-plugin (in retrospective I could have saved myself a lot of time by noticing the plugin still referring to "phonegap" rather than "cordova"). Thankfully there is a popular fork available which keeps maintaining the plugin, but that again is not compatible to the latest version of Cordova. Well, at least there is another fork for that which is a sign for how active the community is.
The same problem goes for documentation and the information available in general. While searching for a problem you are likely to dig up lots of articles from anno 2014. Not a problem per se, but reread the previous to paragraphs if you don't see why this is a problem for Cordova.

Weird bugs.

One more thing that almost cost me my sanity is that Cordova by default does not honor a website's viewport setting. An experienced web developer might have figured that out a lot faster, but it took me hours to understand why a website looked different when rendered in Cordova vs a browser. The solution was to use a plugin that was... well outdated and not compatible to the latest version of Cordova. :) Fortunately I was able to fix that easily.

I guess that's it for now. I was able to let the steam off! Please don't get me wrong: Cordova is great for some things, but I wish the whole developer experience would be more "consistent" in general.

Saturday, December 30, 2017

How to make yourself appear well organized during a job interview

I was tempted to name this post "One weird trick to make you look smart during a job interview" but I went for the non-clickbait version instead...

As part of my job I enjoy participating in job interviews with potential new developers every now and then. The interview is lead by my boss (very experienced in all things management) and I'm there to fill in the technical gaps. I saw both good and bad candidates and learned a lot about presenting yourself, but there is one particular thing that struck me during a recent interview: the applicant kept taking notes as we spoke. She continued to do so during the whole interview, for no obvious reason (we didn't assign any tasks and there was nothing she would need to remember).

After the interview, my boss asked me for my opinion on the applicant and then continued to offer his own opinion: "she seems very well organized". There was no other point in the conversation that would indicate her being well organized - it's the notes that made her appear like that.

So next time you have an interview be sure to take pen and paper with you - it might pay off. Bonus points for actually not taking serious notes but doodling instead! That might turn out really bad if you are asked to show your notes though. ;)

PS: This was all via Skype by the way, but this would work just as well during an on-site interview.

Sunday, April 30, 2017

Setting up Mac OS X in VirtualBox

Mac OS X is not meant to be run inside a VM. In fact, it even violates the EULA which you have definitely read. Anyway, if you were to follow a guide for running Mac inside VirtualBox (like this) you would end up with a perfectly fine VM. However, there are some caveats. First you would notice that the resolution is stuck at 1024x768. You could fix that by changing some internal settings of VirtualBox. Next, you wouldn't be able to connect USB devices to the virtual machine because you have to install the proprietary Extension Pack first, maybe like this.

Almost there, theoretically... Since VirtualBox doesn't provide Guest Additions for Mac, you won't be able to use things like Clipboard Sync and Shared Folders. That's a huge bummer, because it's a crucial feature if you plan to use Mac and your host system side-by-side (e.g. for development). To workaround this, you can take use of Mac's built-in Screen Sharing (VNC) and File Sharing (SMB) features. But first you have to create a second network adapter in your virtual machine which acts as a host-only adapter (don't forget to create the host-only network first). This way the guest machine (Mac OS X) has access to the internet via the NAT adapter, but the host machine is still able to easily access services running on the guest via the host-only adapter. Nice!

Now on to configuring VNC and SMB. Open System Preferences in Mac OS X and go to "Sharing". Enable both "File Sharing" and "Screen Sharing". For the former you'll have to enable user authentication by clicking "Options" and check your username under "Windows File Sharing". Nothing else to do for "Screen Sharing".

You should be able to connect to the VM using your favorite VNC client now. The IP address of the Mac machine is The same goes for SMB.

If you intend to use this setup on a daily basis, I'd recommend to start the virtual machine in headless mode, either via GUI (right-click the machine, "Start", "Headless") or via command line (VBoxManage startvm "MACHINE_NAME" --type headless). If your hardware has lots of spare resources, I'd recommend to put the VM into autostart so that you can simply connect to it via VNC whenever you need it.

Update: Well, almost. If you're using a keyboard layout other than US, you'll have lots of problems with "special characters" (-, etc). Lots of people have the same problem, but I wasn't able to fix that. Just use VMware instead.

Saturday, April 22, 2017

Putting my node.js-toolbelt aside...

So I'm about to head into a new challenge, which does not include much - if any - node.js development. Therefore I'm trying to conserve as much of my current knowledge as possible for others and potentially a future me (hey tom! :)).


Ubuntu is the one and only operating system to use if you ask me, but I'm sure you can get stuff done with any of the operating systems nowadays. As an editor I love Atom for its simplicity, ecosystem and performance (see: how to install Atom on Ubuntu). Chrome is the way to go for its incredible developer tools of course.

Installing npm properly is surprisingly hard because of file permissions. If you don't follow the steps below you'll have to install global dependencies as root (and also some local dependencies if I remember correctly?): 

Frequently used modules (server-side)

When creating a new project I see myself using the same modules over and over again:
  • moment: I haven't touched a Date-object in a year or so...
  • express: it took me months to finally give it a try, but it really makes things a lot easier!
  • Q: I'm trying to use native Promises, but for advanced promise-handling (e.g. wait for several promises to finish) this library is still the way to go
  • bunyan: must-have if you're serious about your application. Crank up your logging for easy error-detection. Also incredibly helpful if you're using multithreading (cluster)
  • request-promise: for requests...
  • standard: You're doing it wrong if you're not using a linter. It took me way too long to figure this out, since I was too lazy to figure out the correct rules, but that is exactly the point of standardjs: just use a fairly standard ruleset across all projects and get coding!
Some more notes on standardjs: I hate single quotes and I was absolutely shocked when I saw that they do not use semicolons. However, it really does not matter at all. You'll get used to it, I promise. It's not religion, we just want to get stuff done...
There are also Atom-plugins to show and automatically "fix" style violations. That way I didn't even care if I accidentally used double quotes or a semicolon out of habit, because the linter fixed it for me.

This is usually enough to get started. Of course, depending on the project you might include a few more related modules, but I generally try to keep the number of dependencies low. Most importantly, I try to avoid frameworks like lodash, etc because they're usually used like a blackbox that magically does things without knowing about its performance or security implications. That's why it took me so long to finally use express, but in that case it saves you from lots of stupid boilerplate-code (request routing) without being an unnecessarily thick layer.

Someone has to be able to use the application after all (aka client-side)

I'm really not a designer, and would never dare to call myself a Frontend Developer. I can get decent things done, but using CSS is like black magic for me, which is why I'm still using br-tags instead of setting margin on elements...

Anyway, I recently started using Material Design Web Components for all webapps I'm working on! The documentation is far from perfect, which makes getting started really hard as a non-experienced Web Developer. In fact it took me three tries (over the span of a few months) until I finally understood how to properly use it and felt comfortable to use it in my own projects. The thing that was not obvious to me from the beginning was that there is additional documentation for each component inside the respective folder (doh!). So after checking out the Getting Started Guide make sure to look at a component's documentation.

For small webapps which are only used internally inside a company it's usually fine to include each Javascript- and CSS-file in your HTML and call it a day. If the project gets any bigger and you care about the nerves of the poor guy who has to maintain your project after you quit, you should give webpack a try. I love that it allows you to draw dependencies between Javascript, CSS and even HTML if need be. Moreover, you can start using npm for installing frontend dependencies, which is a huge step forward for everyone involved. Again, the documentation is really hard to follow for non-experienced developers and it took me quite some time to figure out the basic setup I needed. I recommend you to take a look at the obvious "Getting Started" for Javascript and "Code Splitting CSS" for CSS.


It's still hard for me to put the way I create applications into words, but I share a lot of articles related to that on Google+. Here's a few things to know:
  • classes ending with "Bridge" are generally wrappers for some kind of logic, but nothing that involves UI. TimeBridge, SqlBridge, etc you get the idea.
  • classes ending with "Component" wrap a UI component and all its logic.
Without webpack, every class is wrapped in an IIFE in order to not pollute the global namespace by exposing internal methods and variables. With webpack the class is simply exported using standard syntax.

That's the most important things to know when reading my code. There are some more subtle things which I won't go into detail now (instead, take a look at the articles posted on Google+).


I love Google Cloud, and I enjoyed working with AppEngine a year ago. But for node.js development Heroku is still the way to go if you ask me. The deployment process via git is too good to be true!
(Please note that I've only used Heroku for single-instance hobby projects. For anything serious I'd probably not recommend Heroku but a multi-instance setup with a loadbalancer and autoscaler)

Putting it all together

You can find a sample project which uses all of the above on GitHub: either with webpack or without it.

The apps are hosted here (with webpack) and here (without webpack) for demonstration purposes.