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 (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.
A NativeScript plugin for building truly native applications using Vue.jsnativescript-vue.org
Let’s dive into it 🧐!
This learning preparation follows the Learning Lab methodology.
- 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.
- 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.
- 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/
- 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
This is how NativeScript works under the hood!
VueJS & documentation
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:
A NativeScript plugin for building truly native applications using Vue.jsnativescript-vue.org
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 👨🏽💻
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:
- Defining the goal of the app and the basic UX with wireframes.
- Listing and checking the plugins I would need to build it to know if it’s feasible.
- Defining the architecture.
- Implementing the services to gather data from APIs.
- Implementing the Vuex Store, constants, and actions.
- Implementing the Vues and connect them to the store.
- Implementing loading states and error states.
- Adding platform-specific code.
We will quickly go through the most important steps, and describe them with examples.
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:
- Infinite-scroll — It is handled directly natively with the ListView
- Pull to refresh — I had to get a plugin from the NativeScript market
- Access the connectivity to display an error — There are methods from NativeScript to access it
- Convert Markdown data to HTML to display it — I found a NodeJS package to do it!
- Firebase — For the analytics
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).
The perfect Vue.js folder structure and component architecture with smart and dumb componentsitnext.io
Here is the structure of my GitNews app:
│ ├── Android
│ │ ├── app.gradle
│ │ ├── google-services.json
│ │ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ └── ...
│ └── iOS
│ ├── Assets.xcassets
│ │ └── ...
│ ├── GoogleService-Info.plist
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── build.xcconfig
│ └── ...
│ ├── NewsItem.vue
│ └── NewsLoading.vue
│ ├── fetchGitnews.js
│ ├── getColor.js
│ └── getReadme.js
│ ├── index.js
│ ├── modules
│ │ ├── news.js
│ │ └── readme.js
│ └── mutation-types.js
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.
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!
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 previous
updateList() 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 👏!!
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.
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:
You can find in this page the full specifications about what you can do in CSS with NativeScript: https://docs.nativescript.org/ui/styling
How to use Cascading Style Sheets (CSS) in NativeScript to change the appearance of GUI elements. The article describes…docs.nativescript.org
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
This article is a straight-to-the-point checklist for deploying a NativeScript-built app to the iOS App Store and…www.nativescript.org
Important: in order to build or run for NativeScript VueJS you need to add the
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!
Use Sidekick's rich starter templates, verified plugins, cloud builds, and debugging all while using your own preferred…www.nativescript.orgNo
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.
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!
- 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
- 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).