Category Archives: NativeScript

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)

NativeScript 5.2.0 Released

NativeScript 5.2 offers a wide number of fixes, and is well worth upgrading to. Checkout what has now been fixed and/or enhanced in this awesome release from the NativeScript team.

One of the more interesting things for iOS is the In App Podfile and Src code support. Drop your any src code into the /App_resources/ios/src and/or a Podfile in /App_Resources/ios and your app will automatically build it with your app. So you don't need to create a plugin to test or embed things in your app anymore. Plugins still are good for reusable code; but sometimes you might just have a simple function or Podfile that you just want added to your 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 ModulesT

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

Dialog now supports Decimal type
ImageCache now has onError exposed
onDiscardedError now officially in the typings
Android model fixes
iOS Flat Actionbar fixes
Password hint support
Multiple crashes fixes

Android

Upgrade to V8 7.1.302 - which offers
- Stable Sorting
- More bytecode embedded saving 200kb of memory per engine.
- Escape analysis improvements (up to 40% faster)
- globalThis support
- Intl.RelativeTimeFormat support
Android X support
Ability to free Java memory that is being retained by a JS object
Gradle 3.3.1 support.

iOS

OnDiscardedError handler now works properly.
Can now manually free OBJC memory that is being retained by a JS object
Can now call ObjC methods with the same name but different parameters. (I've ran into this bug myself -- woohoo!)
GC tuning parameters
JSC tuning parameters

Fixes in Exception handling
Memory allocation fixes
In App Podfile and native Src code support

CLI

Node 11 support
Angular HMR support (finally fully working!)
--debug-brk on iOS should be working again.
Unit testing should work on Android again.
Fixed High CPU usage issue.
generate splashscreens should work again.
HMR will now update styles.


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.2.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

NativeScript-SQLite Multi-Threading!

The first release of NativeScript-SQLite was April 19th, 2015 on GitHub, and April 26th to NPM. I am happy to say this plugin is now almost 4 years old, and it was one of the first plugins available to NativeScript. I believe there was two or three others released before, like NativeScript-Flashlight. By June of 2015 we had a grand total of 18 (eighteen) plugins in the NativeScript eco-system, where today we are at almost 1,000 plugins.

NativeScript-Sqlite has had a lot of upgrades like encryption, prepared queries, and several bug fixes over the last 4 years. But the newest feature; I'm probably the most proud of. Without your app changing a thing (besides setting a simple option flag); NativeScript-Sqlite can now be fully multithreaded. What do I mean by that? In a nutshell all SQLite calls can now happen in a background thread. This means that if you are inserting or reading 20 records the UI won't freeze.

A couple years ago I did a session on Performance and NativeScript; my sample app showed how doing several different things could freeze the UI easily; and the best way to deal with this was to move as much of your work to background threads.

Now if you watch this image; every time I hit the SQLite button, the "n" freezes for a few seconds. This is because the work loading and processing the records is all done on the main thread which is the UI thread, causing the Animation to stop and/or stutter.

Since NativeScript-Sqlite has always been Promise (and/or Callback) based ASYNC code; it ended up that I could preserve the entire API as is; when allowing you to use multithreading. You just need to set a flag when opening up the connection and it will become multithreaded.

And this is what it looks like when sqlite is doing everything in a background thread. Notice how smooth it is. This is because the main thread is just waiting for the acknowledgement back that everything has been loaded.

If you check out the demo app; the code change is just this:

[[code]]czoxMDk6XCJuZXcgc3FsaXRlKGRibmFtZSwge2tleTogXFxcJ3Rlc3RpbmdcXFwnLCBtdWx0aXRocmVhZGluZzogISFzcWxpdGUuSEFTX0NPe1smKiZdfU1NRVJDSUFMfSwgZnVuY3Rpb24oZXJyLCBkYkNvbm5lY3Rpb24pIHtcIjt7WyYqJl19[[/code]]

Basically if the commercial plugin has been loaded; we flip on the multithreading flag. Otherwise we leave it off. (This way the app can test, Encryption, Multithreading, Commercial features, and no extra features all in the same codebase.)

The open source version of the plugin can be easily installed by typing tns plugin install nativescript-sqlite@latest, the open source repo can be seen at https://github.com/NathanaelA/nativescript-sqlite.

The commercial version which includes Encryption, transactions, prepared queries, and now multithreading can be purchased from my site at nativescript.tools.

NativeScript 5.1.0 Released

For those who upgraded to 5.0.0 last month, it was a bit of a rough ride.  A lot of cool features but a lot of weird corner case broken items.  Fortunately since that point, they have released a several 5.0.x point releases which fixed several of the larger flaws.  5.1.0 actually fixes several of the non-critical smaller flaws and adds some cool new features...   So if you were waiting to jump on the 5.x bandwagon, this should be the stable release you are waiting for!

The quick list of some of the new features in 5.1

Core Modules

Enable modal dialog chaining in IOS - this allows you to have another dialog follow the first; anyone who has tried this in the past; know this was always a pain on iOS.

isScrollEnabled - This allows you to disable scrolling in the scrollbar component.

androidSwipeEnabled - Allows you to disable swiping in the Android tabview control.

You can use the arrow keys to select an option, in this screen shot; the "Plain JavaScript" is chosen and so it is highlighted.

Android

Android AAB (Android App Bundle); support added!

New package.json flag;  suppressCallJSMethodExceptions: true/false - enables suppression of the boolean errors when calling a native function.  This could happen and crash the app.  Now you can suppress them.  (see http://fluentreports.com/blog/?p=581 for more information) 

Java 8 Static method support on interfaces; allows NativeScript to call these Static functions.

extends should now work against standard javascript classes (i.e. non native Android classes); so that you can now do class MyVue extends Vue {}; class blahComp extends MyView {}; and it will work properly.

iOS

CStrings are a bit more resilient when passing to a function that wants them as a pointer to read and possibly write.

Updated JavaScript engine to JSC 12.0

CLI

Several bugs when using hmr are fixed.

Yarn Support

Adding lots more Analytics/Tracking (Don't forget to disable this for your privacy: tns usage-reporting disable && tns error-reporting disable)


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.1.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

The "tns preview" Feature

The all new "tns preview" feature in NativeScript 5.0 is very useful for testing small local projects and/or for new developers who want to try out NativeScript without installing all the build tools.    

However, the preview app has some limitations, some of them can be worked around.   The first is that you must have working internet as the link between the CLI to the preview app on the device is via cloud servers.   Your app is transmitted via the internet to your device; and the device creates another channel that is transmitted back to the CLI the console so you can see any errors that occurred. 

If your company has an issue with your app source code being transmitted out to the cloud; then make sure you don't use this feature. 

The second limitation is that only the plugins that come with the preview app can currently be used.   These are the only compiled plugins you can use:

Now, this is a decent list; but we currently have over 800 plugins available to NativeScript.    A number of these additional plugins can be used in the preview app.    There is two ways to work around the built in limitations of the Preview app.  However, only if the plugin is 100% pure javascript source (*).    If the plugin has no compiled code; then you can work around it easily by doing the following:

  1. npm i --save-dev nativescript-dev-webpack
  2. tns plugin add <plugin_name>
  3. tns preview --bundle

By using the --bundle command, it will use webpack to webpack your source code and then those 100% pure JS plugins will be transmitted to the app in one of the two bundles.  

The second way (if you don't want to use webpack, or webpack is breaking something) is to basically install the plugins into a different folder that will be synced via the preview function.

  1. Change to your "app/" directory (main directory that contains the app.js/app.ts file)
  2. npm i <plugin_name> --save
  3. In your source code do 'var X = require("~/node_modules/plugin_name");'     (or you can use the import statement, you still have to use "~/node_modules/" to allow the javascript engine to be able to figure out where the plugin actually resides, since it isn't in the normal location.

Again this technique will ONLY allow any 100% JavaScript plugins(*) to be used in NativeScript, anything that has a cocoapod, gradle, or jar/aar file won't work.    Everything inside the "app" directory is synced to the device, so these 100% JavaScript plugins will also be synced and then be usable.

(*) - It is possible that a 100% JS plugin won't work on Android.  Any plugins that actually requires the SBG (Static Binding Generator) to generate compiled Java code from the JS code can't work; as the Preview app has no ability to use any additional compiled code.

NativeScript 5.0 Released

It has been a long road getting to this point; but I'm happy to see that the NativeScript team released The final piece of the 5.0.  The CLI tool which was the final piece was finally released on Nov 2nd; the rest of the pieces have been released for a couple days.

5.0 adds a whole lot of new awesome features; however since several pieces have changed; I would highly recommend before uploading a 5.0 app to the app stores you do another full test of your application; testing everything as several low level framework items changed for both iOS and Android.

The quick list of some of the new features in 5.0

CLI Prompts

The cli now will prompt you for input; so when you type "tns create ProjectName" you will see something like this:

You can use the arrow keys to select an option, in this screen shot; the "Plain JavaScript" is chosen and so it is highlighted.

HMR - Hot Module Replacement

This is the feature most NativeScript developers have been waiting for; this is awesome.  You know the silly change a file app restarts; change another file app restarts livesync?    Now you can do this:  tns run --hmr

HMR, allows the page and JavaScript code to be updated dynamically (no more full app restarts) ; if you change a class the class may have to be re-instantiated (like in this example), but if you change other things, like functions, the state is preserved and the new function will be what is called the next time that function is needed.   All in all, this is very HOT!   (You do need to have the nativescript-dev-webpack as a developer dependency of your project for HMR support)

NativeScript Preview

QR Code

Preview allows you to preview the application without having xcode or android tools installed and building it.  It uses the already built playground preview application to preview the app so that you can see the app on your mobile phone.   It has the same limitations as the playground site; but for most developers getting started it is a quick and easy way to start playing around with programming application.    When you type:
tns preview

you will then see the qr code in your console.  Point the playground app's qr scanner at it and then your app will start running on your phone.   Please note the entire application is uploaded to the cloud; which then your phone links to.  So if this is an issue with your company  don't use this feature.

Internal Changes

Android Core modules is now descended from the Google Support libraries; this opens up many more visual plugins and makes the app a lot more modern and compatible.   One word of caution this did require them to do a bit of reworking of several parts of the base code for android.  Their is the likely potential for new bugs to appears in areas that were bug free before.  So heavily test your app before releasing it to the stores.

iOS Core modules now have a new way to do the safe areas; this also has required a lot of reworking and so the same warning applies.  Test your app thoroughly to make sure that something in this area won't cause you any issues.  

Other android specific changes:

  • now using the v8 engine, v6.9.427.23.
  • before-plugins.gradle support
  • SBG will fail if their is a JSParser issue
  • JSParser fix for Decorators
  • Runtime issue fix with support > 26 on devices < 23.
  • Gradle is now using 3.2
  • Building is even faster now

Other iOS specific changes:

  • Typing generation improvements
  • Webkit is now using 11.4
  • Several marshalling to native from JS issues fixed.

Other specific changes:

  • Many bugs fixed
  • Webpack Vue  bundling support
  • Angular memory leak fixed
  • Styling changes to support dynamic theming
  • tslib helpers now global
  • appSettings now supports allKeys method
  • Touch event pass through now supported


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.x.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.


Known issues

NativeScript 4.2 Released

The new version of NativeScript just dropped today!   As usual the update is worth getting for several features that are shipping in it.

Major Features

  • LiveSync now uses Sockets on Android
  • iOS and Android now support the `discardUncaughtJsExceptions` flags.
  • Simpler Templates (less NPM dependencies)
  • Android now support HTTP Gzip'd packets
  • Debugging Webpacked apps

Minor Features and/ Bug Fixes

  • Android v8 engine upgraded to 6.7.288
  • Android app no longer crashes when closing debugger.
  • Multiple CLI building issues resolved, including LiveSync on modern Android; Gradle issues with Google plugings.
  • Android P support
  • iOS XCode 10 support
  • Several LiveSync fixes
  • Lots of build issues fixed

Known new Issues

  • None so far

NativeScript application wide runtime settings (updated 5.2)

NativeScript Switch

On thing most people are probably not aware of is that the Android runtimes has a large number of knobs and switches to customize certain behavior of the engine.   I will try and list out all the current switches and knobs that you can use.   iOS now has one switch.

First of all the settings go into the /app/package.json   If you open up the default package json you probably will see:

{   
    "android": {      
        "v8Flags": "--expose_gc"    
   },    
   "main": "app.js",
   "name": "tns-template-hello-world",
   "version": "5.2.0"
}

That "android" key is where everything goes for Android specific settings.   The default setting that comes in the files is "v8Flags": "--expose_gc" this one is rather critical in that this enabled the runtime to call gc from JavaScript.   Now, there is quite a few v8Flags you can use; most the time they aren't needed but if you need to tune the v8 engine; you can add more flags into this string.  I even list a few in this post.   Let me warn you again; DO NOT remove the "--expose_gc".   You will cause your app to crash when something attempts to call the GC from code.

As of version 5.2; there is a "ios" key called "jscFlags" option that is now available. My recommendation while building/testing your app is to add the key "ios": { "jscFlags":"--validateOptions=1" } The jscFlags has items that can be used to tweak the JavaScript core engine. You can find more flags here.

Ok, so here is the complete list of settings you can change in the Android section:

SettingDefaultMin VersionDescription
gcThrottleTime03.xAllows you to throttle
how frequently JS GC
triggers native GC
See:
Memory Management
memoryCheckInterval03.xHow frequently to check
memory usage
See:
Memory Management
freeMemoryRatio0.03.xRation of memory before a GC is ran (works with
memoryCheckInterval)
See:
Memory Management
markingModefull3.xSwitches which type of GC engine to use.  "none" will enable a different engine which doesn't do
marking.  Typically faster
for Angular apps
handleTimeZoneChangesfalse4.1True will enable the
ability for a time zone
change in the settings to
effect the NS app.
maxLogcatObjectSize10244.0How many lines of text a
console output will log.
forceLogfalse4.0True will enable logging
in release mode
suppressCallJSMethodExceptionfalse5.1True will suppress the
boolean type conversion error from null that could randomly occur and crash the application.
codeCachefalse2.xTrue - Enables code
caching in the v8 engine.
v8Flags--expose_gc1.xTunes the v8 engine
heapSnapshotBlob""2.x(Believe to be unused
now)
heapSnapshotScript""2.x(Believe to be unused
now)
snapshot.blob""2.x(Believe to be unused
now)
profilerOutputDirKey""2.x(Believe to be unused
now)
profiling""2.x(Believe to be unused
now)

IOS Level Flags:

SettingDefaultMin VersionDescription
gcThrottleTime05.2Allows you to throttle
how frequently JS GC
triggers native GC
See: Custom Flags
memoryCheckInterval05.2How frequently to check memory usage
See: Custom Flags
freeMemoryRatio0.05.2Ration of memory before a GC is ran (works with
memoryCheckInterval)
See: Custom Flags
jscFlags""5.2Tunes the JavaScriptCore engine. Valid Flags

Top Level Global Flags:

SettingDefaultMin VersionDescription
discardUncaughtJsExceptionsfalse4.2True - will disable
crashing on JS errors, will
log any issues to console.

Recommended changes:
discardUncaughtJsExceptions: "true" - This will keep the app from crashing on certain types of errors; this should be enabled for release mode! Some developers might find it more productive to have this enabled while coding to eliminate application crashes. Please note you MUST pay attention to the console if you enable this during development; because most JS errors that would crash out; will now be just logged to the console.

suppressCallJSMethodExceptions: "true" - This will keep the app from crashing on the boolean conversion issue that can occasionally occur.  This is not to say the app might have some other issue later; but this will eliminate a stupid (imho) crash reason.

markingMode: "none" - This will enable the experimental GC engine, this will help incredibly with Angular based apps. Please note it "might" cause more crashing errors if a plugin forgot to hold a reference to something it needed later. However with the above discardUncaughtJsExceptions enabled; those errors won't crash the app.

Late Breaking news; in 4.2 they actually moved "discardUncaughtJsExceptions" to the top level of the package; the reason why is because shortly after they added the support to Android; the support was added to iOS.  So now this flag controls both iOS and Android, so it no longer belongs just in the "android" block.

So in your package json would look like this if you used my recommended settings:

{
   "android": {
       "v8Flags": "--expose_gc",
       "markingMode": "none",
       "suppressCallKSMethodExceptions": "true"
    },
    "ios": {
        "jscFlags": "--validateOptions=1"
    },
    "discardUncaughtJsExceptions": "true",
    "main": "app.js",
    "name": "tns-template-hello-world",
    "version": "5.2.0"
}