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 Testing: Unit Testing

ns-road-signsI got to give a talk on NativeScript testing to a great group of people at NativeScript Developer Days.  20160920_190247Despite my silly technical problems at the beginning, we managed to get back on track and I was able to present all the critical information that was needed to get everyone up and running.  I did manage to miss my last slide; so I will make sure to have all that information at the end of this post.

For those who are interested in doing testing and weren't there; or those who were in the talk, and just want to get a quick refresh, or if you just prefer the information written down; then this set of blog posts is for you.   I plan on doing a multi-part series on this as I want to cover what I did in my talk in the first two blog posts; but then expand the series to show Angular Native unit testing, how to unit test controls, and how to write unit tests for the NativeScript core.

You can view the #NSDevDay video here .  You can download my slide deck from the talk here.  And you can download the entire app that I wrote for my talk, including all the tests from here.

The posts currently planned in this series are:

Unit Testing

So our first type of testing we will discuss is Unit testing.   Unit testing, for those of you that are un-aware of what it is -- it allows you to take a part of your code (typically a class or module) and you test it.  The best way is to treat it like a black box.  You don't care how it is implemented internally; you only care about the interface it exposes (i.e. inputs and the results).  By treating it as a black box; this allows you to re-implement/rewrite/refactor/fix it or do any other internal things to the class without the rest of your real or test code caring about the actual internal implementation.  Because your class is self contained it makes your code a lot more de-coupled and stand alone.  This typically means the code is better engineered and more maintainable.  In a nutshell, unit testing, is basically throwing as many different types of inputs and then verifying all the outputs and/or execution of your class is correct.

Now some people like to develop the tests before the code; this way they think of the scenarios that they need to handle; create all the tests (which of course at this point will all fail) and then implement the code.   Others build the code and build the tests along side the code, or build them after the code is complete.   There are pro's and con's for all sides; and that is really a whole different blog post.   In my opinion it is better to just make sure you do it; not the when of doing it.  One other recommendation is that when you get a bug report; you write a test for it. This way once you fix it; then in the future that specific bug will never happen again as your tests will always be checking for it.  Remember the idea is to test for everything you can think of, if a bug slipped through -- that means you failed to test everything and so by adding those "bug" tests, now hopefully you are actually testing everything the class can do...

The really cool thing is NativeScript actually has built in unit testing.   The neat thing about the built in unit testing, is it actually runs fully inside your NativeScript application.   This allows you to test anything that you have in your application including any added plugins, or custom code.   To install it, you just do tns test init.  This will ask you which testing framework to use and will install it.   I prefer using Mocha, and so the tests examples will all be mocha based; but again the framework you use is your choice.   One thing to note is that the assert functionality is actually provided by the Chia library in each of the testing frameworks supported by NativeScript.  If you really prefer a different assert library there are ways you can change it, but that is out side of the scope of this blog post.

For all your unit tests in NativeScript, they are all located in the /app/tests folder.  To then run all your cool tests  you will type tns test android or tns test ios.  TNS will then build your app and launch it in test mode.   Once each test completes; your console will tell you which tests passed/failed and then finally how many passed/failed like this.

NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 0 of 6 SUCCESS (0 secs / 0 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 1 of 6 SUCCESS (0 secs / 0.005 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 2 of 6 SUCCESS (0 secs / 0.007 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 3 of 6 SUCCESS (0 secs / 0.008 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 4 of 6 SUCCESS (0 secs / 0.009 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 5 of 6 SUCCESS (0 secs / 0.083 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 6 of 6 SUCCESS (0 secs / 0.085 secs)
NativeScript / 19 (4.4.4; Samsung Galaxy S5 - 4.4.4 - API 19): Executed 6 of 6 SUCCESS (0.217 secs / 0.089 secs

Lets get to the actual creating of tests in Mocha.  In my sample carder app; I provided a sample test file. So lets look at the unit test file I provided. The file is located /app/test/carderUnitTest.js.  The first thing you will see is that I include the class I plan on testing.

var cards = require('../cards.js');

Pretty hard to test it, without requiring it.   So in case it isn't obvious you still need to require the file(s) that contain any plugins/classes/module you need to test.

Then the next part of the code you will see is;

describe('Cards', function() {
    describe("current card", function() { 
        it ('should return ace of spades', function() {

The first line of this, we use the describe command to give the test a name, this allows you to know which test group passed or failed.  You can also nest describe's inside of describe's to allow you to have sub-groups of tests.   Finally you will see the it command, which is the actual test. You can have as many it's as you need in a group to test the full functionality.  So walking specifically through this test; we are saying the main test group is Cards (I name it after the class I'm testing); the following describe is I'm testing functionality I'm testing the current card function; and finally what my expectation of my test, which in this case is that it should return ace of spade card.

Then next we add our add my actual test code;

// Reset Card deck to known state
cards.resetDeck();
            
// The get "Current Card" function
var result = cards.getCurrentCard();
            
// My Expectations, that it should be
// a Ace of Spades on a reset card deck
assert.equal(result.suit, "Spade"); 
assert.equal(result.value, "Ace");

If either of the last two lines are false, then the test will fail and it will then mark this test as a failure in the log.

As you can see creating this test was fairly simple; Reset deck, grab the card and then verify it.  If you scroll down in the test file to the end of it; you will see the random cards test.  As you can see that test is a bit more complex.  Your tests can be as simple or complex as you need.  Typically the simpler your tests are the better, as then it is less likely that your test is actually the broken part of the code if it fails.

One other feature of Mocha is you can actually do ASYNC tests; so if your code is promise or callback based; you can also test it.  By doing this:

it ("Test promise", function(done) {
  call().some().cool().func()
  .then(done).catch(function() { done(false); });
});

// or

it ("test callback", function(done) {
  someFunc(function(err, results) {
     if (results) done()
     else done(false);
  }
});

Notice in the it function, it has a done parameter now.  The done() function is passed in for you to call when the async code has completed.  The mocha unit test detects if you tell it to have a done parameter and will switch that test to be fully async.

Note: If you are using my NativeScript-LiveEdit plugin, the watcher has had the ability to start these tests instantly on Android (Without having to use the slow `tns test android` command) for quite some time.  So anytime you change any of the /app/tests/ files; it will automatically launch the tests and you will see the results almost immediately.  However, I have recently added a couple new features to the watcher; you can hit inside the watcher window a "t" to start testing immediately; or the "m" to switch modes (i.e. default-auto-test, always test, and never test), and the "n" to force it to launch the app in normal mode.

Now all of this can be totally automated and it is highly recommended to be completely automated in something like local git hooks or some CI environment so that when you commit a change the unit tests are done.  The sooner your tests run the quicker you find any breaking code after you make any changes.  It is always very re-assuring when you have to fix a bug in your class and then  re-run your tests and everything passes...

Depending on your CI environment and how frequently you commit, you might consider having the heavier tests run once every three commits or based on a keyword put in the commit or in a issue tracking system.  Again, the idea is the more tests you can do and the more testing coverage you have the better off you are.

If you need help setting up a automatic testing and/or CI environment or you would like some training, please contact me.

Resources:

NativeScript Developer Days

20160920_190247Well, we just finished the Conference yesterday!   Thanks for everyone coming out; I enjoyed meeting a ton of you.   And I hope everyone had a great conference.    For NativeScript being released as a Beta to the world 18 months ago; they had a large turn out.   In fact the Angular Native sessions had to be split into two rooms because so many people showed up.   Good problem to have!

Great job by Brian (and I'm sure others behind the scenes at Telerik & Progress) getting everything coordinated and setup.   It was an enjoyable conference with great speakers.

T.J. and Jen did a great job on the Angular 2 training session; I even learned some things in Angular Native; check out the in-depth tutorial on Nativescript.org, great stuff.

The Opening by Burke and Todd was very entertaining and love some of the history and vision you guys presented...    In 2014 NativeScript was started.  18 Months ago was when the beta was released, and the rate of adoption for NativeScript is through the roof.

I have to say, I'm still very very sad that Sebastian wouldn't let me steal his evil and "un-named" bot -- I would have provided a good home for it, and I could have helped with your goal of world domination...  So tell me Sebastian which room are you in again?     😉

I thought Alex Ziskind's talk was awesome, I don't use Office 365; but man your Plugin ROCKS!   If I get any clients that need that type of functionality; I know which plugin I will use.   Awesome job on both the plugin and the speech!   And to answer your question, Calendar would be my bet for next integration, everyone uses a calendar...

Nathan's Walkers ShoutOutPlay is awesome, I love how you blended using your ShoutOutPlay with your slides and talk; that was genius; and really made your talk shine!    Sharing! Sharing! Sharing!   😉

Congrats for MeWatt for winning the app contest -- the app & technology is very cool; but what stood out most to me is as I talked to the owner of the company (which he was an awesome guy) -- he mentioned that the app was built in 7 weeks from NO NativeScript knowledge to fully working on Android and iOS.   Holy smokes, 7 WEEKS to Awesome APP.   Talk about NativeScript being enabling!

And Raymond had a great talk to close out the day.  I so REMEMBER the magazines and typing in the many many lines of code; COMPUTE was the magazine I always waited for; I was on the c64...

The #MobileTea meetup after the #NSDevDay was cool.  It was people from the entire mobile community; React, Cordova, Native, etc...   The funniest thing that happened was two guys did a great job of presenting how to use PouchDB (on browser) and the native CouchBase library stuff on ios for doing local data and offline data and syncing of it.    However, the presentation on iOS he was showing the code for how to setup Couchbase and syncing and it was a lot of code.   (He did do a good job)...   So I did a quick search on our plugins site NativeScript.rocks for couchbase and found the plugin and the docs and it is 8 lines TOTAL of code to do the exact same thing in NativeScript and those 8 lines enable it on both Android and iOS...   NativeScript is just so COOOOOOL...  🙂

It was awesome to meet a several of the engineering team from Sophia -- we had some great discussions, and they now get to put a face to "that" guy that posts all those weird hard bugs that really mess up the schedules...  😀    The cool thing was we actually hashed out some great ideas for how to help enable several parts of the community to flourish more and how to help the community know what bugs we can easily work on ourselves from the TNS-Core.

It was also very cool to meet Rob, Brandon, and Clark from Progress/Telerik at the speakers dinner, all of them way behind the scenes at Telerik.   Rob, if you ever get any openings in your team -- it sounds like an awesome job, I love hacking on new technology....  🙂

And of course it was very awesome to meet Valio & Todd, Dan and Brian at Telerik, I chatted with each of them several times over the last 18 months, so it was great to finally meet and put faces to the name.

So if you picked up one word.  It was AWESOME...  Thanks again for everyone I got to talk to, and If I didn't put anything in here about you; my apologize; names and my memory sucks...

Oh and I plan on putting a blog post up later on my Presentation with the slide deck, link to the source & tests and all the key parts to help anyone who is interested in NativeScript Testing.     I understand the talks were all recorded; so I'll update the post to link to them when they are released!

NativeScript: Version 2.3.0 Released

ns-versionFor those hiding out in the forest; guess what was released by our cool park rangers at Telerik today!     Yes, you got it - v2.3.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:

  • iOS XCode 8 support for iOS 10 support - * (I've heard this might not be fixed yet)
  • Navigation memory leak squashed
  • Android Text Hint Color supported
  • Buttons now support text-decoration and text-transformation properly
  • iOS d.ts generator works properly
  • Android Extend working properly again
  • Android now properly re-throwing exceptions (better error messages)
  • Android a couple crashing corner cases fixed
  • Observables fixed (was broken in some nested situations in 2.2.0)

A Lot of other smaller bug fixes and enhancements went into place; unfortunately the really big feature for 2.2.0 & 2.3.0 has slipped again -- threads.   It was a lot bigger than they expected; I've seen progress on both Android and iOS on this front; based on the activity it should be showing up in the masters channel soon, meaning we will be able to test and play with it soon.

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

Common Issues

Images and a parent that has Color set, causes the image to not show only the color that was set on iOS.   To fix you can do this a couple ways.  Remove the color on the parent.  Upgrade or disable the broken source (Line 133

image._setTintColor(newValue);

in "node_modules/tns-core-modules/ui/image/image.ios.js, comment it out.

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: Debugging the Android Build Process

I've seen this error myself a couple times and it appears that several others have ran into it..   You type something like tns run android or tns build android and it gives you an error about some process failing to build -1 error and to try a --stacktrace to see more info...  Not entirely helpful.   How do you do a --stacktrace?

So let me tell you how to actually do a --stacktrace; the magic is simple, but not obvious.

You need to do the following:

cd platforms/android
./gradlew buildapk --stacktrace

Pretty simple once you know it...   This is what TNS uses to actually do the building part of the process; so when it fails; you need to manually run the process with the --stacktrace parameter.  This will NORMALLY give you why it failed; however there are cases where it doesn't.   So in those cases you try this command next:

./gradlew buildapk --stacktrace --info

And if that fails; then you try the really realllllllly reallllllllllly verbose output command:

./gradlew buildapk --stacktrace --debug &gt; somefile.txt

Then open up the text file in some editor that can handle 5 megs of text and search for the first occurrence of "failed" will typically give you why it failed....

One interesting issue that I ran into the other day helping a buddy of mine...   TNS seems to assume that anything not listed as a DevDependancy is a Dependancy; this can cause serious issues sometimes with things that actually should NOT be compiled into the app.   TNS builds a module using gyp; and gyp requires tar and tar-pack.  The authors of tar & tar-pack decided that the npm modules should have tests included in them (what????  Are you crazy?) and these tests have .tgz and .gz files in it.   Unfortunately these .tgz and .gz files will cause the android tools to fail in a lot of cases when it attempts to process them.

So there is two ways to solve this issue:

  1. Add tar & tar-pack to your dev-dependancies.
  2. Manually enter your node_modules folder; and find tar/tar-pack and then delete the test folders.

In my opinion adding those two modules to your dev-dependancies simplifies things and then you don't forget about them at some later point if you have to reinstall your modules...

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