Lessons Learned on Writing Apps with NativeScript VueJS

#11— An overview on How to Build Native Apps with NativeScript VueJS

After learning how to taste wine 🍷, I decided to follow my second year of the Learning Lab challenge, by taking 1 month to learn how to build native apps with NativeScript VueJS. You will see in this post how to do the same and quickly build native apps!

As you probably know there are different ways to build mobile apps:

  • Native — it uses Java or Kotlin for Android and Objective-C or Swift for iOS; this is the best way but it takes time (you basically have to do the same app twice) and requires good skills for developing in both platforms.
  • Hybrid (with Webview) — it uses web languages (HTML, CSS, JavaScript) along with some plugins written in native languages; basically, you create a website inside a native app which has usually bad performances but saves time as you can develop only one app for both Android and iOS (and even Windows).
  • Hybrid (without Webview) — it uses other languages that compile into native code without webview, there are many solutions such as NativeScript, React Native or Xamarin; it brings as good performances as native, and uses only one code for both platforms, it requires fewer skills (only one language) and less time!

As a web developer, I already tried hybrid apps using Ionic and Intel XDK. Even though it’s very easy, you can see that these apps lack reactivity, especially with old devices. The app can be quickly killed by the OS by lack of memory.

That is why I decided to learn hybrid without webview and specifically NativeScript. They recently released a plugin called NativeScript VueJS that lets you code your views using VueJS framework instead of Angular or Vanilla JS.

Note that there are a few solutions to code Native apps with Vue:

  • Weex — Built by Alibaba, the problem is that the community is only Chinese and some of the documentation is not translated into English.
  • Vue Native — It is basically a wrapper of React Native, which is pretty new and that is why the community is still small.
  • NativeScript VueJS — Even though the VueJS plugin is quite new, it takes advantage of NativeScript which is stable, well tested and with a big community.

Let’s dive into it 🧐!

Learning preparation

This learning preparation follows the Learning Lab methodology.

  1. Finding a mentor
    I didn’t spend enough time to look for a mentor 😌. Nevertheless, I joined the slack of the NativeScript community. This community is pretty welcoming and answers any kind of questions. But don’t annoy them before googling your problems.
  2. Defining the scope of the topic
    The scope of this topic is knowing how to start coding an app, how to build it, and how to deploy it. Also, I want to know what are the limitations of NativeScript VueJS to know in the future when I should use it and when I should not.
  3. Choosing a learning resource
    The learning resource was pretty obvious for me, the documentation, moreover because the VueJS extension for NativeScript is pretty new, there was no other learning resources. Nevertheless, there is a Coursera course about NativeScript available, but it uses Angular instead of VueJS.
    Here is the link for NativeScript VueJS: https://nativescript-vue.org/en/docs/introduction/
  4. Defining a project
    I originally wanted to build 3 apps but at the end, I had to focus on one app:
    - An app that provides an infinite newsfeed of trending GitHub repositories from different sources

What is NativeScript VueJS

Before describing how to build an app with VueJS let’s have an overview of how it works. How it can be native with JavaScript, and the tooling around.

NativeScript

This is how NativeScript works under the hood!

Source: https://docs.nativescript.org/core-concepts/technical-overview

Basically, the NativeScript Runtimes converts the UI into Native UI for the device and it runs the JavaScript codes, like NodeJS, which means you can load as many NPM packages as you need as long as they are not made for web frontend, basically libraries that need to access the DOM through the web browser cannot work with NativeScript!

VueJS & documentation

As you can see in the previous graph, NativeScript works with JavaScript (Vanilla and XML for templating), Angular or VueJS. It’s only a matter of taste, I like VueJS because I find it easy to read and write so I went for it 😀.

The only problem is that because NativeScript VueJS support is pretty recent, it’s hard to find examples and tutorials about it. So when you don’t find anything for VueJS you should just look for NativeScript with Angular (or Vanilla) and think a bit to adapt the code. It’s not that hard but you should be aware of it!

Utilities & Components

There are a few utilities and components:

  • Routing — Vue Router is not yet supported, so the routing is done manually in each view.
  • Layouts — This is what defines the structure of your components, if you know CSS, you will understand it pretty fast: AbsoluteLayout, FlexboxLayout, GridLayout, …
  • Components — Every UI element, action bar, buttons, text fields, images…

You can see the full list in the menu on the left of this page:

I recommend to quickly have a look at all of them before starting your app, just to know what you can do.

Regarding the components, each of them will be translated to a Native component, for example, the <ListView></ListView> will become an android.widget.ListViewin Android and a UITableView in iOS. It is described at the end of the description of every component. For example here: https://nativescript-vue.org/en/docs/elements/components/list-view/#native-component

You can do a lot of thing by default with NativeScript such as persisting data into some little database or checking the connectivity, but some other APIs are not there by default.

But luckily there is a market with about 1000 plugins (when I wrote this article): https://market.nativescript.org/ 👍

You can find there, for example, a plugin to access contacts, to send messages, to connect with firebase or just to have a pull to refresh ready made! Most of the time the documentation is made for Angular or VanillaJS with XML but it is pretty the same to make it work with VueJS.

NativeScript Command Line Interface

Last but not least, NativeScript provides a command line interface that lets you develop and run your code with an almost live update in your device/simulator, debug your code with VueJS debug tools and deploy for production! Also thanks to VueJS CLI you can start your project very fast 👨🏽‍💻

NativeScript CLI and VueJS CLI are as easy as pressing “any” key

Let’s build the app

Before building the apps, I first tried the official tutorial. This tutorial covers the basics concept by building a To do app. The good news is that you don’t need to install anything to do it, it can be done fully online thanks to the NativeScript Playground: https://nativescript-vue.org/en/docs/getting-started/playground-tutorial/

Once ready here is the process I followed to build this GitHub news app:

  1. Defining the goal of the app and the basic UX with wireframes.
  2. Listing and checking the plugins I would need to build it to know if it’s feasible.
  3. Defining the architecture.
  4. Implementing the services to gather data from APIs.
  5. Implementing the Vuex Store, constants, and actions.
  6. Implementing the Vues and connect them to the store.
  7. Implementing loading states and error states.
  8. Styling.
  9. Adding platform-specific code.
  10. Deploying.

We will quickly go through the most important steps, and describe them with examples.

Goal

The goal is to build an app to explore and discover GitHub repositories (with an infinite newsfeed) from different sources: GitHub trending, Hacker News and Reddit. I decided to call it GitNews!

It will be composed of 2 main views:

  • Newsfeed of repositories— with a pull to refresh and infinite scroll
  • Preview of readme—with a share function and open in browser button

I also added later one About view, and an error view when there is no network connectivity.

Plugins and APIs

I had two kinds of needs for plugins and APIs: backend and frontend. I checked for each the feasibility.

For the frontend:

For the backend:

  • An endpoint to get GitHub trendings
  • An endpoint to get HackerNews last results
  • An endpoint to get Reddit last results

As you could read all my requirements can be managed either with NativeScript APIs, by a plugin from the market or just by npm packages. As concern the backend I decided to call directly all the endpoints and parse/treat the results from the device instead of building my own backend.

Architecture & file structure

I recently wrote an article about how to structure a VueJS project 👍. I basically followed it and included the NativeScript files (specific assets and config files for Android and iOS).

Here is the structure of my GitNews app:

.
├── App_Resources
│ ├── Android
│ │ ├── app.gradle
│ │ ├── google-services.json
│ │ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ └── ...
│ └── iOS
│ ├── Assets.xcassets
│ │ └── ...
│ ├── GoogleService-Info.plist
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── build.xcconfig
├── app.scss
├── assets
│ └── ...
├── components
│ ├── NewsItem.vue
│ └── NewsLoading.vue
├── fonts
├── main.js
├── package.json
├── services
│ ├── fetchGitnews.js
│ ├── getColor.js
│ └── getReadme.js
├── store
│ ├── index.js
│ ├── modules
│ │ ├── news.js
│ │ └── readme.js
│ └── mutation-types.js
└── views
├── About.vue
├── News.vue
├── NoNetwork.vue
└── Preview.vue

A few details about these folders (very similar to how to structure a VueJS project) :

  • App_Resource — Contains all the platform config and related files (AndroidManifest.xml, Info.plist), and platform-specific assets (such as icons).
  • assets — I put there the images displayed in the views that are not the icons of the action bar.
  • components — All the components of the projects that imported in the main views.
  • services — To make the code easier to read I put the “backend part” into services. Basically, the functions that retrieve the news from the different APIs, and the one that converts the markdown to HTML.
  • store— The Vuex constants in mutation-type.js, the Vuex modules in the subfolder modules (which are then loaded in the index.js). The actions of the Vuex modules call the services and commit the results.
  • utils (optional) — Functions that I use in some components, such as regex value testing, constants or filters.
  • views — The main views of the app, in my case News (the newsfeed), Preview (of the readme), NoNetwork, and About.

Components

The power of NativeScript (and probably react native) is the component-based architecture 💪. It forces you to use composition instead of inheritance. Every native item is wrapped into a component. So building an app becomes similar to play Lego, assembling blocks (that you can reuse easily from an app to another).

You can see above a simplified version for better readability of the News vue connected to the Vuex store. The code is pretty simple.

When loaded, the loaded() method is triggered and calls the updateList() methods that check the network connectivity (and display the error page if there is none) and then retrieve the news from the APIs.

The NativeScript component <ListView/> which is wrapped into the <PullToRefresh/> component (coming from the plugin market) makes a loop of the news that has been retrieved and that are in the Vuex store. The news are displayed by the component <NewsItem/> that I created myself.

A method called onItemTap() is passed to the <ListView/>and is triggered when the user taps into an item of it. It will then load the Preview view!

The power of Vuex

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion. 
- Source: https://vuex.vuejs.org/

Vuex is similar to Flux / Redux, it handles the state and centralizes it within the app. Working with Vuex for an app is just very powerful. You can see how it works in the figure below!

Source: https://github.com/connor11528/vuex-shopping-cart

By implementing first your state architecture with the getters and then the actions and the mutations, you’ve done 80% of the core of the app. Then you just need to build your components and connect them to the actions, and getters to it and that’s it 🙌!

In the case of GitNews, the initial state looks more or less like this:

Then when the news.retrieve() action is triggered, the API will be called by the previousupdateList() method, the news.loading state will be true, the API will be called asynchronously, and the result will be passed to news.retrieved. Then the magic happens and the <ListView/> will show the news automatically! That’s the power of Vuex 👏!!

Platform-specific code

I developed the app on Android and I had to do some actions that are specific to iOS or Android (to color the status bar of Android for example).

So this is pretty easy, there is no need to update two code bases!

I faced some problems, the ListView was working very well on Android and it was dynamically resizing each item of the list, whereas in iOS I had some troubles. I had to set a static height for each item.

Styling

If you are familiar with CSS, styling will be very easy for you! It’s basically a limited / constrained version of CSS (the classes will just be converted to native code that’s why it’s a bit limited). You can see it in the following code example.

This style will look like this:

As easy as CSS right?

You can find in this page the full specifications about what you can do in CSS with NativeScript: https://docs.nativescript.org/ui/styling

Deployment

Deployment is also very easy, you need to add your icons, splash screen and then just type a command line! Here is a full tutorial: https://www.nativescript.org/blog/steps-to-publish-your-nativescript-app-to-the-app-stores

Important: in order to build or run for NativeScript VueJS you need to add the --bundle flat to the commands. It is not specified on this article written for NativeScript (Angular or JavaScript).

Also, after building the app I found an amazing GUI tool to help you update the settings of your app, add icons, build and even deploy iOS and Android apps from your computer (no matter if you are using windows, mac or linux)! It is called NativeScript Sidekick, it’s pretty amazing and allows cloud build. Note that when I wrote this article the publish to AppStore function was not working but there is an open issue in the NativeScript Sidekick Github repository, so it will probably fixed at some point!

The final result 🚀

Here is the final result of the app. It is available on Android and iOS. It took me about 5 days of work to build this app.

iOS (on the left) and Android (on the right)

Pros and cons of NativeScript VueJS

Using NativeScript VueJS was a very pleasant experience, I was able to build two apps very quickly (I will share the second as soon as it is ready). I really enjoyed it and I fully recommend it to VueJS users who want to develop mobile apps!

Pros 🙂

  • Real native experience.
  • Cross-platform without maintaining two code bases.
  • Easy to write using VueJS and CSS.
  • A lot of plugins
  • A good slack community.
  • A lot of examples and tutorials online (for NativeScript with Angular).
  • The power of the Component based architecture.
  • The pleasure of having a centralized state with Vuex.
  • The speed of development.
  • Cloud build (for iOS and Android) with NativeScript Sidekick

Cons 🙁

  • I wanted to do an animation but I was a bit limited, I guess I could have done it with native code.
  • The debugger didn’t work very well for me.
  • Most of the examples and plugin documentations are made for NativeScript with Angular, but it is not too complicated to “translate”.
  • Building an app is more work than building a website (because of the native components limitations), especially if you write it for two platforms.
  • When you write, try to test in both platforms frequently (I wrote first my code for Android and then make some fixes for iOS at the end).
  • Deployment to the AppStore is pretty hard if you don’t own a Mac book nor an iPhone (even though the cloud build makes it feasible, along with App uploader).

If you liked this post, please click the clap 👏button below a few times to show your support! Also, feel free to comment and give any kind of feedback. Don’t forget to follow me!