Category Archives: Plugins

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

Plugins.nativescript.rocks upgraded

Behind the scenes PNR (http://plugins.nativescript.rocks) has been upgraded to support several cool new features.

At this moment the largest difference is the backend data storage system has been completely changed; and now has a lot of new data available to it.    This system should allow us to do some more pretty cool things in the future...

By using this new data; I also have a bit more accurate plugin list,    In addition the new system has the ability to track both NativeScript 2.x plugins and separately 3.x.  So on the page you can now see a select list that allows you to change "All" (All plugins), "2.x" plugins that should be only 2.x compatible; and then finally only 3.x compatible.  In addition I took the time to actually drop a physical search bar in the title area; as my virtual search bar seemed to confuse a lot of people.

Play around with it, let me know if you run into any issues.

NativeScript 3.0 Sneak Peek and what it entails for Plugin developers.

For those who are not aware, v3.0 of NativeScript is the next major version that will be released.  It has been being worked on for several months now as it has parts of it have been completely rewritten to enhance speed of the framework in a number of areas.    Some parts of it have undergone radical changes in design, and as such will require changes to plugins to make them compatible.

Unfortunately these changes are a breaking change and will mess up the plugins for a while...

Some pre-release information has trickled out and as such the plugin developers needs to be made aware of these changes, so we can start getting a jump on these changes...

The biggest issue is any plugins that deals with any properties, or stylers has been completely changed.   These plugins will HAVE to be changed to support 3.0.   This means your plugin will no longer be NS <= 2.5 compatible, these are BREAKING changes.

 

Plugin Sites and the Package.json

As an aside if your plugin doesn't have any breaking changes and can continue to work fine in all versions of NS; then I am asking you to add a new flag to your package.json file to flag that this plugin is 3.0 compatible but doesn't require 3.0.

Your package JSON NativeScript section should look like this:

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

The additional "plugin" structure is being introduced  to try and capture the data that has been missing from the plugin infrastructure.  At this moment each item is totally optional.   However, this will allow the plugin sites to categories and filter the plugins based on criteria's that are important to subsets of the users using the plugin sites.  Please see: http://fluentreports.com/blog/?p=489 for more details on the new "plugin" structure proposal.

 

Back to the breaking Changes

The first resource is that some of the NativeScript team produced a video last week https://youtu.be/bwO3cYPb4zQ which will give a decent overview of the changes.

The developers working on the 3.0 project gave a run down of the changes and how they benefit us and/or what changes we need to be concerned about.

The second resource, which I find to be a bit more valuable is this document that is in the source repo.  https://github.com/nativescript/nativescript/blob/master/Modules30Changes.md

They used this document in the above video; but since they only covered an overview and this documents has all the nitty-gritty details.

For this to be a smooth transition I really strongly encourage you on the "core3" attribute be used if you are not just bumping your platforms to 3.0.0.      I will be automatically filtering out plugins that I believe are only 2.0 for 2.0 mode and 3.0 for 3.0 mode.  So  having things tagged correctly will help the end users have a much more painless transition.

 

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: iOS and xCode 8 the wonderful world of breaking changes

native8xcodeFor those who have upgraded to the all new xCode 8, you may have noticed some of the plugins breaking...     The biggest breaking change in NativeScript and xCode 8 is now things deep down in the ObjC runtime that used to be a function call are now a property.

So, for example let say you needed to access UIScreen.mainScreen.

 

 

In xCode 7 this was

var mainScreen = UIScreen.mainScreen();

in xCode 8 this is now:
var mainScreen = UIScreen.mainScreen;

Notice, it is no longer a FUNCTION call.  It is a PROPERTY.   Now how do you make this compatible so your code can run with both xCode 7 and xCode 8.

If you are developing an app; I recommend you use the helper function that Telerik added to NativeScript which they use throughout the core modules.

var utils = require('utils/utils');
var mainScreen = utils.ios.getter(UIScreen, UIScreen.mainScreen);

If you have your own plugin, then I'm going to recommend you embed my code into your own plugin...  The code is basically the same as Teleriks, but you eliminate the require call.
function iosProperty(theClass, theProperty) {
    if (typeof theProperty === "function") {
        // xCode 7 and below
        return theProperty.call(theClass);
    } else {
        // xCode 8+
        return theProperty;
    }
}

Then you use it the exact same way;
var mainScreen = iosProperty(UIScreen, UIScreen.mainScreen);

Happy NativeScripting, and hopefully you can easily get all your plugins updated shortly to support both xCode 7 & 8!

NativeScript: Patreon Posts & Plugins

For those who are unaware; I've started doing paid content; see my post on "Why Patreon" to see the reasons.   I'm going to attempt to keep this post updated with plugins and posts that are available to those who are my patreon supporters.

Posts:

 

Plugins:

 

NativeScript: Android plugins and Windows path size issues

If your on Linux or OSX you can skip this post; it only applies to us pathetic people that prefer Windows (like me ). I do have Linux and OSX, so maybe I'm not that pathetic; but since I do prefer Windows, maybe I am.

If you don't want to read the reason this occurs but all you want is the fix; then scroll down to the fix!

Well if you see this error: Command [Some Path]\gradlew.bat failed with exit code 1 then you more than likely ran into this error if you see a lot of messages above it with "No Delegate Set" and errors.

Well to understand the issue you need to understand that this is a issue between Windows, Gradle and how NativeScript (A fix might show up by v1.8 of NativeScript) currently does Android plugins. Windows, if it supported larger path sizes; this wouldn't be an issue (which is why it works on Mac/Linux). NativeScript if it handled plugins differently might not run into this issue either. But at the current place we are at; it does so here is the crux of the issue.

1. Windows only supports 255 character path sizes (if they are not UNC or Unicode path's)

2. NativeScript scans all your plugins; any that have a platforms/android folder; it will use the include.gradle file found in that folder.  If there is NOT a include.gradle file; it will create one for you using the plugin name as the information.

3. Gradle combines all the productFlavors (which are inside the include.gradle files) into one long string.

Ok, lets look at a sample include.gradle file (this is also what is also generated for you, if it doesn't exist)

android {
    productFlavors {
        "nativescript-websockets" {
            dimension "nativescript-websockets"
        }
    }
}

So lets pretend your code exists at: C:\nativescript\AwesomeProject\, so there is (32) characters. Now add platforms\android\ (18). Next add build\intermediates\res\merged\ (31) as this is where Gradle does its resource merging. So lets say you are using the Telerik NativeScript UI plugin; and lets grab one of the image names \debug\drawable-xxhdpi\someimage.png which is of course adds another 49 characters. So this means we are using 130 characters already; leaving us with 122 characters left to play with.

So if you have a plugin installed like nativescript-websockets you get 23 characters used just for a single plugin. I bet you can see where this is going. Add on the cool nativescript-telerik-ui plugin and you have another 23 characters used. Add just a couple more plugins, and yes -- you are now well over 255 character limit!

Guess what happens???    Well if you are following the story so far; you get a nice error that gradle quit with error 1.

The Fix:

Now for the good news; here is how you can continue developing!

  1. Go to your app folder and do a tns platform remove android to safely recover, you need to kill your existing android platforms folder.
  2. Go into you node_modules folder, and then you need to repeat this next set of steps for EACH of the plugins you have installed.
    • Enter that plugins platforms\android folder and edit the include.gradle -- if that folder doesn't exist then you are done and can skip this plugin.  If the folder exists but the include.gradle file doesn't exist you can choose to ignore it or create your own.  DO NOT create a platforms\android folder, if it doesn't exist. Only create a include.gradle if the plugin already has a platforms\android folder and it doesn't have a include.gradle.
    • Edit the include.gradle and make the name shorter; this is the formula that I used.   Replace nativescript with "ns", eliminate any dashes, and then use the first letter for each word in the plugin.   So "nativescript-cardview" becomes "nscv",and "nativescript-telerik-ui" becomes "nstu". So the include.gradle changes from above (nativescript-websockets) to:
      android {
          productFlavors {
              "nsws" {
                  dimension "nsws"
              }
          }
      }

      Pretty simple huh?   By shorting the name, you go from 23 character per plugin to 4 characters per plugin.   So you can now easily fit 5 plugins in the same space it used to take for 1 plugin.  Please make sure the total letters are unique -- don't have two plugins with the same name (i.e. "nsws" for nativescript-websockets and nativescript-webserver)  as the same name, make them distinct.  Having duplicate names will probably break Gradle.
  3. Do a nativescript platform add android to re-install the platform after you are all done, and then you should be good to go.

Please note this potential side effect: I have confirmation below that if you are using a plugin that requires additional permissions; this work around will unfortunately not merge the info from the plugins AndroidManifest.xml file.   With all the plugins I had, I never saw this issue; but depending on what you are doing this is something you may run into.   You have two choices to deal with this:

  1. Don't rename that specific plugin inside the include.gradle file.  This way the AndroidManifest.xml file will get merged properly.   You an afford a couple plugins to still have large names.
  2. Copy the information that you need (like permissions) from the plugins AndroidManifest and manually merge it into your master manifest located at App/App_Resources/Android/AndroidManifest.xml

The bug report so you can track this is Android/369 and based on the conversation with the NativeScript devs this should hopefully be fixed in v1.8 (but no promises).

NativeScript: Announcing {N} plugin tracking site

If you are like me occasionally you have to find a plugin and you go and check the npmjs.com site and do a search for NativeScript and then peruse a ton of entries; some relevant and some not so much.

Well, last night as I was finally working on updating my manually done plugin list (http://github.com/nathanaela/nativescript-plugins) ; I realized that the number of plugins was just getting to be too great for me to now be manually tracking them all.

So I set out to create something that could automate everything; I found a site/project called react.parts that was open source.  I quickly downloaded the source and glanced through it and promptly borrowed the data updater component.   I made a huge number of changes to the updater, some was just fixing some bugs and some was that I needed totally different fields for my purpose.    I am happy to announce today it runs on one of my servers every night getting and building the dataset for the all new NativeScript plugin site:

http://plugins.nativescript.rocks

The site as of today, Feb 18, 2016, the site lists 86 different plugins, my old manual list only had 45.   As the authors fill in data in the plugins, the data will automatically be updated and added.

We have a total of 33 different authors making NativeScript plugins!   Not bad for less than a year, and Eddy Verbruggen has the most plugins; at a count of 12 of them!  Wow, way to go Eddy!

For you plugin authors you need to make sure you have in your main package.json, the following items to get listed properly.   Some of these items if missing will be considered a minor issue; others will cause your plugin to NOT show up.  At this time you MUST have a link to the github repo that hosts it, you also must have either "nativescript" or "{N}" in your keywords.

If you want the Windows, iOS or Android icon to show up on your plugin, you need to use one of those key words also in your "keywords" OR you need to make sure you have them in your nativescript.platforms object.

Please make sure you include a version, and a license field; this is very helpful for people to quickly see in the list.  And example of the fields is what I use for my nativescript-zxing plugin.

{
  "name": "nativescript-zxing",
  "version": "1.0.0",
  "description": "A Simple ZXing barcode reader/writer wrapper",
  "main": "zxing.js",
  "nativescript": {
   "platforms": {
      "android": "1.4.0",
        "ios": "1.4.0"
   }
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/nathanaela/nativescript-zxing.git"
  },
  "keywords": [
    "NativeScript", "Barcode", "JavaScript", "Android", "iOS", "ZXing"
  ],
  "author": {
    "name": "Nathanael Anderson",
    "email": "nathan@master-technology.com"
  },
  "bugs": {
    "url": "https://github.com/nathanaela/nativescript-zxing/issues"
  },
  "license": {
    "type": "APACHE",
    "url": "https://github.com/nathanaela/nativescript-zxing/blob/master/LICENSE"
  },
  "homepage": "https://github.com/nathanaela/nativescript-zxing",
  "readmeFilename": "README.md"
}

Please note, it updates the data nightly, so if you submit changes; and you don't see it show up in 24 hours; ping me and I'll check into what is going on...