Category Archives: Uncategorized

NativeScript - DynamicLoader

logo-dynamicI'm happy to announce my latest commercial plugin; this one is a bit different then most of my plugins.

I ran into a situation while benchmarking one of my apps where the parsing of the Declarative UI XML files and the building out of a fairly complex layout cost me a couple seconds of time when navigating to this screen.   I then found out that the majority of the time was spent building a part of the app that was completely hidden.  So, I had to find a way to mitigate this...

Enter my newest plugin, what I have built with this plugin is the ability for you to dynamically load (& unload) any chunk of Declarative UI XML (and its associated JavaScript file) into any UI element that accepts at least a single child.

I have a sample github repo using the new plugin, showing how easy it is to use the plugin, and a full demo showing different ways to use the plugin.

Everything in the Blue box is totally loaded dynamically from all the different Declarative UI XML files that are located in the /views/ folders that you can see in the github repo.

nativescript-dl0 nativescript-dl3

You can purchase this plugin at: http://nativescript.tools/product/16

NativeScript: CSS Selectors & Pseudo Selectors in 2.2.0

The NativeScript team released a feature under the cover of dark; not even listed in the change log; but Panayot; did a refactoring of the CSS selector system in NativeScript. With his changes he has not only sped up the selector code in most cases but he added some additional features like

[myAttrib="yes"] > .figure { color: red; }

And fixed several things that were broken in earlier versions like:

 .android.landscape  Button {  background-color: blue; }
.landscape.ios Button { background-color: green; }

If you understand why this is so important; this opens up CSS a LOT.   For example; I have two plugins; nativescript-orientation, and nativescript-platform-css.    Orientation automatically will put landscape as a class of the <Page> when you are in landscape mode; this allows you to have custom css for landscape mode.   It allows a lot of flexibility.   However, when I created the platform-css plugin it automatically adds ios or android to the Page classes.  Again this added a lot of flexibility as you could in a single css file do:

Button.ios { margin: 20; }
Button.android { margin: 15; }

To allow you to style the buttons so they look properly on each platform.   However the OLD CSS style system would not detect that "landscape ios" should use the rule:

.landscape.ios Button {}
or
.ios.landscape Button {}

So, originally  I had to add a HACK to my NS-orientation plugin to detect if you were using my platform-css plugin so that it could create a special css class rule to allow the second rule (.ios.landscape) to work as expected.   Now with the all new css selector system in 2.2.0; it all works properly; and ALL variations of the rules are valid and I don't have to do anything extra!

Major Kudos from me to Panayot!   This fixed a number of other weird CSS corner cases that have been in the issues list for a while.  So this was a imho one of the best new features of 2.2.0...

Now, there is another awesome new feature that Panayot did; he has pseudo selectors; at this moment the button now supports both a normal state and a highlighted state.  So you can do:

Button:highlighted {
background-color: cyan;
}nativescript-pseudo

And the button will change to a cyan background when clicked and on Android 5+ you will still even get the ripples!    Awesome job Panayot!

NativeScript: Version 2.2.0 released

ns-2.2.0For those living in a dungeon hacking out code; guess what was released by those fine wizards at Telerik today!     Yes, you got it - v2.2.0 of NativeScript is now available!   Upgrade Instructions below.

As usual; if you run into any issues I will be putting any common issues at the bottom of this post as I and others run into them....

New or Fixed Features:

  • Android now properly supports some the of the Java classes that were broken in 2.1 (Major)
  • Nested Bindables
  • Letter Spacing is now all in EM Units (CSS: letter-spacing)
  • CSS supports new properties, more selectors and even pseudo selectors (Major)
  • Android Launch Screen Support
  • Observable's are now auto-nesting (this can cause a breaking changes -- see known issues below)

A Lot of other smaller bug fixes and enhancements went into place; unfortunately the really big feature for 2.2.0 has slipped -- threads.   It was bigger than a single point release could handle; I've seen progress on both Android and iOS on this front; so I have high hopes it will make it in 2.3.0...

Upgrading:

First of all to upgrade is done is a couple steps:
> npm install -g nativescript
> 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.2.x

 

Common Issues

Nested Observables might throw an error

(iOS) TypeError: Cannot set property 'disableNotifications' of undefined
(Android) TypeError: undefined is not an object

If you have objects like

var x = new Observable({
y: new ObservableArray([])
});

This will probably throw the above error; eliminate the nesting; and make the structure like this:

var x = new Observable({
y: []
});

Github issue: https://github.com/NativeScript/NativeScript/issues/2457

x86_64 bit Emulator on iOS might crash on code that is fine.

Error:

Service exited due to signal: Segmentation fault: 11

Solution: Switch to a 32bit emulator like the iPhone 4s.

Github Issue: https://github.com/NativeScript/ios-runtime/issues/622

 

Angular 2 cssClasses Incompatibility

ORIGINAL EXCEPTION: TypeError: _this.cssClasses(...).set is not a function

You need to upgrade your NativeScript-Angular version to the latest version; the older version which worked with v2.1.0 of NativeScript is incompatible with v2.2.0. You should be able to do a

> npm install nativescipt-angular@latest --save

 

Introducing tns-template-plugin

If you create plugins, I've created a awesome shell that will basically build out your entire plugin folder structure after asking you a couple questions.   This is standalone, you don't need anything beyond what you should already have (npm/node).   It has ability to create plugins in a variety of ways...

It will automatically create (and embed info inside them):

  • License
  • Readme
  • Source code file(s)
  • Demo
  • tsconfig (if needed)
  • package.json
  • ignore files
  • Additional support files

The plugin generator will asks you about 10 questions initially; but it is smart enough to save the common ones (like name, email, github) so that in the future it won't need to ask you again.   In addition to being able to generate complete plugins for both JavaScript and TypeScript, it can also use your own "masters" of the files to generate the plugin if you have your own basic look/feel for all those files.

To use is very simple:

git clone https://github.com/NathanaelA/tns-template-plugin nativescript-somename
cd nativescript-somename
npm start

Answer some questions, and bam you have a full plugin all designed and ready for git and npm...

My goal is to be able to eventually do a tns plugin create somename or tns create nativescript-somename --template plugin and I have a enhancement report in the CLI repo to allow this; but until that time, you can do the three steps above...

NativeScript: Declarative UI not updating?

stop-nsThis is just a heads up so that others don't waste the time I wasted; trying to figure it out...

So, I've been working all day on a really cool NS app for a client; made LOTS of graphical changes;  Gradients, shadows, borders, opacity, custom built fonts, themes, tap effects, etc -- looks and acts really sweet...

So I start the app up again and it changes several fields frequently so all of a sudden the display appears locked up; none of the values are changing while just watching it...   I click on a button and the display updates; properly.  Weird.  So I do it again, and again it freezes about 10 seconds into doing updates; interacting with certain things in the app and bam the display starts updating again; and 5 seconds later it the ui stops and is no longer updating again...   Argh...  Inconsistent issues are hard to trace..

So I run the copy of the app that I had deployed to my actual phone from this morning; and everything works great -- not as pretty; but no display glitches.

Ok, so now I'm thinking some change I did has broken the Observables some how, maybe the Obs notification is crashing, or being eaten.  So I start debugging and basically waste about a bit of time tracing things back and even add code to verify that the Observable is sending property change notices properly...   So, after doing a bit of work, everything programmatically looks correct; everything is still bound, the binding context is still valid; the Observable is sending the updates properly; everything looks correct in memory; just the labels don't update...

I start writing up an issue in the NS repo to ask for some more pointers on how to trace down why an Observable is sending notifications, the label is bound and listening; and the label actually shows the updates for a random numbers of seconds but then just randomly stops updating (but can be "kicked" by doing things in the app)..  Yes, that weird of a problem.

Well, before I finish writing up the issue I decide to try a hail-mary as my dad would say.  I killed the emulator; started it back up and....   Everything works....    Ugh, wasted a lot of time; but the good new is it wasn't my app -- my app works great...

So the point of this story -- if you start getting any unexpected random display update glitches; try rebooting the emulator...

 

NativeScript: TypeScript Speed/Memory usage

For those who may have seen some post of mine on Slack about TypeScript being not a performant as JavaScript; I have finally done the real benchmarks and spent the time totally de-typescriptifing the NativeScript 2.00 runtimes.  And here is my startling results....

everythingyouknowiswrong

(c) 2010, Jan-Willem Reusink - https://www.flickr.com/photos/jimmybenson

Oh, wait; that is not right -- I was the one wrong.  😉

The actual real numbers do not bear out what I had believed based on some TypeScript tests that I had done in Node a while back.  I am still not sure why my initial tests in Node behaved differently; but after spending a couple days building the tests, using a large JS application and a totally de-typescriptified the NativeScript runtime, I can say without a doubt in my mind that TS add little to no meaningful hit to the runtimes.  On iOS I actually didn't see a memory difference at all, the GC seems to collect the memory so quickly, that it wasn't even showing up.    On android it takes about 40-60 more megabytes of memory for everything; however after the first GC, all the memory is reclaimed.     So yes, you do end up with a small amount wasted memory and GC pressure added.  However, with it ALL being reclaimed at the first GC; 40mb temporarily wasted really is a drop in the bucket for what TS does offer you.

The other thing that I was surprised by was that the TS runtimes actually started up faster than the pure JS versions.  Now that I had to reason through why TS code was starting faster than raw JS; it makes a lot of sense -- The reason why is because most classes are lazy instantiated.  So the amount of JS code actually compiled and ran by the v8/JSC engines are a lot smaller in TS compiled code because the majority of the code is inside the function that wraps each class.   So if a class isn't needed yet during startup (but is loaded via the require statements) then the time it spends running it is minuscule compared to a runtime that actually builds all the classes while it is loading each one.  So, even though the difference was in literally milliseconds, it still was measurable.  Eventually when you do have that class instanciated; you will have more time used their; but since each class being created later is literally measured in NanoSeconds, the hit later actually "feels" faster to the user since time to first pixel ended up being faster using TypeScript code...

Actual numbers (best of):

Startup time TS: 393,675,213 (NanoSeconds)
Startup time JS:  399,058,778 (NanoSeconds)

Memory Usage TS: 7,544,460 (Bytes)
Memory Usage JS: 7,488,292 (Bytes)

Memory after GC TS: 4,979,548 (Bytes)
Memory after GC JS: 4,993,268 (Bytes)

Please note the reason why GC JS is actually bigger than GC'd TS is more (all) classes have been defined, created and are in memory as real objects vs the raw un-instanciated source code in TS if they haven't been used yet.

So, guess what I am going to be using more of....  😉

NativeScript and WebWorkers/Threads

gears-148196_960_720So about 10 months ago, I put in an issue for adding threads/workers to NativeScript.  I realized early on this was a major feature that is missing.  10 months later, I still have that same opinion; the only real major feature NativeScript is really missing is background threads.   For a lot of projects this won't have an effect; but their are those that need to do processing and this missing feature is a major problem for these types of applications as there has not been a good way to work around it.

Well mid-last week, a user x4080 posted a question about if WebViews main thread is tied to the NativeScript main thread or if it could be used as another thread.  Light bulb went on in my head --  awesome thinking outside the box by x4080!     I quickly created a test framework using an existing app I had written and tested it.   The threads are distinct!   Fast forward a couple days and today, I am happy to announce nativescript-webworkers!   I have wrapped everything up on Android so that it works like a just like a traditional WebWorker with extras!  iOS support should be later this week.

To install you just need to do the standard nativescript plugin add nativescript-webworkers then you can follow my simple sample in the docs or any of the countless myriad of webworker examples on the web.   This does obviously increase the ram required and their is a startup cost for the webworker to be primed and ready to run.    But if you have any processing you don't want on the main thread; we now have a solution that should solve most use cases where more than one thread is needed.

 

 

 

Upgrading to NativeScript v.Next (From pre-release nightly masters)

Please note these are how to install the newest pre-release; based on my experience with the current nightly pre-release masters available at http://nativescripts.rocks.

The first thing you MUST do is upgrade your NativeScript Command Line utility, first.     The easist way is to do a: npm remove nativescript -g

Yes, we need to de-install the current version; trust me it is easier this way.

Next thing if you are doing anything with Android; you want to do is type "gradle" and see if it runs.  If it doesn't run from the command line you need to either install gradle or set your path to use it.   If you have Android Studio installed; gradle is including with Android Studio, so you don't have to install it again.  For example on my Windows machine; my gradle is located at: C:\Program Files (x86)\Android\android-studio\gradle\gradle-2.4\bin.   If you are using Ubuntu, the version included is really old and you will need to install a ppa from: https://launchpad.net/~cwchien/+archive/ubuntu/gradle Then you will be able to do a sudo apt-get update && sudo apt-get install gradle and get a much more recent version.   On a Macintosh, it is recommended you install brew, and then do a brew install gradle.   You can alternatively download and install it directly from https://gradle.org/

The next thing you need to make sure is that you have your ANDROID_HOME and JAVA_HOME environmental variables set.   If you don't have them set you will get WEIRD unrelated errors when trying to do things with the new version of the NativeScript command line tool.

Then you download the latest master nativescript-cli-master.tgz from nativescript.rocks.  Then type:  npm install nativescript-cli-master.tgz -g

If everything worked fine; you should be able to do: tns --version and you will see  the next version number plus "non-ci".

Now that you have your updated command line; you next want to download your platform(s); tns-android-master.tgz and/or tns-ios-master.tgz.   You will next need to do a
tns platform remove android ----- WARNING!!!  THIS WILL DELETE EVERYTHING IN YOUR platform/android folder.   If you have anything you customized (i.e. like the androidmanifest.xml file); you will want to copy it out first... WARNING!!!!

Then you can run tns platform add android --frameworkPath=tns-android-master.tgz assuming the tns-android-master.tgz file is in the same folder where you are running the tns command.    Please note the --frameworkPath is case sensitive; and you need to point it to the entire path wherever the tns-android-master.tgz or tns-ios-master.tgz files are located at.   I typically put them in the parent folder that contains all my nativescript project folders, so then I can do tns platform add android --frameworkPath=../tns-android-master.tgz from any of the projects.

The final piece is updating the common core (tns-core-modules-master.tgz).  Now in some cases you can skip installing the new CLI & Runtimes and just use the core.  I haven't tried to see if the new common core library is compatible with the older runtimes; but I in a lot of cases initially they are compatible, but close to the middle of the development they typically are now relying on a new feature exposed in the the runtimes.   So it is always safer to keep the updated together.

In version 1.3 the tns_module folder in the app folder has been depreciated and is no longer used.   So you can just delete the app/tns_modules folder.   The new location is in the node_modules folder; so you can now do a npm install tns-core-modules-master.tgz

And finally after everything is all done; you do a:
tns prepare android
and/or
tns prepare ios

And you are now running on the latest masters!

NativeScript Nightly Masters

For those who would like to live on the bleeding edge; I have started the process of having one of my servers build each of the different NativeScript repo's nightly from the master branch. You can now download any of these from NativeScript.rocks.

Currently done are:

  • NativeScript Common/Core Library
  • NativeScript Command Line Interface
  • NativeScript TypeScript Declarations
  • NativeScrtip Android Runtime

The Android runtime does automatically have my LiveSync patches; so you will be able to use any of the masters with my LiveSync plugin.

I am in the process of getting the iOS runtime building (I believe I have pretty much everything I need to make it to work). However, I still need to purchase a Apple Developer Key for the server, to hopefully complete it. Since I am a contract developer; this last part will have to wait until I have some extra funds to fund this part of the project (which hopefully will be in the next couple of weeks)...

Update (2015-14-09): I may have a way to build the iOS without a key thanks to Yavor Georgiev; I will be testing this soon...

Fonter - A Simple NativeScript Font Application for iOS and Android

[[ A updated version of this post has been posted for NativeScript v1.5+ and icon fonts here. ]]

Since the subject of Fonts has been causing issues for multiple people in the NativeScript community I figured I would write up a post on how to do it.

Attached to this post is the completed project.    First thing you need to do is a
tns create project fonter -- then cd fonter and tns platform add android or tns platform add ios.   Now your project is ready to go.  I deleted the app/main-page.js and the app/main-view-model.js in this sample app, since they are not needed.

Next thing we need are some fonts.   So I go to https://Google.com/fonts and look at several fonts and pick a couple fonts and download them.  (Please note you actually have to download the fonts from https://github.com/google/fonts)   To keep things simple, all three fonts are under the SIL Open Font License: http://scripts.sil.org/OFL

font-folder

Second thing we need to do navigate to your app folder, and create a new "fonts" folder like so:

This folder MUST be named the exactly "fonts", no upper case letters.  It must be all lower case letters, exactly "fonts".

 

font-list

The next thing we will do is copy the fonts you downloaded into your fonts folder.   In my case I downloaded Indie Flower, Josefin Sans, and Lobster.  So my folder looks like this:
So we have three fonts that we want to add to the CSS.  In my case I want these fonts globally in the application so I will open up the app.css file; and add the three following changes:


.Lobster {
font-family: Lobster-Regular;
}

.IndieFlower {
font-family: IndieFlower;
}

.JosefinSans {
font-family: JosefinSans-Regular;
}

You might notice; the font-family name is the EXACT SAME SPELLING and EXACT SAME CASE of each of the file names.  The only thing that is removed is the .ttf extension.   This is REQUIRED for Android.  Android will automatically load the file (with the .ttf) referenced in the font-family from the fonts folder.

On iOS we have to do something slightly different; we have to register them before use.  If you open up the app.js file, you need to add the following code to it, as you see just BEFORE the application.start().


if (application.ios) {
var fontModule = require("ui/styling/font");
fontModule.ios.registerFont("IndieFlower.ttf");
fontModule.ios.registerFont("JosefinSans-Regular.ttf");
fontModule.ios.registerFont("Lobster-Regular.ttf");
}
application.start();

Again, you will notice the file name is spelled and cased exactly the same as the file name on in your fonts folder.   This is important!    However you name the file; both the iOS registration and the android css declarations MUST be exactly the same.

At this moment, the fonts are registered and usable on both iOS and Android.   So lets show them.   Open up your main-page.xml and here is the code I used:



<label></label>
<label></label>
<label></label>

fonts-androidSo now we want to try the code.  tns run ios --emulator or tns run android --emulator.  On Android everything should work perfectly and you should see something like this.

 

 

 

Unfortunately on iOS it isn't as simple, when you run this project you will see that Lobster and Indie Flower work properly, but Josefin Sans is defaulting to the default font...

font-titlebar-osxHere is the "small gotcha" on iOS.   The font is registered under its actual font name, not under the file name.   So we have one more step you need to do; and you can do it in either OSX or Windows.  Go to your fonts folder and double click on the JosefinSans-Regular.ttf and you should see a window like either of these (depending on your platform).  Notice the part I highlighted in Red.  That is the actual font name.   So, the last piece to this puzzle is you need re-open the app.css file and change the .JosefinSans class declaration to:font-titlebar-win

.JosefinSans {
font-family: JosefinSans-Regular,Josefin Sans;
}

Do you see what I added.  I appended the actual font name to the font-family.  The ORDER is important.   On Android because it does auto-registration of the fonts, it will load and register the FIRST font, and then it is happy.   On iOS it doesn't see the first font so it just ignores it and then sees the SECOND font and then it is happy.

fonts-iosSo now when you do a tns run ios --emulator you should see this.

 

 

 

 

You can download the complete project (including fonts) here: fonter.zip

The fonts/fonts.json file is just the font information for the fonts from the google code project; I wanted to make sure the copyrights information was in the same folder as the fonts in case someone finds the sample elsewhere.

[[ A updated version of this post has been posted for NativeScript v1.5+ and icon fonts here. ]]