Category Archives: NativeScript

Running NativeScript 5.4 and NativeScript 6.0 side-by-side.

For those who have been hiding in the hills for a while; you may not have noticed that the cool news for NativeScript is that we have a new version that has been coming for a while. 6.0 was officially released today!

Well 6.0 has been release; and there are a lot of things to like in 6.0, but if 6.0 doesn't work for your app; you might still need to run 5.4 to get your work done. Unfortunately, the NativeScript team did not listen to my advice and release a 5.5 to continue testing the new webpack only builds, so we now have a 6.0 with still a lot of webpack issues and now no easy work around because legacy mode was removed in 6.0.

One of the techniques, I used while testing 6.0RC on plugins and apps and reporting the massive number of issues I ran into; is making my install side-by-side. So now I have a tns5 command which is my tns 5.4.2 install. And then tns is my 6.0 release.

The first step to run a side-by-side install is to do a npm i -g nativescript@5.4.2 to install 5.4.2 (the last 5.4 version) on your machine in the global node_modules. Now depending on the OS; this directory will be in a couple places:

The easiest way to find out where it is stored is to run the following command in your command or terminal shell: npm root -g

Under most linux installs this folder is here:
- /usr/local/lib/node_modules

Under Mac OSX the folder can be in a couple places, depending on how you installed it.
For example because I run nvm on my mac, my folder is located here:
/Users/nathanael/.nvm/versions/node/v10.15.3/lib/node_modules

And on windows 10, it is located typically here:
%USERPROFILE%\AppData\Roaming\npm\node_modules

But using the npm root -g will tell you exactly where it is on your machine.

So first navigate to this folder and find the "nativescript" folder; and then copy it in its entirety to the "nativescript5" folder. This gives you a fully working NS 5.4.2 version in a different folder that won't be overwritten when you do the npm i -g nativescript@latest which will give you the NS 6.x version.

The final piece of this puzzle is creating the tns5 command, on my mac the folder for where to put it is:
~/.nvm/versions/node/v10.15.3/bin

So I created the tns5 symlink to point to ../lib/node_modules/nativescript5/bin/tns

On Linux we needed to create the symlink in /usr/local/bin; and so I created the tns5 symlink to ../lib/node_modules/nativescript5/bin/tns (the exact same relative path as mac)

Steps:

  • npm i -g nativescript@5.4.2
  • npm root -g
  • cd (folder listed from npm root -g command)
  • copy nativescript to nativescript5
  • npm i -g nativescript@latest
  • create a tns5 symlink

This should allow you to have a permanent install of v5.4.2 and then your normal update-able version .

NativeScript Plugins and the costs...

A NativeScript Logo in Puzzle Form
NativeScript Plugins

Now most of you are not plugin developers; and as such do not understand what costs go into creating or maintaining an open source plugin. Normally I wouldn’t even think to post something like this; and I don't want this to be seen as "whoa is me". But a statement from someone at Progress; made me realize that many others are probably also be under the mistaken idea of all the costs of a plugin and so I now feel I should address this...

So here is the summary of the statement made to me in a conversation:

Plugins are either paid for mostly by companies, clients, or those that are free are still excellent advertising for your services. So releasing a plugin is a win/win situation.”

The funny thing is before I started doing NativeScript plugins; I am sure I thought the exact same thing. So, I can’t fault anyone for thinking this! It is very easy to think plugins and open source work is created by “mostly” companies, as it makes logical sense – all the press Microsoft, Google, Facebook and Amazon generate from their open source work. This can also be especially true, if you are doing open source work and being paid by a company for your work (like the NativeScript team, and the many teams at Google, Microsoft, etc that are producing open source work). So, I can honestly see how this is the prevalent view.

In a nutshell there are three separate claims here we will discuss:

  • Plugins are mostly paid for.
  • Plugins that aren’t paid for; are good advertising
  • Releasing them is a win/win situation.

Claim: Plugins are mostly paid for. (TLDR: false)

First of all, being fairly in tune with the plugin community; to my knowledge the majority of all the plugins in the NativeScript community are actually done as a mix of paid and unpaid work and those that were paid, are very very rarely still supported by the company who initially funded or released it. So even if a company actually sponsored the plugin, there is no followup money to continue maintaining or enhancing it. Meaning the author is almost always again donating their time to make this plugin work and/or do maintenance on it!

Since I really don't like talking in hypotheticals; we will use my plugins as an example. 21 of my 25 open source plugins were done completely on my own dime. Meaning, no actual clients paid me for any of that work. That includes some of my most popular plugins like NativeScript-Permissions and NativeScript-Sqlite (*3).

A lot of people have assumed that the authors of these plugins are paid by a company to maintain them. I may list Master Technology or nStudio on my plugins documentation to try and advertise my services, since I do own/co-own those companies. But I do not see a dime of money from anybody (nor even from my own companies) directly for working on any of my own plugins. Pretty much all work on all my open source plugins is in on my own totally unpaid time. These were all done either to help one of my own personal projects, for the technical challenge, or to help the community. Occasionally, I might actually fix a bug or add a feature that can be directly attributed to a client needing to use the plugin, which then it might be paid for. But that is not as common as many might think. (Lets just say in the 4 years I've done this, I've only had a handful of requests.)

For a truly complete picture of at least my plugins; 4 of my 25 plugins (mainly smaller plugins), actually had some real paid parts to them. Yay! Again, not normally enough to actually pay for the entire open source development of the plugin. But enough to pay for some or several of the extra features in them to meet that clients specific needs. So yes, there can be some money in it. But in most cases, it is still not even enough to typically pay for just the time that went into creating that plugin in the first place, let alone any of the time to support it or maintain it.

In addition as one of the few developers that has actual commercial plugins, I can also speak on this side of the coin. Even the money made on my commercial plugins has not actually paid for the actual development costs of those commercial plugins. In fact there used to be another developer with a commercial plugin -- he recently left the NativeScript market. There just hasn’t been enough purchases. And finally, I do have a lot more private/unreleased plugins that were in a several of the cases mostly (or even in a some cases, fully) funded by clients. In this aspect; there could have been good money involved with some of these. (*1)

So based on my own personal experiences, and many discussions with others in the community; I would have to say there isn’t nearly as much money going around to deal with making them -- let alone any money for support, bug fixing and/or documentation. One of the most famous examples of this issue. The OpenSSL library; it underpins the entire secure parts of the internet. HTTPS is provided by OpenSSL; so browsers, servers, your phones all have OpenSSL libraries (*2) in them. The team that was maintaining this highly complex software, was only getting about $2,000 a YEAR in donations; despite many many many companies using it in their hardware and software that they sold for massive profits. This matches my experience; both my donation Paypal and my attempt at a Patreon accounts have seen so little money, that I don’t even think it is enough to even get a coffee even once a month.

This is called the long tail of support: the support side still needs to happen; but no funding occurs for all the additional work that will easily exceed the initial work on the plugin over the life of the plugin.

Claim: Plugins that aren’t paid for, are good advertising (TLDR: mostly false)

Some people believe that I get paid in Advertising. That makes some logical sense, and yes I do to some extent. Since I have several of the top plugins, I won't totally dismiss this as 100% false. Let us dissect this logically. I have a pretty good grasp of the reality of this -- with my 25 open source plugins in the eco-system, and being in it since day one. That seems like a potentially large amount of advertising, I could be getting. This statement actually was very true when NS was first started; each plugin released had a huge huge amount of ability to be seen. Unfortunately, their is now well over one thousand plugins. That means even with all my plugins together – I only have approximately 2.5% of the advertising market (+/- a tad depending on popularity) and that is shrinking daily. So even the advertising I can do with them; really is simply drowned out by the other 97.5% of the plugins. Having popular plugins, or long standing well known plugins does help increase that percentage; but just the sheer volume of plugins pretty much negates a plugins ability to do much advertising. Again, having a well supported and widely used plugin; helps increase this percentage a lot -- but anyone putting a plugin into the community now -- well your new plugin is just 1 in over a 1000...

With the amount of time it takes to actually create a plugin and then maintain it -- It is actually considerably cheaper for me to spend that time just doing additional contract programming; and then be a sponsor at a conference (which can be a tax write off for smaller companies) – so that my company is seen everywhere at it. A conference can now drum up considerably more business. That company is seen with only 5 or 10 other sponsors, and might even be seen on many of the videos; tweets, etc. All the way around good press, and typically gives the company the ability to talk one on one with many potential clients and hand out even more advertising and share contact information in person. Or write blog posts like this one, that are hopefully shared everywhere. (Hi, I do contract work :-D!!!) Or just be very helpful in the community so that people know why you are considered one of the top developers in the community and so you get contacted because of that. There are several ways in the NS community to stand out; and almost all of them are considerably cheaper than writing a plugin.

Unfortunately, their is one big GOTCHA people don't realize. If the plugin is broken, it actually turns into a significant liability and so it is negative advertising! Which now means that plugin now actually turns from help into a source of long term money and time drain; as I try to make sure my free “advertisement” isn’t now a liability… Nothing inspires a potential client, more than trying your "free" plugins and it crashing. Yes, that will totally inspire them to try your paid services.

Just for those who haven't been around since the beginning of NativeScript time; there have been over 5 different sets of breaking changes to plugins over just 4 years. Each time a breaking change occurred; some of the plugins had to be completely rewritten or heavily modified to make work again. Others, fortunately had much more minor changes or if you are really lucky; no changes. But any way you cut it; all the plugins you released had to be re-tested, debugged, and upgraded to the next version of the framework. So writing plugins, this isn't a write once, and it can just sit and work forever, like plugins in many of the other communities. This is why plugins from NS 1, NS 2, NS 3, NS 4 don't work in NS 5, and of course our newest breaking changes are occurring in the brand new NativeScript 6 release. So watch a lot of plugins break again...

Claim: Its Win/Win (TLDR: LOL, So very false…)

Well you can probably guess based on the first two claims at how this goes -- since those were both false. But I have probably the one of best story to show you how false this claim is. This is a 100% true story, and I am attempting to minimize it to the best of my ability because I am not trying to make the parties look bad. I think this situation really points out how terribly lopsided this "win/win" idea really is or can be.    I can only speak to my story; but I have heard about another one in our community that is likewise just as "great".

So first lets take my awesome top rated NativeScript-Sqlite open source plugin, it was released for free, no strings attached, and developed by me for free, nobody paid me for any of the open source part of it(*3).    According to the COMOCO scale; it is worth about $150,000 in development costs. So far, nothing wrong, this was my goal for it to be something useful in the community. And I am very happy it is a useful plugin for everyone to use.   This is open source at its finest!  

So there is this small company called Kinvey, which Progress bought for ~49 million dollars a couple years ago.   Kinvey is a HIPAA compliant Database as a service; primarily focused on mobiles. They charge very large sums of money to companies for every byte of traffic / data stored.  Product is well written, and very secure -- so overall companies like paying the money for the piece of mind it gives them. Still Nothing wrong here, either. Good product, and excellent revenue stream for Progress.   They support several different mobile platforms, including NativeScript.

Does anybody want to take a guess where I'm going with this?   So when they developed their plugin for the NativeScript platform, they used one of those totally awesome open source plugins.    Any guesses to which one? Ding. Ding. Ding. Yes, you are correct – my NativeScript-Sqlite. Again, so far, nothing really bad, right...

Now I want you to really think about this.   Progress pays their programmers to build NativeScript, they also pay their programmers to create and maintain the Kinvey services and plugin (so the Progress developers all get paid). Progress also paid 49 million for Kinvey, so definitely the creators of that technology got paid. Progress also now gets paid massive amounts of money for every single byte of data stored that the app uses which has this Kinvey plugin in it. (So hopefully they are making all that money back!).   So far, let me be 100% clear – their is nothing is wrong with these people being paid, in fact they all deserve to be paid for all their work. So now every single NativeScript app that uses Kinvey has my plugin in it for all the offline features...

Everybody is happy right?    

Well, not so much. First, I have never even seen a single penny of revenue from Progress for this part of my awesome "win".  Oh well, that is the breaks of a well designed open source plugin, right?   It is being useful, its entire purpose in life. Woo Hoo, Yay! Ok, not so much -- I'll admit it is a bit annoying, they are making millions off of some of my work, and I don’t even see a single penny.   And, I do realize it is only a small (but critical) part of the NativeScript side of the project, but it is more the principle that bothers me. This story is such a common story in our industry (think OpenSSL) – I am in very good company of people whose excellent hard work is totally unpaid for and/or underfunded; but the company using it makes crazy boat loads from it. So, I'll just let it be – and we can count this as a “oh well”, and life can go on... 

Oh, I bet you thought I was done!    Ahahahahahaha....

Let’s not stop yet, it gets even worse!   So, I obviously didn't "win" on the first point (i.e. direct money).  So, what in the world could be worse? Well what about that awesome advertising/recognition that is the second point we discussed above.   Anyone want to take a guess?     Lazy person, I bet you clicked the link.  🙂   

Ok, I'll be nice and embed a picture here of the link...

Because my plugin is a declared NPM Dependency,  I also don't even get any recognition either. Nor does anyone see ANY of my documentation, my name or any of my advertising for any of my services.  So all these companies that pay Kinvey hundred's of thousands of dollars, who would be actually the perfect targets for me to do contract work for -- they don't even know I exist!   Kinvey, has my plugin so integrated, nobody even knows it even uses my code. I am totally invisible, even though my plugin is the offline part of their NativeScript plugin.  So, now we are at no money and no advertising/recognition, on something that is used to easily make millions for Kinvey.

Well, you know what; you won't believe it -- but the story continues to gets even WORSE! But we will actually stop here; my goal here isn't to make Progress and/or Kinvey look bad! My goal with this example is to actually show how much of an awesome "win/win" situation this really is for a real open source NativeScript plugin author...    The plugin was 100% funded by me, is worth about $150,000 in development costs; and it is being used in apps, which was my purpose in releasing it. But I honestly can’t think of a case anyone can make where this can really be considered an actual “win/win” situation.


So in summary; these are three separate claims here:

  • Plugins are mostly paid for. (False)
    • Very few of my released plugins are even partially paid for, let alone fully paid for. And none of them have had funding for the long tail of support.
  • Plugins that aren’t paid for; are good advertising (False)
    • Advertising from the plugin is such a small percentage of the entire market; it is more cost effective to do other forms of advertising. In addition do to all the down sides of plugins long tail of support, it will very easily become a liability or negative advertising and/or a money/time sink.
  • Releasing them is mostly a win/win situation. (False)
    • Win/Win it is not (See story above). In addition to the long tail of support; in our community, we rarely see much support or PR’s for the actual issues. The costs for the long tail of support can greatly out weight any potential benefit from the first two items.

Notes

*1 – Unreleased because the long tail of support that I mentioned, it is crazy bad in all reality and as I don’t want any bad advertising. At this moment, I am unwilling to release more “free” plugins that just require more free maintenance work and support. I have a hard enough time keeping up with my existing plugins. At some point in the future; they might get released if I can figure out ways to mitigate the costs...

*2 – There are now a couple of forks of OpenSSL that are used in some products, so OpenSSL is not in everything now; it used to be. In addition, because of a nasty vulnerability in OpenSSL a couple years ago; several of the bigger internet companies figured out that they needed to do a better job and they stepped up and started funding the OpenSSL foundation. So this is to my knowledge funding is no longer an issue for the OpenSSL foundation.

*3 – There is one of the commercial add-ons for SQLite that has been partially funded by a client. But the open source side; was not funded by anyone but me.


All company names and trademarks are owned by their respective companies.

NativeScript and Fortnite

Isn’t that an interesting title – I wonder if you can guess how I plan on tying the two together! Can we all say Click Bait! Stay tuned, and we will show you how I combine both of these into one blog post...

Now many of you know that NativeScript is 100% open source. I can take NativeScript and build the entire stack locally on my computer and never deal with Progress again, if I were to so choose. This is awesome from the standpoint that I am not technically stuck (*1) if I need to fix some issue. Many of the technology stacks in the past you could get to a point, and then if the issue was lower in the stack you were totally stuck. In my career I’ve run into this several times; and it really sucks when you can’t fix the issue because it is a issue in a lower part of the framework where you can’t get any access to it. In this case; we have full control over everything if and when we need it, so we are is a great position moving forward if using this stack.

So, the question I have seen around; and even had myself in the past was: Since NativeScript doesn’t make any money, how can Progress possibly continue to pay to keep it going? What is their business plan to turn a profit, and when will it be cut off?

Seriously; common sense says; if a product doesn’t make money after a couple years; a company will discontinue it. How many projects has Google canned that is making money; but not making as much money as they wanted to continue it? So, if the product has no real way to make money long term; then why would they keep it?

Yes, it does have a couple minor revenue streams, like paid support; but even the paid support probably doesn’t actually fully even pay for just the support techs that do all the awesome support for NativeScript. So basically NativeScript does not make any money directly. On paper; it looks like it is probably just burning money...

So why would Progress spend so much money to continue enhancing, and maintaining it, for a product that will never actually turn a profit??? Then what are our risks as the community that they will pull the plug tomorrow when they finally figure this out???

Well rest assured; I don’t believe it will discontinued any time soon. First; I would be totally shocked if most of NativeScript development costs are not written off as a very nice tax liability (*2). Smart companies have money pits in certain area for key reasons, one of the biggest is taxes. The other interesting thing is it is not really just a normal money pit used just for tax liability reasons.

NativeScript is the Advertisement. NativeScript is not a product, in that sense to Progress – it is a significant way to get you (the developer) to use Progress services. So just like some large company might pay millions of dollars in advertising; per year to try and reach you. Progress is doing the same thing – but instead they are actually targeting it specifically at developers. Virtually every dollar of advertising is being spent on developers. Who is a large part of their market target; well us developers! So it is an extremely well targeted advertisement, much better than you can do with any adwords scheme you can find!

Changing this point of view, completely changes the entire narrative of why NativeScript exists and its continued long term viability. It is no longer just a money losing venture of Progress. It is an significant advertisement to get you to use all the other Progress services. This is a critical point to understand; as this underpins the whole reason why NativeScript should continue to exist for the foreseeable future.

Since NativeScript is very much like Fortnite (see told you I would work it in!). They hand out the awesome 100% free game. And which game company has been just raking in the money (like 2.4 BILLION in 2018 alone) from a single free game? And if anyone follows Fortnite; you will know they are constantly improving it. However, they get you on all the “extra” attached revenue streams. Yes, you can play Fortnite 100% free and never spend a dime and even continue playing all the cool game modes that keep getting released.

You can also use NativeScript, create awesome apps and never actually spend a dime with Progress. Which is actually what the majority of the community does; but all Progress needs is a very small percentage of the NativeScript users to use its payed services and NativeScript ends up causing a major profit for them.

As some examples; to show how this works… Progress owns NativeScript, and say you want someone to build you an app, who is your first stop? (Especially if you are a large company!) You might see a nifty services page on Progress’s site – you contact Progress. But they do not actually do the contract work. They actually sub-contract it out to others; and take a hefty cut for that privilege. This works well for everyone involved. Or perhaps you are a independent developer; Sidekick, cloud builds, attend the conferences? All revenue streams. Larger companies; secure data storage, chatbot, ai, etc. Progress offers many of these “addon” services; and all of them have fully working integration's with NativeScript. So any development by a enterprise class company has a large chance of starting and choosing to stay with the owners of the NativeScript stack and paying for that privilege.

In other words; Progress is brilliant – they have managed to figure out how to take the same model used for Fortnite and use it on developers. So hopefully this reassures everyone that NativeScript should have a long life ahead of it. (*3)

Well played, Progress!


Notes:

*1 – I am not stuck; in that I can fix my own copy of the code and deploy the app. This does NOT mean that Progress will take your patches and fix the master so that it is fixed in the next version(s). It just means you can fix it in your copy…

*2 - Progress is a multi-national company; so they have taxes in multiple countries – different countries have different laws; but typically losses in one business unit can be used to write off tax gains in other units. So the “paper” loss of NativeScript offsets revenues from the other parts of the company, and so it then lowers some of their tax burden in probably several countries.

*3 - I am not a employee of Progress or Telerik; nor have I ever been, so this is all based on the know facts. However, this matches all the facts to a T. So, it is my strongest belief based on all public data available; that this is why NativeScript exists and will continue to exist. It also explains why Progress was willing to continue to sink million of dollars into NativeScript; and also purchased things like Kinvey for 49 million dollars.


Please note all companies names, Logos and products are owned by their respective owners and convey no endorsement of any content or other products in this post.

NativeScript 5.4 Build Failures

People who have been using the plugins like Firebase and/or other Google services may have all of a sudden had their apps stop building with an error like this.

+ adding aar plugin dependency: .[some path].\widgets-release.aar
.[somepath].\app\src\main\AndroidManifest.xml:22:18-91 Error:
Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:19:5-37:19 to override.


FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':app:processDebugManifest'.
Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:19:5-37:19 to override.


Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 30s

Wonderfully helpful error message huh? Well the issue is that Google recently changed their services to use AndroidX descended components. This change has been in the wings for a while and even NativeScript has been working towards this goal (NS 6.0 will be fully AndroidX). But in the meantime unfortunately Android.* and AndroidX.* are totally incompatible.

There are two things you might have to do to solve this so that you can continue to work...

  1. You create (or modify if it exists) a file in your App/App_Resources/Android/before-plugin.gradle and add the following section:
android {
     project.ext { 
          supportVersion = "28.+"
          googlePlayServicesVersion = "16.+"
     }
} 

This will pin your app to continue using a slightly older version of the Google services which is still based on the Android library. (IMPORTANT NOTE: when you later upgrade to NativeScript 6, you will want to delete this out; because NS 6 is Android X based; and so you will want the later versions).

2. If the above doesn't fully solve the issue; you may have to do a search in your node_modules and specifically the plugins for any plugin that actually uses google services in their gradle.include files; they might be hard coded to use a "+" as the version, and you will need to change them to be also "16.+"

--- UPDATE:

I had one of my friends, Dick Smith; showed me another solution via slack this morning; instead use the app.gradle file (also located in the same spot App/App_Resources/Android/app.gradle)

dependencies {
     configurations.all {
          exclude group: 'commons-logging', module: 'commons-logging'
         resolutionStrategy.eachDependency { DependencyResolveDetails details ->
             def requested = details.requested
             if (requested.group == 'com.google.firebase') {
               details.useVersion '17.+'
             }
             if (requested.group == 'com.google.android.gms') {
                 details.useVersion '16.+'
             }
             if (requested.group == 'com.android.support' && requested.name != 'multidex') {
                 // com.android.support major version should match buildToolsVersion
                 details.useVersion '28.+'
             }           
         }
     }
 }

This will override it as Gradle looks for the pieces it needs; it runs this code and even thought the plugins gradle file might state it wants version X of something; it will change it to the version we want... (Please note the same warning applies; when you upgrade to NS 6.0 in a couple months, you will want to then either change these versions to the AndroidX versions or delete this section).

--- End Update.

Finally after you make both those changes; I highly recommend you do a "tns platform clean android" before you rebuild the app, so everything is clean..

Finally if all else fails and you aren't expecting to release your app for another couple months; you can actually upgrade to the test version of NS 6.x; this version is currently unstable and you might have other issues (and you will probably want to update to the latest 6's each day just to try and make sure you are on the most recent version...)

npm i -g nativescript@next
npm i --save tns-core-modules@next
tns platform remove android
tns platform add android@next

If @next fails, and you need to return back to a solid release you can do the following:

npm i -g nativescript@latest
npm i --save tns-core-modules@latest
tns platform remove android
tns platform add android@latest

Please note; I do NOT recommend you run @next it normally is the least stable and most buggy version of Nativescript you can run. But sometimes you have to do what you have to do to proceed. 🙂

NativeScript 5.x and HMR Issues

If you are one of the lucky people who are reading this blog article, because your app used to work! After upgrading to the latest NativeScript and enabling the new Workflow your app is now broken...

Well I have some good news... It is easy to get back to a working state.

Here is how you can revert back to using the Legacy Workflow..

First thing, you need to open the nsconfig.json file in the root of your project. This file is where this key parameter is kept.

Inside the nsconfig.json file you will see "useLegacyWorkflow": true change this to false and save the file.

Then from the CLI; do a
- tns platform clean android (if using Android)
- tns platform clean ios (if using iOS)

Then you can do a tns run android or tns run ios and be back working.

Please note; DO NOT USE --bundle or --hmr flags; as this will re-enable HMR and the only reason you are changing this flag is because HMR is already not working for you...

I would recommend you submit a bug report to the nativescript-dev-webpack github repo about your issue; so that it can be tracked. Version 6.0 of NativeScript is supposedly going to disable the Legacy Workflow mode; so it is critical they get all the data they can on what issues you have seen so they can iron them all out...

Common HMR issues with fixes:

  • Your page/css/xml/html isn't changing on the device.
    • Make sure the name of the files end with "-page". So "main-page.xml" or "cool-page.css"
  • Your extra files (like sqlite databases) aren't being synced to the device.
    • Edit your webpack.config.js file, and add them to the copy step so that they are bundled up.

Some common broken NativeScript-Core HMR issues:

  • Pure JavaScript apps (i.e. not TypeScript) do not function properly on the second screen or on the first screen if using a SideDrawer as the root view. Click/Tap/Event handlers are not assigned properly.
  • Width/Height Specific files are unused (i.e. main-page.HW600.xml doesn't work; only main-page.xml is picked up.)
  • Shared NativeScript XML files do not link up to proper event handlers. (Similar to first issue; but a different aspect)
  • Some CSS files do not seem to be tracked properly.

Upgrading to XCode 10.2

Public Service Announcement.

If you are using any iOS plugins that use Swift v3 or less; DO NOT UPGRADE to XCode 10.2. Apple in its infinite wisdom has completly removed the Swift 3 tool chain.

You can re-add the tool chain back; BUT Apples guidelines state that apps submitted must be using the built in tool chain -- so odds would be very likely that if you re-added the Swift 3 tool chain to XCode 10.2, that the app would be rejected by Apple due to its requirements.

So the safest bet is to stay at XCode 10.1 if you are using any Swift plugins...

NativeScript-Core replacing the root view...

Please note this to my knowledge only works with NativeScript-Core / PAN (Plain Awesome NativeScript) applications. I do not believe this will work with the Vue or Angular variations of NativeScript. There maybe another way to accomplish this with those variations, and if you know how -- please let me know and I'll update this post.

So I was minding my own business again, and I saw this question pop up in NativeScript GitHub. Take this scenario; you want to have a SideDrawer that is active on all pages.

Seems simple enough you create the /app-root.xml as this:

&lt;nsDrawer:RadSideDrawer xmlns:nsDrawer="nativescript-ui-sidedrawer"><br>    &lt;nsDrawer:RadSideDrawer.drawerContent><br>        &lt;GridLayout backgroundColor="#ffffff"><br>            &lt;Label text="Go to Cool Page" tap="page1"/><br>            &lt;Label text="Go to Another Cool Page" tap="page2"/><br>        &lt;/GridLayout><br>    &lt;/nsDrawer:RadSideDrawer.drawerContent><br>    &lt;nsDrawer:RadSideDrawer.mainContent><br>        &lt;Frame defaultPage="/pages/main/main-page">&lt;/Frame><br>    &lt;/nsDrawer:RadSideDrawer.mainContent><br>&lt;/nsDrawer:RadSideDrawer><br>

But now I need a login page... And my awesome side drawer is now active on the login page. Uh-oh -- it even has a ton of links that go to places and so we don't want that if they haven't even logged in. In fact we probably don't want them to even have access to the side drawer when not logged in...

What is the solution?

My solution, is fairly simple is you revert your code back to close to the default app-root.xml:
Your <strong>app-root.xml</strong> actually is changed to this:

<Frame defaultPage="/pages/login/login-page"/>

That is because we want the main frame of the app to load my login page; in this case my login page will force them to login if they don't already have a valid stored login token... Notice, their is no SideDrawer, because it is no longer the root.. So part one is working great, no side drawer during login...

So now how do we get our cool SideDrawer to be active on the rest of all the pages...

const Application = require('tns-core-modules/application');<br><br>function loginIsValid() {<br> <strong> Application._resetRootView("/pages/root/root");</strong><br>}<br>

Yep, look their -- there is a cool feature in the framework that allows you to REPLACE (or RESET) the root view. So by doing this, my /pages/root/root.xml file now contains the SideDrawer root layout which I displayed at the top of this post.

Notes:

My own personal applications typically are laid out in such a fashion that I have a "pages" folder, and in the "pages" folder I have each separate page js, CSS, and XML. This typically allows me to quickly find the page I want to work on.

NativeScript AndroidX support and Plugins

The next major version of NativeScript (version 6) will be switching from the android.support packages to the new androidx namespace. This will be a hard break; as you can only use the support api's or androidx api's; but not both. This is something Google has been implementing for a while; and NativeScript is getting on board to eliminate later issues and give us great support. The awesome developers at Progress have already created a fork of NativeScript; which you can install to test which uses androidx instead of using the support libraries.

Since one of my plugins is affected by the changes; I took a look into what was required to support both the current versions of NativeScript and the new upcoming version of NativeScript.

For any of you who have plugins; this code is what I basically devised.

let androidSupport=null;
if (android.support && android.support.v4) {
  androidSupport = android.support.v4;
} else if (global.androidx && global.androidx.core) {
  androidSupport = global.androidx.core;
}

Then you can use androidSupport to access the namespace, and it pretty much works the same as what you would access using android.support.v4 or the new androidx.core replacement. Because we used feature detection; this allows us to support both namespaces in the same code base.

So if you have JavaScript or TypeScript code that uses android.support.* then you can use this technique to make your plugin forwards compatible with the next major version of NativeScript while retaining support for the prior versions.

Here is a list of classses that are being moved from android support to androidx: https://developer.android.com/jetpack/androidx/migrate

NativeScript 5.30 Released

NativeScript 5.3 only offers a smaller number of fixes and features than usual; but is still well worth upgrading to.

The most interesting update (for me) is actually the Android V8 engine has been upgraded yet again, but this time to a version that offers some nice performance benefits. It is always nice when an upgrade will increase the speed of your app with just a rebuild of it.
In addition some awesome work has been done on the iOS engine that should also result in a speed enhancement.

So just upgrading the runtimes to 5.3 should give you a faster app...

Important Depreciation Notice

In version 5.2 short imports have been depreciated; I do not know when they will no longer actually work; but basically things like require("http") are no long valid; you need to do require("tns-core-modules/http"). The primary reason for this is that webpacking requires the full path; and it has problems with short imports.

Core Modules

The core modules offers the following enhancements and fixes...

Resource ID on Android error fixed during Navigation
Webview and TabView fixes
Icons on Tabview and ActionBar should look better
View classes now have the missing .background* Style options.

Android

Upgrade to V8 7.3.492 - which offers
- Faster Await
- Faster JS Parsing
- Faster Spread Elements
- Embeddins supported in ia32 now
NativeScript Arm64 support built in on release versions
Static Binding Generator fixes and enhancements
Gradle 3.3.2 support.

iOS

Lazy Evaluation - Performance
Many Debugger fixes

CLI

HMR is no longer considered Beta; almost all critical issues with HMR are now resolved.
Several debugger issues resolved



Updating NativeScript

To get updated; you first need to do:
npm i -g nativescript@latest

That will get you the latest version of NativeScript CLI; once you have it; do a "tns --version" and verify it prints out "5.3.x".  Then do a "tns doctor" to verify your environment is up to date and has all the newest support tools you need for a successful build.  

To update a project; you need to do the following:

Latest Runtimes:
tns platform remove android && tns platform add android@latest
tns platform remove ios && tns platform add ios@latest

Latest Core modules:
npm r tns-core-modules --save
npm i tns-core-modules@latest --save

To install Webpack & HMR support:
npm i nativescript-dev-webpack@latest --save-dev
Note: you need to have nativescript-dev-webpack as a development dependency for HMR to work.  

To install latest NativeScript Angular plugin
npm i nativescript-angular@latest --save
You will then need to install the actual angular bits; which as of this post v6 is currently supported.

The addition of all the additional analytics/tracking to the CLI reminded me; you can disable it permanently; if you value your privacy by doing:
tns usage-reporting disable && tns error-reporting disable


Known issues

  • Android Q is not supported properly; The fix is slated for 3.3.1
  • TNS frequently (for me at least) kills the build with "Error is: cp: cannot create directory " and to fix you have to reset your platforms. (This might be more plugin development related corner case)

Mobile Application Security

Security is never perfect, the minute the device is under the control of an attacker; you have issues. So the primary goal of security is to raise the bar so high; that it becomes much more profitable to attack your competitors app then your app. Don't make your app the easy target.

So, recently I have seen several blog posts and even a podcast in the NativeScript community on Mobile application security. Unfortunately; some of the advise is just wrong. I really hate to be harsh; but giving out bad advise is far worse in my opinion, than giving no advise when it comes to security of your application and infrastructure.

Lets talk about the Good, Bad and the Ugly... Lets start with the Bad.

Bad Advice

Would you really accept someone saying it is super secure to set a cookie to "isAdmin=1" for allowing admin access. Well, I'm here to debunk several things that I've seen show up recently as they "sound" good, but are still bad advice in most cases.

First, in a couple blog posts I read, and the pod cast I recently listened too, all recommend using NativeScript-Secure-Storage for storing secure local data. Simply put you are just as safe using my NativeScript-LocalStorage plugin (which has no security at all) as the Native-Secure-Storage plugin in all cases that I can think of except one very specific case 1. (So basically; you have added no extra security to your app in almost all cases to just using raw file storage on the platform.)

How is that you ask? Its encrypted storage using industry strength encryption systems. Well, the issue is that any person attempting to pry the secrets out of your app; will be running it on a rooted phone (iOS or Android, doesn't matter the OS). With a rooted phone, I now have full access to EVERYTHING on the device including the secure "storage" files. Bam, game over; do not pass go! I now have your secrets that you thought you "securely" stored. As you can see a pretty pointless plugin in all reality for securely storing anything. ( This is a bit of a simplification, but for someone who knows exactly what they are doing -- they can trivially pull all the values out of the secure storage plugin in literally only a couple minutes on any rooted device. )

(1) - Using JSScrambler or AppProtection can mitigate most of this issue, there are still some corner cases that might still allow access to all the data even using these products.

API Endpoints and Keys

The next thing I heard talked about was HTTP, Kinvey and API keys; the advise wasn't bad so much as incomplete. This isn't specifically against NativeScript 4, (or Kinvey), because really React Native, Titanic 2, Phonegap/ionic/Cordova 3 , and several others are all JS code based; the JS code is shipped with the application; meaning the code can be fully read by your attacker. So when you have in your plain JS code:

Kinvey.init({
   appKey: '&lt;appKey&gt;',
   appSecret: '&lt;appSecret&gt;',
   encryptionKey: '&lt;encryptionKey&gt;'
});

or

const result = http.get("https://master.technology/secretApiPath?appKey")

Guess what I now have access to? I have access to the ability to read (& write?) any data your appKey has permissions to do. So it is very critical to initially assume this code is 100% readable and that none of this is secured at this point. So make sure you plan the usage rights for all your keys and api endpoints properly. If you don't plan for this, then your appKey may give me access to read and write things that even the app doesn't do, which could be really bad for your overall security footprint.

Again, I want to stress this is NOT specifically talking about NativeScript; as this same advise applies to React Native, Cordova, Titanium, Flutter, Java, ObjC, and pretty much every environment. If I can get the API keys out, I then have the full access that your key offers. Now JavaScript based systems are tremendously easier to pull this out than say; something using compiled code (like Flutter or ObjC). However, you know what I would start with on a 100% native app? I will just run strings on it... Its amazing what is easily seen in plain text from a compiled applications like all your endpoints and keys.

(2) - Titanium has a built in encryption of the source code. However, last time I looked it was the same key for all apps; once you have the key (which of course I do ☺) -- it is trivial to decrypt all the code in every single Titanium app. But I will admit it did take a bit of time to figure out the key, so it isn't bad system.
(3) - Cordova has a third party plugin to encrypt the code; I spent less time breaking it than I did downloading it. To say the least it was the simplest of the bunch.
(4) - NativeScript HAD an official plugin, after pointing out how easily I could break it; it was dropped shortly after. I believe you can still find the repo for it -- and you can probably still use it; but it really is as trivial to break as the Cordova plugin.

Encryption

So in this case; any api keys and important endpoint urls; are better off encrypted in the app. That won't stop everybody; but it will make the bar to get the values out a lot harder. This applies to ALL app types! You want to encrypt or obfuscate the data and do not make it trivial for them to find it. If your JS code says:

let apiKey = "##DS#F#1%F#aD#D#";
apiKey = decrypt(apiKey);

Guess what code I'm going to look at next? So using the decrypt right next to the assignment is not going to slow me down in the slightest. Now using it somewhere in the middle of something completely unrelated might actually make me miss it, especially if it is not called decrypt but something like initializeCameraModule. So if the value you stored in your apiKey is not a real apikey but a obfuscated key and since I am unaware of it, you cause me a lot of wasted time as I'm trying to figure out why my external calls to your api aren't actually working properly. Again, wasting my time is the quickest way to make me want to attack a simpler or softer target. Now someone paid to figure this out; will figure it out; but a casual hacker might give up. Each barrier that you can raise and actually waste a bit of time 5, will discourage and drive up the costs to figure it out.

Another partially bad advise is the use of Encryption to keep your data at rest in a state that it is not easily retrieved. It sounds great! But this suffers from the exact same issues as discussed above. If I have easy access to your source; I'm going to trivially find your key and then decrypt all the data. This exact same warning also applies to my own encrypted SQLite product; if you don't protect the keys; I can pull all the data out.

So doing something to hide the keys is critical.

One potential solution if your app has a login, is that when the user types in the password for login it is used to calculate a new encryption password, which is then used to access the encrypted data store or sqlite database. Then, since I, the attacker don't know the password, I have no ability to ever retrieve the data from any data at rest no matter what I do unless I convince you to give me your password.

(5) - Any place you can seriously waste the person attacking your app's time is pure gold. Eventually they will figure it out; but in the meantime you drive up their costs and frustration. At some point, if those costs are significant enough, they will stop and attack an easier target. Their are many other techniques that you can do while working with keys/endpoints that can waste significant amounts of time and should be considered.

Compiled Code

In some cases it might be in your best interest to have compiled C code that sets up certain values and/or decrypts parts of your data. This makes it a lot harder to figure out what is going on, and can store keys you want protected. However, if your source code is still plain text, then I can easily see how/when you are calling it, add breakpoints and then determine how it works. So this really again can add no real security or can be an extra high barrier depending on what other protections you have in place.

Source Code

There are two things about the source code in JS based apps that you need to consider.

  • The first is that any secret apis, keys, endpoints and your proprietary business logic are easily found.
  • The second, which is related but a different aspect which might concern you more; is that I now have all your source code. I can easily create a clone of your cool app on the app stores with literally no development costs (new startup screen, some css color changes) and then totally undercut your price.

So lets look at some ways to try and mitigate the primary issue of visible source code...

The Ugly

A lot of people believe Obfuscation is a good and a valid answer. Since it is frequently put forward and considered a valid solution; and so it is recommended; this is why I consider this the Ugly.

Obfuscation

Now one thing that they got correct in the blogs & podcasts; was that obfuscation actually does very little. In fact other than JSScramber, the rest of them that I've played with are literally only one step above useless. If they minify your code; they have some usefulness as your app size goes down. If they slow your app down, then they are actually worse than worthless. But odds are very likely they will not have any performance hit. Unfortunately, almost every single one of them, by dropping the code into a decent beautifier, will eliminate almost all obfuscation. So using obfuscation (which includes the recommended NativeScript --uglify flag you see in some posts) really presents absolutely no additional security beyond the minification of making myFavoriteVariable become c. That can eliminate some really basic understanding. But an average JS developer can easily still read the source code. If I'm the one breaking your code; all I'm going to do is just drop the newly beautified code in phpStorm and refactor any variables as I figure them out and then we will be right back at pretty close to your original code rather quickly.

It can slow the attacker down some, but really it is something that won't really cost that much time as refactoring and code insights will allow me to trace things down rather quickly. So in my opinion; this really offers very little value. In addition most Obfuscation will NOT change any of your static strings. So if you had:

let apiKey = "xyz"; <br>http.get("someurl" + apiKey)<br>


and it transforms it to:

let a="xyz";http.get("someurl"+a);<br>

Does that really stop anyone from understanding that a is probably the apikey?

In addition, just a fyi -- in all cases (except JSScrambler) of obfuscation that I have seen and played with I have broken the obfuscation is less than 30 minutes, most the time in a couple minutes just using a beautification will do it. But there were a couple that actually required a few minutes to read through the output to figure out where to attack it at.

The Good

Lets discuss the best ways to potentially handle the the security of your application, lets look at the two possible ways to handle this..

JSScrambler

JSScrambler actually provides really good Obfuscation at the higher levels. But for the highest quality obfuscation your app pays a significant speed penalty constantly; like up to 50% slower depending on what the code is doing. So this is one of those things you have to evaluate if the added security is worth the performance hit and choose the security level you are most comfortable with. On some of the lower settings, there is no constant performance hit; but it is a lot more trivial to eliminate the obfuscation. This is one area you can increase the bar extremely high. Which would potentially not make it worth the time to attempt to figure out your app, but their is a serious price to pay. Now I haven't heard of anyone that has actually hacked JSScramber set at the highest level; but do you really think anyone would tell you if they could? Please feel free to pay me to find out how secure it is.

Encrypted Source Code

There is one other service AppProtection.net that offers encrypting the source code. This actually is my product/service; so major disclaimer here!!! I think this also raises the bar extremely high . With AppProtection; I encrypt all app JS code and the V8/JSCore engines decrypt the files while running. All my tests had ~10% slow down during the loading of encrypted code as the code had to be decrypted in memory. (No decrypted code is save to disk at any point, it is always only in memory), so each time you start the app you have a perf hit. But you do not have the "constant" hit as with higher levels of JSScrambler, since the code is running from memory will already decrypted. However, as with anything; someone extremely skilled in debugging can eventually even break this also.

So in all reality the only real solutions at this moment to actually protecting your source with NativeScript is JSScrambler or AppProtection. With other products like React Native or Cordova, JSScrambler is the only current solution. (Please note; if I get enough requests for React Native, I could bring the AppProtection tooling to it as the code already runs on JavaScriptCore)

So now that we talked about the Good (Source Encryption), the Bad (false information that doesn't help) and the Ugly (Obfuscation). So, lets discuss a couple related items..

SSL Pinning

Using SSL Pinning can be very valuable for the opposite side of this; making sure your app is actually talking to your server. This will eliminate Man-in-the-Middle data watching. So if you are transferring data that you value; you might consider adding SSL pinning to your app. However you do have to make sure that you plan for how you will update the key with the new SSL key when it expires.

Security in General

I am going to re-iterate; their is NO PERFECT security, all security can be eventually broken. It is impossible, once the app is in the attackers hands to stop them. Just look at how frequently Denuvo gets cracked -- they are paid millions to get it correct and are constantly updating the security and it still gets broken frequently. So once an attacker has your app, they now have the ability to do anything I want with it. So the goal is to what we call security in depth. Do multiple things that raise the bar as high as you are willing to pay the price. As their can be a cost for each security measure you implement. For example if you are super paranoid; you could use AppProtection, JSScrambler, and multiple native C modules all in the same app. Then if the attacker finally broke one aspect of your security their are still several others blocking them from going forward. Now that is being ultra paranoid, but their is nothing stopping you from doing it.

Final Notes

If you are working on an app that needs to be secured and/or you want someone to do some security contract work on your app and/or the API endpoint infrastructure, we can assist in this. If you would like someone to attempt to break your app's code and suggest additional things to strengthen your apps security footprint; again please contact us at master.technology

About the Author

I am the owner of Master Technology, which focuses primarily on server side work and desktop apps. If you need any NativeScript work done; from optimization, code reviews, training, help on an app, creating plugins, and even full apps created. Please feel free to inquire at master.technology.