Where do I get started?

What are plugins?

Official NativeScript Plugin Seed

  • Intelligent scaffolding
  • Built-in unit testing setup
  • Built-in support for Travis CI testing
  • A powerful development workflow

The Workflow

npm run plugin.tscwatch

npm run demo.android

npm run demo.ios

In the plugin SRC directory

In the demo app directory

AndroidManifest.xml

  • Unique name of the app package
  • Permissions
  • Minimum Android API
  • Drawables
  • Activities
  • Services
  • Intents

Manifest in a Plugin

What is an Android Activity?

  • Google describes an activity as "a single, focused thing that the user can do."
  • Simple way to think of an activity is a screen inside of an app.
    • Not all screens are activities.
  • NativeScript apps have one main activity.
  • Activities have life cycle events that are useful for plugins with native code.

Activities in Plugins

How do we hook into and know the correct activity result event executes?

What is an Interface?

An Interface is just a collection of abstract methods that a class can implement.

Interfaces in NativeScript

Only minor language differences.

JAVA

TypeScript

Creating Java Arrays

JAR vs. AAR

Similar but Different

JAR = Java ARchive

AAR = Android ARchive

Where does it fit into a plugin?

Java to Javascript

Most things map their data types the way you'd expect and are simple to use.

However, there are a couple of gotcha moments.

  • java.lang.String => String
  • java.lang.Boolean => Boolean
  • Short, Int, Float, Double, Long => Number

+

How to use with NativeScript?

+

Isolate plugin integration

+

Simple. Podfile.

...in a suggested folder structure.

Does it get added automatically?

tns plugin add nativescript-my-plugin

+

Ready to Go!

You can now write JavaScript/TypeScript with the Objective C or Swift code provided by the CocoaPod!

+

I want CocoaPod TypeScript definitions!

+

Development workflow?

  1. Make changes to plugin code
  2. Compile plugin (if using TS)
    • tsc -d nativescript-my-plugin/my-plugin.ios.ts
  3. tns plugin remove nativescript-my-plugin
  4. tns plugin add nativescript-my-plugin
  5. tns run ios --emulator

+

Steps to CocoaPod TypeScript Definitions

+

Steps to CocoaPod TypeScript Definitions

  • npm i tns-platform-declarations --save-dev
  • add "references.d.ts" file in root

/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />

TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios

+

Any faster workflow please?

+

Steps to CocoaPod TypeScript Definitions

+

You Swift'ed Me!

+

You Swift'ed Me!

CameraSelection - No Results!

+

You Swift'ed Me!

+

You Swift'ed Me!

+

Swift - Behind the Scenes

+

Swift - Behind the Scenes

+

Swift - Exposed!

+

Swift - Exposed!

TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios

  • When making Podfile changes:
    • tns plugin remove nativescript-my-plugin
    • tns plugin add nativescript-my-plugin

+

Swift - Exposed!

Plugin Listing

How does it get listed on the plugin sites?

Plugin Listing

How does it get a category?

• You put it within the "nativescript/plugin" key

How important is the platforms key?

• Critical, this tells NativeScript which core modules it works with at a minimum.

What are the rest of the keys?

• Read about them on https://plugins.nativescript.rocks

Plugin Listing

Anything more basic I should know?

• Make sure your .npmignore file ignores the demo folders,, TypeScript .ts files and any other files that are not needed to make the plugin run.

Github/git folder layouts:
/demo - is the standard NativeScript demo folder

/demo-angular - is the Angular NativeScript demo folder
/demo-vue - is the NativeScript Vue demo folder

/src - is your plugins source code folder.
.gitignore goes in /  folder, .npmignore goes in /src

Plugin Listing

How does it get listed on the plugin sites?

• Plugin name or the keywords must contain the word NativeScript.

• Your package.json file is the key!

How quickly does it show up?

• Instantly on https://plugins.nativescript.rocks

• Within 24 hours on the other plugin sites.

XCode 

IDE for Mac Desktop, iOS, Apple Watch, etc.

What is Swift?

Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, macOS, watchOS, tvOS, and Linux. Swift is designed to work with Apple's Cocoa and Cocoa Touch frameworks and the large body of existing Objective-C (ObjC) code written for Apple products.

Swift                     vs.                  Objective C

What is Swift? ...cont.

  • Interoperability lets you interface between Swift and Objective-C code, allowing you to use Swift classes in Objective-C and to take advantage of familiar Cocoa classes, patterns, and practices when writing Swift code.
     
  • Mix and match allows you to create
    mixed-language apps containing both Swift and Objective-C files that can communicate with each other.

How do Apple developers share open source libraries?

Kinda like npm for iOS development!

CocoaPod Coolness

CocoaPod Coolness

CocoaPods vs. Npm in numbers

There is a thriving community  publishing and sharing rich libraries

via CocoaPods

Plugin Layout

Why does it matter?

Plugin Layout

Original Way!

Plugin Layout

Original Way!

Why we used it?

• Easy to link plugins to a git repo.

• Easy editing of demo and reinstall of source code for testing in demos

• Less directory navigations

• License and Readme in root for github

Plugin Layout

Original Way!

Simple Layout, everything is in the root folder of git.

• Demos

• Source code

• package.json

• platforms folder

• other folders and files

Plugin Layout

Original Way!

Why are we abandoning it?

Plugin Layout

Original Way!

Why are we abandoning it?

tns plugin add .. or npm i .. --save

Both do this to your demos node_modules

Plugin Layout

Original Way!

What is that?

It is a symlink, or junction that points back to ".."

Plugin Layout

Original Way!

It is a symlink, or junction that points back to ".."

Why is this so bad?

Anybody know what this folder is?

Yep, it is your Demo folder.

Plugin Layout

Original Way!

Yep, it is your Demo folder.

Putting a folder with another copy of the runtime and/or core modules in your apps node_modules is bad enough.

But it is recursive...

Plugin Layout

Better Way!

Plugin Layout

Better Way!

tns plugin add ../src or npm i ../src --save

NPM still creates a link, but it is no longer recursive.  Yay!

Plugin Layout

Better Way!

tns plugin add ../src or npm i ../src --save

The new NPM linking system has some unexpected benefits:

• One copy of your source code in your /src folder

• Install plugin once, and no more manual maintenance to test changes.

• Use tns run ios --syncAllFiles or

tns run android --syncAllFiles and tns will automatically update your node_modules changes (which is your plugin edits)

SearchCode?

What is SearchCode?   I've never heard of it?

SearchCode is a new site that has been in Beta testing for the last couple of months to allow developers to easily find snipits of code from all the plugins in the NativeScript eco-system.

How does that help me to write a plugin?

Do you know off the top of your head how to write something that works with the call

webViewShouldStartLoadWithRequestNavigationType?

SearchCode?

webViewShouldStartLoadWithRequestNavigationType?

Looky there, 7 samples in different plugins on how people used it.   Now you can easily understand how to use it in YOUR plugin.   Could be Just a little helpful???

SearchCode = Pretty much ALL NativeScript plugin source code in a easy to search and navigate system!

3rd Party Integration

3rd Party Integration

How do I use a CocoaPod?

• You create a /platforms/ios folder

• In that folder you create a file named Podfile

What do I put in a Podfile?

CocoaPods

pod 'name', 'version'

The name and version is whatever you choose to use on https://cocoapods.org/

3rd Party Integration

Advanced CocoaPod Information:

CocoaPods

Choosing a pod from a git repo

Choosing your own source for the podfiles...

3rd Party Integration

Whats a framework?

Frameworks

• A framework is another way to distribute a library for iOS.  In addition the built in libraries in iOS are also frameworks.   Some examples plugins: Spotify, Estimote, StarPrinter.

• You put the framework in your /platforms/ios folder

How do I use a framework?

• You open up the framework and verify it has a module.modulemap file.  If it doesn't you have to create a modulemap file.

3rd Party Integration

How do I create a module.modulemap file?

Frameworks

• You give it a name

• You figure out the main header file in the framework

• You add any linking

• You export *

What, that doesn't sound simple...

3rd Party Integration

How do I create a module.modulemap file?

Frameworks

First to find the header, you need to look inside the .framework file, typically inside the /headers folder.  Normally it is named the same as the framework name.

Then you create it like this example:

3rd Party Integration

How do I create a module.modulemap file?

Frameworks

How do I add linking (if needed)?

Anything else?

I am so glad you asked, sometimes you need a build.xcconfig file to help XCode find the libraries and/or header files listed in the module.modulemap and/or in the framework.

3rd Party Integration

How do I create a build.xcconfig file?

Frameworks

What things can I do with the xcconfig file?

The xcconfig file allows you to pass different parameters to XCode while it is generating your application.   Some common things you may have to pass is:
• Header directories
• Library directories
• disabling Parameter elimination.

Where do I put the build.xcconfig file?

The build.xcconfig file also goes in the /platforms/ios folder.

3rd Party Integration

How do I create a build.xcconfig file?

Frameworks

Some examples:

Tell XCode to keep this symbol.

Tell XCode where to find header files at.

3rd Party Integration

3rd Party Integration

Gradle?

What is Gradle?

The standard build system for Android applications.

How can I find Gradle plugins?

https://android-arsenal.com
https://bintray.com/bintray/jcenter
http://search.maven.org

How do I use Gradle?

You create a folder /platforms/android and create a new file called include.gradle into it.

3rd Party Integration

Include.gradle?

What is inside the gradle file?

Standard configuration

Dependancy configuration

3rd Party Integration

Advanced Gradle configuration

Standard configuration lines

Location to get the aars from

All the required dependencies

MetaData Generation

iOS has two different Metadata generation systems.

• Detailed Metadata

• TypeScript Typings

Detailed Metadata

NS_DEBUG_METADATA_PATH="$(pwd)/metadata" tns build ios

TypeScript Typings

TNS_TYPESCRIPT_DECLARATIONS_PATH=”$(pwd)/typings” tns build ios

Detailed vs Typings

Text

declare class HMAccessory extends NSObject {

       updateNameCompletionHandler(name: string,    

              completion: (p1: NSError) => void): void;

Typings normally does a great job:

Text

Detailed gives you all the data:

Name:  'updateName:completionHandler:'
 JsName: updateNameCompletionHandler
 Filename:        /Applications/.../Library/.../HMAccessory.h
        Module:          
         
FullName:        HomeKit.HMAccessory
          IsPartOfFramework: true
          ... Much more info on this method, including details on parameters ...
       

You can generate both at the same time:

MetaData Generation

Android has a single metadate generation system.

TypeScript Typings

TypeScript Typings

Download and build from:
https://github.com/DickSmith/android-dts-generator

 

Why not, use official repo?

https://github.com/NativeScript/android-dts-generator

Pull request number 12.

Install the tool!

TypeScript Typings

Typings will be located in the /out/ folder.

java -jar build/libs/dts-generator.jar -input <jar1> <jar2> ...

Will generate a .ts file like this.

Even more plugin tips!

Should I make a dependency from my plugin to TNS Core Module?

No, this is one of the worst things you can do to others using your plugin.

Why not?   What could be so bad?

Do you remember the recursion issue earlier?  Do you know what can happen if you have two or more TNS Core modules in your project? (especially if they are different versions?)    App builds fine, but app will crash with weird errors.  This is NOT fun to trace down.

Even more plugin tips!

How should I make my plugin dependent on TNS core modules ?

You can use peer-dependencies, however, even this method is not recommended except in cases where you have specific plugins that work with other plugins.  If you had put a peer-dependency on v2.00 of TNS, your plugin would now be unusable in TNS 3.x even though without the peer dependency it could have work great when 3.0 came out.

How do I do peer dependencies?

Is TNS forgetting to tell you something?

is very simple:

Type adb logcat in a terminal window, it will connect to your phone or emulator and show you all the logs since the last time it was cleared.  To clear your logs, type adb logcat --clear. One additional tip, is you can use grep to limit it to the your application.

That is a weird title, why?

TNS has the weird problem of sometimes not logging everything you need to know.  In some cases it can be really bad, in others it is just a minor annoyance.    Fixes?

is more complex:

You can use XCode, to view the log via the devices menu.

Click here!

Is TNS forgetting to tell you something?

is more complex:

And you will have a small window into the logs.

Look logs!!!

Is TNS forgetting to tell you something?

Better option:

Install libimobiledevice for some useful utilities.

brew install libimobiledevice

Then from a terminal window you can then type idevicesyslog and see the logs from the device.

And you will get a lot of other cool utilities too

Is TNS forgetting to tell you something?

Final tips for adb logcat and idevicesyslog

Because both adb logcat and idevicesyslog are command line programs, both of them can be piped to grep.  You can use grep to filter the log to "CONSOLE" or the process id of the process.  

idevicesyslog | grep CONSOLE

example command line: