Monthly Archives: November 2016

NativeScript 2.4.0 - New Features

ns-version240Some of you might have seen the all New version 2.4.0 has been released today.   This has been a release that has taken a bit of time to get right, but it is finally out!  Wooo Hoooo!!!

Some of the new features

  • NativeScript Workers
  • Per-Side borders
  • Flexbox layout
  • Android Snapshots on Release build (faster app start time)
  • Added "import" to point to the JS file
  • More pseudo selectors: button now supports: pressed, active and highlighted, and views descendants support disabled.
  • Segmented Bar now has a new css property:  selected-background-color
  • TabView now has new CSS properies: tabTextColor, tabBackgroundColor, selectedTabTextColor, and androidSelectedTabHighlightedColor
  • Some CSS properties now support % sizes:  height, width, margin-left, margin-top, margin-right, margin-bottom, margin.
  • Image Capture allows rotation.
  • Camera module now a plugin (Removes a permission)
  • Brand new Theme!
  • Reduce the size of the Android App
  • Much nicer Android crash screen
  • Faster tns prepare
  • Android has ~ 97% support for pure ES6 code.
  • Can create TypeScript typings automagically on android platform using --androidTypings command line.

Lots and lots of bug fixing in all the repo's.

Upgrading (Core):

First of all to upgrade is done is a couple steps:
> npm install -g nativescript@latest
> npm install tns-core-modules@latest --save

For Android:
> tns platform remove android
> tns platform add android

For iOS
> tns platform remove ios
> tns platform add ios

Then you can type tns info and verify that everything says v2.4.x

Common Issues:

  • iOS failing to build, older projects:  v2.4 requires you to have the Info.plist file in the app_resources/ios folder.    The simplist way to fix this is to create a new project and then replace your app_resources with the new app_resources folder.  If you have any resources you have manually added or any changes to any files make sure you copy them out before you delete the old app_resources folder.  I would highly recommend you do NOT merge them as you might get some weird behavior from the old resources in the old format vs the new resources in the newer layout.
  • iOS requires CocoaPods v1.0 or later.   This is not a NativeScript issue so much as the Cocoapod infrastructure no longer allows anything older than 1.0..
  • Android failing to build with some plugins (like NativeScript-Telerik-Ui). with the error Multiple dex files define Landroid/support/v4/accessibility
  • Android failing with snapshot error, install the nativescript snapshot support via
    npm install nativescript-dev-android-snapshot@latest --save-dev
  • TNS no longer building your TypeScript files or livesync'ing any of your TS files.

 

NativeScript - Professional post series

I've been doing NativeScript for a while; and since I'm a contractor/freelancer; and no specific company pays my salary -- I've decided to start putting some of my cool learned tips into the paid category.   Most of these will only qualify if they took me multiple hours to figure out.  Unfortunately nobody pays me for fixing things when they break...  So, if I can use my hard earned knowledge to save you a vast amount of time, what is it worth to you?
All this knowledge is time tested and can save you a vast amount of diagnostic time on why something doesn't work.   So if you think saving you time is worth it; please feel free to sign up and support me; and I will provide the information you need when you need it...
The different series are going to be available on my Patreon site: https://www.patreon.com/NathanaelA
The first series is; NativeScript Platform Differences


You might get an app running perfectly on one platform, and then wonder why it isn't working on the other.   I have started out with a cool post on several issues you might have between iOS and Android using HTTP/HTTPS.

The second series is: Troubleshooting your NativeScript
I have started this series out on dealing with Upgrading from NativeScript  to 2.4 and issues you might face.
The first post in this series deals with a specific iOS upgrading issue.
The second post in this series deal with a specific Android upgrading issue (Error starts with: Multiple dex files), when using several plugins...
The third series is: Ready to Distribute my app...  What now?
The first post in this series deals with a specific iOS Build issues...
The second post in this series deals with a specific iOS Build configuration information.
Some of these posts will be showing up in the next couple day as I have time to finish them off...
And yes; I will continue to post free useful stuff...   😉

NativeScript - Workers

ns-workersOne of the best new features in the brand new 2.4.0 release of NativeScript is WebWorkers.    For those who have seen me around in the community; you will probably all know how long I have been harassing the NativeScript Core Teams to get this done (Since Aug of 2015).  I even went so far as to create a plugin (NativeScript-WebWorkers) that allowed you to spin up more JS threads but with the major limitation that they didn't have access to the native OS side of things, they were only pure JS.    So getting real 100% NativeScript webworkers this release means I am a VERY happy camper!

The feature is fully cross platform (i.e. works on iOS and Android) and allows you to spin up additional JavaScript engines to do all your heavy lifting needs in the background.    Now obviously, the more you spin up the more memory and cpu you will use; so you want to treat them as a precious resource and only spin up those you need.   Let me re-iterate; use these for only heavy duty processes; each worker is another FULL JS engine, which takes a chunk of memory and cpu to just start and maintain.

They still have full access to the iOS and/or Android runtime just like normal.   The only difference between them and the main thread is that you do not have any valid access to the GUI or GUI elements.   You can attempt to modify the GUI, but you will crash your app as you are not allowed in even in a native app to modify the GUI outside the main thread.  Same rules apply to a NativeScript app.

The NativeScript Core Teams modeled the background threads after the web workers model.  They are created, developed and destroyed the same way as a browser web worker would be.   So lets dig in.

Everything is passed via messages between the workers and the main thread; so lets look at a sample demo:

main file

"use strict";
exports.onNavigatingTo = function(args) {
   let myWorker = new Worker('./myWorker.js');
   myWorker.onmessage = function(msg) {
     console.log("Hi I'm a message from the worker: ", msg.data);
     myWorker.terminate();  // We no longer need the worker around, so kill it.
   };
   myWorker.onerror = function(err); {
      console.log("Opps, something went wrong in the worker", err.message);
   };
   setTimeout(function() { worker.postMessage("a Cool Message"); }, 500);
}

myWorker.js
"use strict";
require("globals");
global.onmessage = function(msg) {
  console.log("Got a message form the main thread!", msg.data);
  postMessage("Worker's cool Message");
  // global.close();  // If ran, this would close the worker from inside.
};

global.onerror = function(err) {
  console.log("We can handle our own errors too", err.message);
};

Now as you can see we have two files; the first file is from the main thread it starts the new worker by doing let myWorker = new Worker([path to worker script]); this is how you start a brand new worker.   The new worker will load that JavaScript file and start it up.  Now there are some gotcha's we are going to cover on the worker side that you will want to know about.

  1. You want to require('globals'); as your first or second line.    If you do NOT require the global module, you will not have access to console, setTimeout , setInterval, and any other function you are used to using globally.   So requiring this function is pretty important for most workers.
  2. When you assign .onmessage (or .onerror if you are using it) you must assign them to the global variable.  The new version of the Android engine is enforces "use strict"; properly and having implied "this" variables is NOT allowed.  So as a habit when assigning something to the global scope; implicitly use global.
  3. All messages have a .data parameter that contains the data you sent from the other side.  When you do a postMessage({cool: "wow", I: "am"}); this will be in msg.data.cool and msg.data.I in the onmessage message.  This might catch you, but is easily fixed.  Please make sure that any objects you send across to the other side is fully serializable (i.e. no recursion, no native gui elements) ; if not it will fail unless you use some third party lib to serialize the recursive structure.
  4. Terminate() or Close() the webworker if you are no longer going to use it.  If you are planning on continuing to use it; then leave it running it is cheaper to leave it running (& not doing anything) than to terminate and restart.
  5. If you get an error message like this: Worker Error: Uncaught TypeError: Cannot read property 'prototype' of undefined this can mean it can't find the worker file that you wanted to load.  Using the tilde to say main app folder '~/path/to/worker' is the easiest way to fix it.  OR it can mean that the file that is required is doing something that is causing the worker to crash.
  6. If you see the error: Uncaught TypeError: global.moduleMerge is not a function The solution is to do a require('globals'); at the top of your worker file.

Once you understand these items, you are ready to rock and create cool background threads to do all your busy work so that your main thread never freezes again...