Author Archives: Nathanael Anderson

NativeScript: Plugins - Let Fix the Data!

Some of you might not be aware but I wrote the plugins.nativescript.rocks.   I also helped write the plugins.nativescript.org site (if something doesn't work on plugins.nativescript.org; please blame my cohorts in crime, Nathan Walker and George Edwards.   I had NOTHING to do with any bugs!  😛  )

Well, with the new upcoming changes in 3.0 and some data that we have been unable to determine I have decided to request that the plugin authors add a little bit more metadata to the package.json file that comes with the plugin.

So lets look at the existing "nativescript" key.

"nativescript": {
   "platforms": {
      "android": "2.3.0",
      "ios": "2.3.0"
    }
 },

This tells nativescript which version of NativeScript runttimes are supported.   This allows the TNS command line to throw and error/warning if you are not using the proper versions.   This is useful information as this tells us what platforms are supported.   However, this fails when people (like me) write dummy wrappers to support the plugin not crashing on the other platform.     On the plugins site it will say this plugin supports both Android and iOS, but in all reality the plugin only really supports iOS, and actually doesn't really do anything on Android.    I would like to have the plugins site actually reflect this reality rather than you downloading a plugin you thing works on Android and it turns out it doesn't.

In addition since Angular was introduced to the eco-system, there are a large number of plugins that actually do NOT work with NAN (NativeScript Angular) code.   And even some that don't work with PAN (Plain Awesome NativeScript) code.  In addition in the future we might get other frameworks supported like VueJS (VAN?), etc.

So I would like to start capturing the data so that we can do these additional cool things.   And so I am proposing the following additional OPTIONAL meta data to be added.

"nativescript": {
   "platforms": {
      "android": "2.3.0",
      "ios": "2.3.0"
    },
    "plugin": {
       "nan": "false",
       "pan": "true",
       "core3": "true",
       "wrapper": "ios",
       "category": "visual"
    }
 },

nan = NativeScript ANgular will be assumed to be false, unless Angular is detected in the Keywords/name/description.
pan = Plain Awesome NativeScript Will be assumed to be true.
core3 = Supports NS Core Modules 3. Will be assumed FALSE if platforms.ios/.android < 3
Will be assumed TRUE if platforms.ios/andorid >= 3.
wrapper = Using a dummy wrapper Will default to false, use "ios" or "android" to signify platform which is using a wrapper.
category This is the category to put the plugin in.   Valid categories currently are: "Interface", "Processing", "Templates", "Developer", "Utilities"

I am up for other category suggestions.   But at this point these are the primary categories that I use on plugins.nativescript.rocks.

Please note each key is optional; however, your plugin will get extra points for having an category key.  And you will LOSE points if we detect a plugin is using a wrapper and you haven't tagged it, as this is a issue the plugin users really hate seeing faulty data about the plugins support.

I would recommend plugin authors start adding this to any releases of there plugins so that we can capture the data.  This will become critical with the 3.0 release as a large chunk of plugins are not going to be compatible between NS 2 & NS 3.

NativeScript 2.5.0 - Released

Some of you might have seen the all New version 2.5.0 has been released today.  For the first time that I can recall; Telerik has actually beat me to the release news.   You can read the official blog post here.

Some of the new features

  • Better Debugging using Chrome Developer tools
  • Working Webpack 2.0
  • Flexbox layout fixes
  • Updated Android Runtime Engine (even more ES6 support)
  • More css support for ActionBar
  • Lots of bug fixes

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

Next try the new update command
> tns update

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

Some Changes

  1. tns run does not work the same way anymore; it is now equal to tns livesync --watch
  2. To actually "rebuild" the app; use tns run android --clean

Common Issues:

  1. In some cases when doing a tns platfrom add android, the package.json file gets a entry in the dependencies section for "tns-android": "^2.5.0" which will cause any following builds to fail with the error code: the plugin tns-android is already installed.   Fix: Delete it out the package.json.
  2. ActionBar items -- backgroundColor do not use color names; only use Hex values.  Using color names can cause the app to crash.
  3. Android --release apps and error about can't find package "nativescript-snapshot@x.y.z" or "nativescript-angular-snapshot@x.y.z" in the registry.     A couple things can be causing this; first make sure you have updated everything.   Second, occasionally the hooks folder gets out of sync, you might have to delete your hooks & node_modules folder and do a npm i to reinstall everything.

 

NativeScript Android Snapshots

For those who haven't deployed any apps in v2.4 of NativeScript; one of the new features that is turned on by default is SnapShots.    Now most the time this is a AWESOME thing, however occasionally this can cause issues.   For example I have one app of mine that this crashes at startup when using SnapShots.

Now the docs do list how to disable snapshots; but it is a lot easier for me to find the notes on my own site than trying to figure out which doc has the info.

The environmental variable you need to adjust is: <strong>TNS_ANDROID_SNAPSHOT</strong>

  • 0 = Force Snapshots off always
  • 1 = Force snapshots on (including in debug mode)
  • Unset = Snapshots only in Release mode

Allowing TypeScript to understand NativeScripts ~/ home path

I know a wide number of you use TypeScript; well one of the irritations I've had with TypeScript -- I just figured out how to solve.   Finally did some research and tests to figure out how to make TypeScript support using ~/ as a normal path for building and determining editor intellisense since this is a special path in NativeScript meaning the home app path.   Using this path in a import / require statement means you can do something like this.

/app/views/login/login.ts ->

import * as animation from '~/support/animation'
and it will load in the file at   /app/support/animation

You can use relative paths, but I find absolute path's a lot easier to read and understand exactly which file is being loaded.   In addition things like my NativeScript-Updater can't use relative path's (do to some low level issues in the iOS runtimes) and determine if a file has been updated.

Ok, so the solution: open your tsconfig.json file and add the following:

"baseUrl": ".",
"paths": {
   "~/*": [
     "./*"
   ]
  }

To the "compilerOptions" key in the json file.

Amazon Tablets - Jailbreaking / Rooting

Amazon sales some decent little tablets called the Amazon Fire 7", add one of there decent kids cases and the tablet is great for letting the kids use for a ereader, comics, games, notes, Zork, and many other tasks that a normal Android compatible touch screen devices can do. All for the grand total of $50 for the android device, and $20 for the case.   So around $70 you have unit that is perfect for kids.

Now with this unit there is a couple of small gotcha; by default it comes with a silly advertising screen saver and it is tied completely to the Amazon eco-system.   For those who aren't interested in Advertising there is two options; one you can pay Amazon $15 to eliminate the advertising, or you can remove it yourself.   Now many of you know me; So I'm sure you can guess which way I did it. 🙂

The second issue is that it only has a 3 month warranty; they DO sell a "kids" version for $99 that comes with the case, removal of the ads and a two year warranty.   So the cost difference between the two is negligible if you want a two year warranty, this is your better bet and you don't have to do anything to eliminate the ads as it comes already without ads.

This device is not a bad little tablet; and my kids fight sometimes over who gets which one of the them that we have.


Now on to why most of you are probably viewing this blog post; I prefer to have full control over any device that enters my house.   So guess what my choice was.  Yep, I eliminated the ads and "root"ed the device.   If that sounds scary; it really isn't.   You just do a couple steps; install some software and boom your done and have a fully open Android tablet.  Please note this can void your warranty and you have a chance you can mess up your device.   No warranty is provided and I don't provide free tech support.  😉 Please note this only works on Amazon Kindle fire 5.3.1 and lower, if you are running 5.3.2; you need to downgrade to 5.3.1 before doing this. There are videos to help you do this.

Please note; by doing this you might eliminate the ability for Amazon's Alexa, freeplace, prime videos, kindle free books from working.   I do have a prime account; but I don't have anything on Amazon I want the kids to have "easy" access too; so I honestly haven't tried any of the prime services on my fire's.   I'm pretty sure the Kindle e-reader app continues to work fine; but no guarantees.    I don't believe my fire's are babysitters, so no video access is given to them.  If they want to be entertained they can read a book.  😉

First things first; you need the tools.  You need to download the link on here:

http://rootjunkysdl.com/files/?dir=Amazon%20Fire%205th%20gen/SuperTool

The file is currently called AmazonFire5thGenSuperTool.zip and it is around 152MB's

After you download it and extract it to a folder; you need to install the ADB drivers; the best tutorial I've seen if you like video's is the author of this tool; "Root Junky" video tutorials which you can watch on http://www.rootjunky.com/amazon-fire-5th-gen-supertool/

If you prefer text and pictures http://www.makeuseof.com/tag/install-google-play-remove-lockscreen-ads-amazon-fire-tablet-without-root/

Now I'm not going to repeat those tutorials; The things I did to make everything work was option 1. ADB Driver Install, then 2. Install Google Play and remove ads from Lock Screen, then 7. Root your Amazon Fire fifth gen, and finally 8. Replace Amazon Fire Launcher with Nova Laucher.
1. ADB Driver Install -- This is required so that the software on your computer can talk to the Amazon Fire, so this has to be done FIRST, and must be working, for everything else to work.  This can be tricky depending on the OS; if you are using Windows 8 or 10; you have to disable driver signing; which you can see how to do in the Text and pictures link.

2. Install Google Play / Remove ads -- well I don't like ads, and I want Google play to be able to install other things, that I mention below.

7. Root your amazon fire; this is if you want to be able to control things; I happen to like putting a firewall on my devices.  This allows me to block all applications from connecting to the internet and dialing home and/or pulling down ads inside of them.    This is not needed; but I personally prefer it.  The firewall I use is called "AFWall+" and can be got for free on the Google Play store. (But you must be rooted to use it).   There are a couple other tools I use on my devices that require root; but I'm a developer so they probably won't interest you.  😉

8. Replace the Amazon Fire launcher with Nova Launcher.  Nova Launcher is a pretty good default launcher; if you like the Amazon launcher; then no need to do this.  But I don't and I find it very limiting and it is very much tied to the Amazon eco-system.  So I install Nova Launcher; then I installed another app called "Kids Place" this allows you to setup a simple to use Launcher for the kids; where I can pick the apps they can run, when they are allowed to be ran and other "kid" friendly items. This "Kids" place runs in its own sandbox and limits the kids to pretty much only the apps you allow it. It has some "holes" that my crafty kids have discovered, but the holes are pretty minor and don't cause any real issues since the firewall blocks access from any app that I've decided doesn't need internet access.

I tend to disable the internet on the tablet, pre-install a ton of books, apps, comics and other items. I have also purchased a License for Moon Reader (My favorite e-reader app), and Aldiko Premium. And so I install these along with FBReader on all my Fire's so that the kids can choose which e-reader they like.  In addition I typically install a couple learning games (for the non-readers), drawing, and even a comic book reader; as everyone loves comics.

If you want to allow your kids access to the internet from the device; I would install the Brave browser as it has built in ability to eliminate ads and tracking which is what you want for your kids. The other thing you might consider is changing the DNS to use a family/kid friendly provider. You can do it on the device; or if you have a smart router; you can tell your router to server a kid friendly dns to a specific device. OpenDNS & Norton both provide free kid friendly dns servers.

None of this is totally bulletproof and you still have to be a parent; but it does make my life a lot easier and I have no concerns about any of the kids taking any of the fires in their rooms and using them.

 

MySQL SSL required connection Ubuntu solutions

I went to implement MySQL replication for a client this evening and ran into some interesting issues that I haven't ran into before. Guess it has been a while since I had to set it up from a client.   So this post is for notes for me or someone else who might need to do this in the future. The normal installation replication installation works great but if you are going to enable ssl connections this is where the things can get a bit more complex.

The first thing to find out is if you have your SSL setup correct, try doing:
And verify the SSL is enabled and build in, in my case everything looked good:

mysql> SHOW VARIABLES LIKE '%ssl%';

have_openssl  = YES
have_ssl      = YES
ssl_ca        = /etc/mysql/certs/ca-cert.pem
ssl_capath    =
ssl_cert      = /etc/mysql/certs/server-cert.pem
ssl_cipher    =
ssl_crl       =
ssl_crlpath   =
ssl_key       = /etc/mysql/certs/server-key.pem\";

This looks correct, so the next thing to figure out is where the error log file is located;
mysql> SHOW VARIABLES LIKE '%error_log%';

log_error     =  ./mysql-bin.err
or something like
log_error     = /var/log/mysql/error.log

Now that you know where the error log is at you can see why it is failing.

In my case the error was this:

2016-12-06 23:21:33 32695 [Warning] Failed to setup SSL
2016-12-06 23:21:33 32695 [Warning] SSL error: SSL_CTX_set_default_verify_paths failed

I love that it is a "Warning".   It is totally broken, but we will list it as a Warning...

Well, this can be caused by several things:

  1. No permissions to the files in the folder, use chmod/chown to give perms.
  2. SELinux blocking it, disable selinux or grant permissions via SELinux
  3. AppArmor blocking it.  (this was my case)

Edit the /etc/apparmor.d/usr.sbin.mysqld file.

You'll see something like this in the file:

/etc/mysql/*.pem r,
/etc/mysql/conf.d/ r,
/etc/mysql/conf.d/* r,
/etc/mysql/*.cnf r,
---> /etc/mysql/certs/*.pem r,  <---
/usr/lib/mysql/plugin/ r,

Add the ---> line <---, make sure it matches your path to where you are storing the certs.  Then restart mysql. After restarting the server, I then got this error: SSL error: Unable to get private key from '/etc/mysql/certs/server-key.pem' 2016-12-06 23:53:32 21728 [Warning] Failed to setup SSL 2016-12-06 23:53:32 21728 [Warning] SSL error: Unable to get private key Ok, this one threw me for a while.  The files are fully readable by MySQL.  The issue ends up being incompatibilities between SSL libraries in use.  OpenSSL 1.0x vs yaSSL The key file will start like this:
-----BEGIN PRIVATE KEY-----
If you used OpenSSL to generate the keys;  OpenSSL creates keys in PKCS#8 with a SHA256 digest.  Of course yaSSL which is (normally) used by MySQL doesn't support either, and want PKCS#1.  So despite having the files fully readable, MySQL is telling you it can't figure out how to "get the private key" out of the file.  Once you know the issue, it has a simple solution:
openssl rsa -in server-key.pem -out server-key.pem
when you are done with this command the beginning of the file should look like this:
-----BEGIN RSA PRIVATE KEY-----
Again, the internal format is different, so don't try and just change the text and insert the "RSA" into it -- it will look like it works until something try's to connect using SSL. Once you have this done, restart mysql again and you should be good to go.

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

NativeScript Testing: Developer Days Video

I just noticed my video from my presentation was released.  This was the presentation that I did at #NativeScript Developer Day in Sept of 2016.   The subject was Testing your NativeScript app and dealt with both Unit Testing and End to End testing.

I saw a couple of "um" mistakes.    I "um" need to "um" work on "um" removing some "um"'s.  😉

Here are the questions at the end (since like an idiot, I also totally spaced about repeating them) are:
1. What about testing Angular2 NativeScript apps.
2. What about Code Coverage .

Slides Deck:
http://fluentreports.com/blog/wp-content/uploads/2016/09/NativeScript-Testing.pdf

Demo "Carder" App I wrote and used, includes all the tests:
https://github.com/NathanaelA/carder

Detailed Blog posts about this subject covering the video:
Part 1 - Unit Testing
Part 2 - End to End Testing