NativeScript 4.2 Released

The new version of NativeScript just dropped today!   As usual the update is worth getting for several features that are shipping in it.

Major Features

  • LiveSync now uses Sockets on Android
  • iOS and Android now support the `discardUncaughtJsExceptions` flags.
  • Simpler Templates (less NPM dependencies)
  • Android now support HTTP Gzip'd packets
  • Debugging Webpacked apps

Minor Features and/ Bug Fixes

  • Android v8 engine upgraded to 6.7.288
  • Android app no longer crashes when closing debugger.
  • Multiple CLI building issues resolved, including LiveSync on modern Android; Gradle issues with Google plugings.
  • Android P support
  • iOS XCode 10 support
  • Several LiveSync fixes
  • Lots of build issues fixed

Known new Issues

  • None so far

NativeScript application wide runtime settings

NativeScript SwitchOn thing most people are probably not aware of is that the Android runtimes has a large number of knobs and switches to customize certain behavior of the engine.   I will try and list out all the current switches and knobs that you can use.   iOS now has one switch.

First of all the settings go into the /app/package.json   If you open up the default package json you probably will see:

{
   "android": {
      "v8Flags": "--expose_gc"
   },
   "main": "app.js",
   "name": "tns-template-hello-world",
   "version": "4.1.0"
}

That "android" key is where everything goes for Android specific settings.   The default setting that comes in the files is "v8Flags": "--expose_gc" this one is rather critical in that this enabled the runtime to call gc from JavaScript.   Now, there is quite a few v8Flags you can use; most the time they aren't needed but if you need to tune the v8 engine; you can add more flags into this string.  I even list a few in this post.   Let me warn you again; DO NOT remove the "--expose_gc".   You will cause your app to crash when something attempts to call the GC from code.

Ok, so the complete list of settings you can change in the Android section:

Setting Default Min Version Description
gcThrottleTime 0 3.x Allows you to throttle how frequently JS GC triggers native GC
See: Memory Management
memoryCheckInterval 0 3.x How frequently to check memory usage
See: Memory Management
freeMemoryRatio 0.0 3.x Ration of memory before a GC is ran (works with memoryCheckInterval)
See: Memory Management
markingMode full 3.x Switches which type of GC engine to use.  "none" will enable a different engine which doesn't do marking.  Typically faster for Angular apps
handleTimeZoneChanges false 4.1 True will enable the ability for a time zone change in the settings to effect the NS app.
maxLogcatObjectSize 1024 4.0 How many lines of text a console output will log.
forceLog false 4.0 True will enable logging in release mode
codeCache false 2.x True - Enables code caching in the v8 engine.
v8Flags --expose_gc 1.x Tunes the v8 engine
heapSnapshotBlob "" 2.x (Believe to be unused now)
heapSnapshotScript "" 2.x (Believe to be unused now)
snapshot.blob "" 2.x (Believe to be unused now)
profilerOutputDirKey "" 2.x (Believe to be unused now)
profiling "" 2.x (Believe to be unused now)

IOS Level Flags:  (None Currently)

Top Level Global Flags:

Setting Default Min Version Description
discardUncaughtJsExceptions false 4.2 True - will disable crashing on JS errors, will log any issues to console.

Recommended changes:
discardUncaughtJsExceptions: "true" - This will keep the app from crashing on certain types of errors; this should be enabled for release mode! Some developers might find it more productive to have this enabled while coding to eliminate application crashes. Please note you MUST pay attention to the console if you enable this during development; because most JS errors that would crash out; will now be just logged to the console.

markingMode: "none" - This will enable the experimental GC engine, this will help incredibly with Angular based apps. Please note it "might" cause more crashing errors if a plugin forgot to hold a reference to something it needed later. However with the above discardUncaughtJsExceptions enabled; those errors won't crash the app.

Late Breaking news; in 4.2 they actually moved "discardUncaughtJsExceptions" to the top level of the package; the reason why is because shortly after they added the support to Android; the support was added to iOS.  So now this flag controls both iOS and Android, so it no longer belongs just in the "android" block.

So in your package json would look like this if you used my recommended settings:

{
   "android": {
      "v8Flags": "--expose_gc",
      "markingMode": "none"
   },
   "discardUncaughtJsExceptions": "true", 
   "main": "app.js",
   "name": "tns-template-hello-world",
   "version": "4.1.0"
}

NativeScript 4.1.0 Released

I took a bit of a break from reporting on NativeScript things; but guess what, I'm BACK!!!

Well, looks like I was on the ball again this time.   😉    4.1.0 has been released to NPM, and it is HOT!

Version 4.0 was a great release and all; had a lot of cool changes.   But 4.1 is an awesome release building upon that great release and if you haven't upgrade to the NativeScript 4 yet; this is what you have been waiting for!   Thank you Progress.

First of all the item that we have been all waiting for if you do any Android development; they have updated the Android V8 engine to pretty much the latest stable released version.  So we jumped from v8 v5.5 to v6.6.   Now that might not seem like a large change but the number of changes in the v8 engine from v5 to v6 are incredibly large.   We now have the brand new JavaScript optimizing engine (Turbo Fan); the new optimized Garbage Collection engine, pretty much full ES6 support ; and so many other countless optimized features -- I could dedicate a post to all the cool things we now have access to in Android.   In a nutshell this v8 is now considerably faster.  In fact one of the tweets you might have seen is how much faster this version even starts the application.     Always awesome for our customers to have the app startup now almost twice as fast.   For all you iOS fans; v4.0.0 of NativeScript upgraded the JavaScript core to pretty close to the latest, so now both sides are running the state of the art JavaScript engines..

In addition to that awesome change that is totally worth the upgrade by itself - we can now use Angular 6 and Webpack 4!   I'm sure many of you will be very happy to see these.

Now that I'm done drooling over all this new found speed and these two other awesome feature updates; lets run down some of the other new features and fixes that you get for free when you upgrade:

  • Android: "in" names space is now fixed.  Prefix it with a $ so that it is $in.rest.of.namespace.
  • Android: Java ByteArray to ArrayBuffer support was improved to support more types of ByteArray's.
  • Android: Latest Gradle now used (and a bug fixed against it).
  • Android: Several Console fixes; including release mode no longer logs.
  • Android: Fixed JNI crash
  • Android: Debug tools are and LiveSync fixes.
  • Android: Android P fixes!
  • Android: ReturnKey no longer fires twice
  • Android: Transition no longer crashes
  • iOS: Console fixes
  • iOS: Inspector port no longer times out quickly
  • iOS: Flexbox fixes
  • iOS: getImageAsync() added
  • iOS: searchbar and listview sizing fixes
  • All: Modal dialog fixes
  • All: Navigation fix
  • All: LayoutChanged event added
  • All: css; linear-gradient support
  • All: File System; get file size
  • All: TabView font size
  • All: Read XML from Bundles
  • Angular: Angular 6 Support!
  • Angular: router state should no longer crash the app in an invalid state
  • Webpack: Webpack 4 Support!
  • Webpack: XML Loading support
  • Webpack: Android Compression
  • CLI: Supports driving more than one iOS simulator
  • CLI: Support Java 10
  • CLI: Full application templates (Beta)
  • CLI: Allow native Objective C source as part of plugins.
  • CLI: iOS wifi driving should work again.

What do you think; I think this is a Rock'n awesome release, thank you to the different development teams (and community members) who contributed to this release!

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 or you can manually run the commands below
> tns update

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

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

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

Common Issues:

  1. None so far.  🙂

Tech support & Open Source bug fixes

I get more than one message a week requesting help with one of my many open source plugins or projects.   I would really love to help you; but this is not something that is sustainable and completely unfair to my family.

Not only did you get the plugin and/or project for free; you already have the source code, documentation, and probably even a full demo that shows most -- if not all the functionality of the project.   You should have everything you need to find the answer to the question yourself.

Pretty much all my income generated is currently from my doing contract development or consulting related work.   So any "free" support work that interrupts paid work; really is a bad thing for my family.   If you are being paid to build your app; than you can see how this  even more of an issue.

If you really you think you found a bug; then by all means report it to the proper repo (https://github.com/NathanaelA) and the support will be appropriately dolled out.   I do take bugs seriously; but again open source plugins are never as high of a priority as paid work.    The bugs will eventually get fixed; but it might take several weeks to find the time to work on it.   In the meantime I do accept pull requests.  I am also much more likely to accept your PR fairly quickly and fix anything that I find broken in it; than reject it.  😀

Finally, I am not opposed to supporting you; so If you really want my support; I do offer paid support https://nativescript.tools/product/11

Now back to the regularly scheduled technical blog posts.  😉

NativeScript iOS Delegates and easy access to modifications.

UPDATE: After a lot of direct testing; this technique does NOT work for fixing and/or updating iOS delegates.   NativeScript does NOT follow the JavaScript specs in this area.  (in other words NativeScript is broken/buggy here, but I do not expect to see a fix for it.)  So even though the JS engine updates the code properly and the delegate object on the JS side of the bridge looks like it is updated.  The original delegate that was first created is cached and used from that point forward.   This technique is valid for any other normal JavaScript stuff; but does not work for the iOS NativeScript delegates as I had expected it to.   Sorry for the bad information, everything would/should have worked if NativeScript didn't introduce bugs into the JS engine in this area on iOS.

---

Over a year ago, I had a long discussion with the NativeScript team about opening the delegates to allow the developers to easily access and change them before they are created.   Unfortunately a couple people on the NativeScript team disagreed with me and my reasoning and rejected my pull request that would have allowed easily extending the delegates before they are created.    They unfortunately thought it was "unsafe", and that was that, the delegate doors were shut.

So then for any projects I needed to extend a delegate I pretty much had to use a custom version of the NativeScript Core Modules for my clients. This has bit me a couple times; when I upgraded as then my changes were wiped out.  (Tip: Always list any of these type changes in your project readme, with code!)

Also, I never had the time to finish my planned work around "TNS-Core-Patcher"; which would have allowed plugins to have patch files to patch the NativeScript core modules during the prepare phase and include any code like delegate changes.     The TCP project is only partially done, so this post isn't about that cool project, that still might see the light of day when I have that mythical spare time.

But instead it is about a post about a issue that Gheric posted to the ios-runtime repo yesterday.   I originally responded and said my usual spiel about about how it only works if you can get access to the delegates prototype chain and that the NS team had dismissed allowing it on this issue.    He responded back and said he didn't see anything in my examples that couldn't be done using his proposed feature.

At first I was thinking, he had no idea what he was talking about.   But I am so happily wrong!    The current version of NativeScript uses this._delegate assignment inside the class for almost every single instantiated delegate that I can see.  I just quickly searched through the code and as far as I can tell; I can get access to every single created delegate.  This is what I believe Gheric was pointing out that the underlying instantiated delegate is accessible.  If he wasn't pointing to it; then because of his persistence; he made me go look at it again and then I discovered it.  But either way; it was because of Gheric's post that I understood the ramifications of having access to the instantiated delegates.

So lets add to to that, NativeScript's current engines now support a large chunk of ES6, not full ES6, but a large enough chunk where what I need exists now.

So what does that give me?   Well, it just gave me the entire ios delegate world!!!   Delegates are no longer locked behind an artificial barrier, and I can change them however and whenever I want!!!  Can you tell I'm excited?    I just got a second Christmas!

I now have a technique that totally eliminates the stupid door the team closed. So instead of letting me have a easy door to make my changes; I have found a awesome open window to allow me to make the exact same changes.

(c) 2013,Angelo DeSantis - https://www.flickr.com/photos/angeloangelo/8607844680/

Ok, so lets get to the nuts and bolts of how to do this.  The key is the ES6 Object.getPrototypeOf()function.  This allows us to get the prototype of an already instantiated object.   So it is almost as good as my original pull request.  In my original pull request I would be able to

let x = require('someComponent');
x.exportedDelegate.prototype.addFunction = function() {
/* Do whatever iOS expects this delegate function to do */
}

Very simple, and allowed me access to all sorts of things iOS expects you to be able to do when you want certain customizations.   Doing it off the prototype chain of the exported delegate is the easiest and BEST place to do it.   It doesn't matter if the delegate is instantiated or not.

Now the WORKING technique is:

let originalPrototype = Object.getPrototypeOf(someClass._delegate);
originalPrototype.addFunction = function() {
/* do whatever iOS expects this function to do */
}

Not that much harder, and the end result is identical.   However there is one potential gotcha with this new technique; if the delegate has not been instantiated yet -- you obviously can't get access to its prototype chain.  Depending on which delegate you need to modify you might have to wrap the code in a looping setTimeout() until the delegate is instantiated.

function fixPrototype(classObject, delegateName, delegateFunctionName, delegateFunction) {
if (!classObject[delegateName]) {
setTimeout(() => { fixPrototype(classObject, delegateName, delegateFunctionName, delegateFunction, 100);
return;
}
let prototypeOf = Object.getPrototypeOf(classObject[delegateName]);
protoypeOf[delegateFunctionName] = delegateFunction;
}

/* Call it */
fixPrototype(someClass, "_delegate", "addFunction", () => { /* do whatever ios expect */ });

 

This simple function, will allow you to pass in the object class, then the delegate name (most the time "_delegate" and then the function name you want to add, and then the function itself.   It takes care of the rest.

Remember, once you have patched a delegate prototype; ALL delegates using that prototype (including any of them created in the future) will get your changes.  That is why it is so important to patch the delegate prototype, you only need to do it once and it works everywhere.

NativeScript Plugins: A Deep Dive - With the Three Stooges

And the second talk I was in at the NativeScript 2017 DevDays, us now up.  My cohorts in crime; and my awesome nStudio team mates; Nathan Walker and Brad Martin is now up.   Audio is a little low; but you can hear everything.

Unfortunately, the majority of my information was chopped since we ran out of time.  This was planned for and sorta expected as we weren't sure exactly how much of the info we would get to present in the time we had.   So almost all my content is totally self described in the slide deck.   😉

One word about the interactive slide deck, some of the slides have a "Down".  We groups the different subjects into their own like mini-slide decks.  So you can go "Down" to see everything about that specific sub-topic.

You can view the slide deck on our nStudio website.  http://nStudio.io/talks/pluginsdeepdive it has a lot more information that we were able to present.

 

 

 

NativeScript: Performance from the Trenches

Well my video for Performance from the Trenches, was released today!   This is the talk I gave at the NativeScript Developer Days 2017.

 

There is a lot of good useful information in this Talk, so enjoy.

Slide Deck: Performance

NativeScript App: https://github.com/NathanaelA/PerformanceFromTheTrenches

V8-Natives Repo: https://github.com/NathanaelA/v8-natives

 

 

 

NativeScript and Console logging on iOS (including XCode 9)

Been a while since I posted; and most this info was going to be presented at the NativeScript Developer days speech that we ran out of time in our cool session.     So I'm going to present it here, because I think this will help a lot of people.

First of all, NativeScript has an issue (at least on my machine) where the logging is incomplete and missing important things, like crash reports (and now on XCode 9, non-existent).

Well, when I ran into the two first issues using XCode 8.2 & 8.3.   I figured out a work around, because I hate my tools not working.    🙂

There is a really awesome set of utilities called libimobiledevice this set of utilities lets you do all sorts of things with a real iphone when it is connected to your computer including reading the logs.

 

Real Devices (any version of iOS)

So I typically do idevicesyslog | grep CONSOLE and it will then show me all my logs for the device and it basically fixes any issues other than some exception reporting.   Most the time my app doesn't crash so that command above I use probably 99% of the time.    However in the cases I need to see the NativeScript actual crash logs.   I use the above command and it will spit out the PID of your app next to the CONSOLE word.  I then cancel it, and do a idevicesyslog | grep <PIDID> and this gives me the full log including anything the NativeScript runtimes print.

Please note this only works for real devices.

Simulators (iOS 10 and before)

UPDATE for iOS 11 simulators, please see below!

Now for simulators; the process is very similar.

You run xcrun simctl list | grep Booted and it will give you a line like this:
iPhone X (4701B6F6-0EE4-423F-B5E2-DE1B5A8C32AC) (Booted)

Do you see that big old long uuid; you need that.

tail -f ~/Library/Logs/CoreSimulator/4701B6F6-0EE4-423F-B5E2-DE1B5A8C32AC/system.log | grep CONSOLE

This allows you to grep the log from that specific simulator.   Again, using the grep CONSOLE filter you can limit it to any console logs.   And you can also use grep <PIDID> to filter it to any application if you need the filtered down to, if you are needing the specific NativeScript application level logging or crash reports too.

 

Simulators (iOS 11)

iOS 11, changed the logging for the Simulator drastically.  Technically iOS 10 changes the NSLog drastically, but 11 enforced some new rules.   So iOS 11 broke the NativeScript internal logging; but it broke the cool tail trick above.    Everything now is now running through the new os_log facility.  The easiest way to get logging from your simulator is this single line:

log stream --level debug --predicate 'senderImagePath contains "NativeScript"'
--style syslog

Please note this is case sensitive, if you don't case the senderImagePath and NativeScript you won't have your filtered logging (or any logging at all if you type it wrong).   This part of it filters it down to just any NativeScript logging from all emulators running.

I created a simple bash script called /usr/bin/local/tnslog and dropped the above line it in and then chmod +x /usr/local/bin/tnslog 'd it.  So I can easily just start tns, and then open another terminal tab; and type tnslog and have all my logging again.

 

Installation

The simulator you need no extra tools.   For real devices you need the libimobiledevice toolset, which you can easily install via brew with the following two commands:

brew install --HEAD usbmuxd

and

brew install --HEAD libimobiledevice

It is really important that you install from head, the changes in Xcode 9 and iOS 11 have made a couple changes to both those libraries require some updates and the normal brew packages are out of date and doesn't have it.  So you need the latest and greatest.

 

Final Thoughts

I have been lazy, and just documented the steps.   If someone has some spare time and wants to create a quick bash script to automate the grabbing of the simulator id, and starting the older logging; against that simulator that would be cool to add to our tools.  But since I'm using primarily iOS 11 emulators now; my tnslog script handles all logging until the NativeScript team can fix their tool's issues.

 

NativeScript 3.2.0 Released

Well, looks like I was on the ball this time; I actually beat Progress to the punch.   😉    3.2.0 has been released to NPM.

  • Blur and Focus events added
  • Android keeps nativeView when navigating forward to eliminate the tear down and re-build when navigating back.
  • Nasty memory leaks in iOS fixed; this one is worth the upgrade alone!
  • Some XCode 8.3 and 9 fixes
  • iOS LiveSync fixes
  • Some Webpack and Signing issues fixed
  • Android metadata generator fixes

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 or you can manually run the commands below
> tns update

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

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

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

Common Issues:

  1. Plugins fails; this is a known issue do to the complete revamp of the lower levels of the core modules design.  Some plugins need a lot of changes to work in 3.x; so you will have to wait for the third party authors to get caught up (Even I'm not caught up).    My plugins site  http://plugins.nativescript.rocks should be listing both version v2 & v3 plugins separately so that you can easily find 3.x or 2.x plugins.

NativeScript: 3.1.x released

Looks like I was asleep at the wheel; according to NPM 3.1 was released late last week; and I totally missed it.   However, I am more on the ball today and saw that 3.1.1 was released today to fix some of the issues with 3.1.    So lets cover the changes in both 3.1 & 3.11

  • Android Chrome development tools now supports the Elements tab; this allows you to see what css is assigned to elements in the UI DOM.  Very nice feature!
  • Android snapshots can be generated on Linux and Mac.  This allows you to make a custom snapshot; snapshots will improve startup time; but they do have the downside of increasing the size of the APK a lot.
  • Android now support ABI splits on first build.
  • Profiling on Android, you can now enable a profiling to see what is taking time in your application.  The feature is also available in @next on iOS.
  • CLI has been improved to fix a lot of issues, including Node 8 / npm 5 support.
  • Several fixes for the SearchBar, and TextFields now have a maxLength property!

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 or you can manually run the commands below
> tns update

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

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

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

Common Issues:

  1. Plugins fails; this is a known issue do to the complete revamp of the lower levels of the core modules design.  Some plugins need a lot of changes to work in 3.x; so you will have to wait for the third party authors to get caught up (Even I'm not caught up).    My plugins site  http://plugins.nativescript.rocks should be listing both version v2 & v3 plugins separately so that you can easily find 3.x or 2.x plugins.
  2. TypeScript incompatibilities; you should be using 2.2 or later with v3.x of TNS
  3. A new  3.1 CSS issue with Background Color
  4. Android runtime can still crash randomly with No weak reference found. long standing unfixed bug...  Disabling screen transitions, seems to help resolve the issue.
  5. Webpack might have random issues in Android builds, you might need to to a tns platform clean android to fix occasionally
  6. Issue with upgrading applications on Android 6 & 7 see blog post on fix.