NativeScript.js

Here I will add little tidbits I figure out developing NativeScript apps on a Mac.  I find a lot of things aren’t documented with enough detail that I have to spend time solving them.  These will be short and simple but hopefully will help others searching.  I will index them better and build this section out as it grows.

Also check my archive of NativeScript blog posts here: http://whoischris.com/category/nativescript/

knowFolders.currentApp() issues on iOS devices

For some reason I was able to save pictures to a directory using the currentApp() + “/mydir” in simulator but not on an actual device.  I opted to just use knownFolders.documents() in order to stash the image files and it works properly on device and simulator now.

Reset Your Emulator/Simulator!

More than once I’ve been held up on the weirdest errors.  Most recent was upgrading to NativeScript 2.1.  I did all the proper steps but was getting an error saying it couldn’t find ui/label Module which is, like, the most COMMON module.

ERROR Error: Building UI from XML. @file:///app/views/list/list.xml:7:21
     ↳Module 'ui/label' not found for element 'Label'.
       ↳Can't find variable: TNSLabel

Made no sense…. oh yea, maybe I should reset my simulator since upgrading.  Duh.

Reading File Contents

I couldn’t figure out how to use the file system to open a text or html file I wanted to read the contents of.  In the NativeScript documentation for the file system they use:

var documents = fs.knownFolders.documents();
var myFile = documents.getFile("Test_Write.txt");

This example is confusing because I don’t know where knownFolders.documents() is supposed to be located and it doesn’t tell me in the documentation.  What path is that? Where are these files?

I have app/htmlfiles/description.html and I want to open that.  Searching around examples I found that knownFolders has quite a few methods for getting paths.  To get the path to your app’s /app/ directory you use knownFolders.currentApp().  This works for reading content from a file in your apps relative path:

var fs = require("file-system");
var documents = fs.knownFolders.currentApp();
var myFile = documents.getFile("htmlfiles/description.html");

exports.loaded = function() {
    myFile.readText()
        .then(function (content) {
            console.log("Reading: " + content);
        }, function (error) {
            console.log("Error: " + error);
        });
}

Using Global Variables Through Your App

This is easy! In your main app.js file you can declare global variables that can be used anywhere in your app (as far as I can tell).  Here I’m making a global array I can use throughout the system.

var application = require("application");
application.cssFile = "./app.css";
global.favColors = ["Red", "Green", "Blue"];
application.start({ moduleName: "main-page" });

Then you can use them anywhere simply by calling global.varname such as this example I can get the array’s first index of “Red” by calling global.favColors[0].

Control nativescript-videoplayer with JavaScript

Say you have this for a video player in one of your main .xml files to run a video using the nativescript-videoplayer plugin.

<Page xmlns="http://schemas.nativescript.org/tns.xsd"
        xmlns:VideoPlayer="nativescript-videoplayer">
<StackLayout>
  <Image src="~/images/logo-wide.jpg" id="main-logo" horizontalAlignment="center" />
  <VideoPlayer:Video
          loaded="videoplayerLoaded"
          finished="videoFinished"
          autoplay="false"
          height="270"
          src="~/videos/intro-video.mp4" id="home-video" />

  <Button id="continue-btn" text="Continue" horizontalAlignment="center" tap="goNextFrame" />
</StackLayout>
</Page>

So you want to control this from your .js file, all you need to do is target the native functions.  So for iOS, if you want to stop it when the frame is leaving, you can use this function:

function videoplayerLoaded(args) {
    homeVideo = args.object;
}
exports.videoplayerLoaded = videoplayerLoaded;

exports.goNextFrame = function(args) {
    homeVideo.videoSource.ios.pause();
    frameModule.topmost().navigate("views/newframe/newframe");
};

Where is Android SDK installed on my Mac?

Get this message?

The ANDROID_HOME environment variable is not set or it points to a non-existent directory. You will not be able to perform any build-related operations for Android.

This took me a while because using Finder you can’t locate it.  It’s installed in /usr/local/Cellar/android-sdk/

If you open your terminal and type:

cd /usr/local/Cellar/android-sdk

Then type ls you will see your android sdk and what version it is so you can then run:

export ANDROID_HOME=/usr/local/Cellar/android-sdk/24.4.1_1

But replace 24.34.1_1 without whatever your version is you see.

Don’t Touch Things In /platform/ (Specifically Icon Settings in info.plist)

I learned this the hard way just like every thing else in here related to NativeScript.  It’s a young framework and there is not a ton of documentation or much of a community yet.  But I love it and the slack community is pretty active.

I finally finished an app and needed to get it in iTunes for my boss.  I started following build instructions using Xcode which involved following along with NativeScript’s docs and also getting linked over to Apple’s dev docs a lot.  Somewhere along the way I felt that I needed to make some changes to my app in Xcode so that it would be able to get submitted for review as it kept hitting errors when trying to upload.

Icons

Icons are handled in a way that’s not overly complex but super easy to screw up.  When you open your project that NativeScript generates you will see a lot of stuff going on.  One of those is the “Use Asset Catalog” option for your icons.

If you have any issues with icons when trying to upload to iTunes you will probably start toying with the Asset Catalog and your info.plist.  One word of advice: DON’T!

NativeScript handles this for you just fine.  Make sure you have all required icons in your /app/App_Resources/iOS directory (including your 120px ones! I.e. 40@3x and so on, these are new and screwed me up bad).

tns prepare ios

The point is, when you want to build your app just run tns prepare ios then open the project in Xcode.  You can have it handle some of the automated tasks you might need when it pops up its warnings, but don’t screw with the .plist file or the asset catalog stuff or you will spend an entire day like me trying to figure out what’s wrong.

When you run the prepare CLI command NativeScript builds out a fully functional Xcode project for you.  Other than dealing with setting up your Apple developer account and connecting it to Xcode there’s not much else for you to do.  When you are ready to build and submit to the app store all you have to do is make sure the device selected is “Generic iOS Device” hit Product > Archive then when the Organizer window opens Validate then Upload to iTunes.