Page tree
Skip to end of metadata
Go to start of metadata

Native Run-time plugins can be created with native iOS & Android development and then used within Smartface Run-time.

If you are a native plugin (Objective-C or Java) developer, you may refer to the related documents for developing iOS Plugins and Android Plugins for instructions specific to the platform.

This guide provides an overview how to initiate the plugin development, how to package plugins and how it is used by the Smartface (JavaScript) developer.


Plugin Development Flow

Smartface CLI (Command Line Interface tool) is a prerequisite for plugin development. For more information and installation instructions, visit the CLI page.

Development flow of the Smartface Plugin will be like this (done by native developer):

  1. Run a CLI command to create a plugin template for iOS and download AndroidPluginTemplate.zip for Android.
  2. Add your previously developed plugin file to template project
    • Compile to check build errors
    • Add necessary files & info
  3. Run a CLI command to generate a plugin zip file from the project

The developed plugin zip file is ready to distribute and use.

Creating Plugin Template Project

The following CLI command is used for creating iOS Plugin Template Xcode Project. It is recommended to create the workspace folder first and then change directory (CD) into it.

Usage :

smfc –task=create_iOSPlugin [–path=…] [–playerPath=…]


  • task : Required.
    “create_iOSPlugin” is specified to create iOS Plugin template.
  • path : Optional.
    Path of the template project to be created. If not provided, current folder is used.
  • playerPath : Optional.
    Path of the base player or project to create the template from your path. If not provided, currently associated versions with the CLI are used. There is some post processing applied to the zip file content when extracted, do not try to use zip file as is.

Filling the Template

Filling the template has some common parts and distinct parts for iOS and Android, described below.

Common Part of Template

Like an npm package, plugins use a “package.json” file to identify its contents. It is recommended to use following command to create a new “package.json” file after changing directory (CD) into workspace:

 

npm init

This will use command line interface to create a new “package.json” file or modify the existing one. Based on the approach, you may need to modify the “package.json” file later manually.

In the file, add following fields to the JSON :

  • os {string} – Identifies if it is an iOS or an Android plugin. Possible values are : “Android” or “iOS”.
  • cpu {array.string} – Identifies architecture types supported by the plugin. Possible values are: “x86”, “ARM”, “ARM64”. For Android, it can be “x86” or “ARM” or both. For iOS, it is required to have “ARM” and “ARM64” together.

Sample Android package.json file:

{
	"name" : "helloplugin",
	"version" : "1.0.0",
	"description" : "Smartface Hello Plugin",
	"keywords" : [
		"Smartface",
		"Hello",
		"Plugin"
	],
	"author" : "Smartface Inc.",
	"license" : "ISC",
	"os" : "Android",
	"cpu" : ["ARM", "x86"]
}

Sample iOS Package.json file:

{
	"name" : "helloPlugin",
	"version" : "1.0.0",
	"description" : "Smartface Hello Plugin",
	"keywords" : [
		"Smartface",
		"Hello",
		"Plugin"
	],
	"author" : "Smartface Inc.",
	"license" : "ISC",
	"OS" : "iOS",
	"cpu" : ["ARM", "ARM64"],
	"zipFiles" : [
		"SMFTestPlugin.zip"

	]
}

Custom plugin post integrator

During the publishing process, the plugin is integrated with published project. To implement custom actions on the post processor, use the “main” property of the “package.json” file. This “main” property points to a JavaScript file. If the file is present during post integration process, than it's used. If there is no specific need to use the post integrator, please delete “main” field from “package.json”.

Refer to the Developing Custom Plugin Post Integrator section for more information.

iOS Plugin Development

For more information, refer to the iOS Plugins document.

Steps are as follows:

  • Open the template project with Xcode.
  • Put your plugin files and resources under “Smartface/Plugin/” folder in Xcode.
  • The names are expected to be unique. If they are the same with another plugin, some files may be overwritten.
  • Write the definition file as described in the iOS Plugins document.
  • Make sure it compiles successfully.
  • Save your project.

Android Plugin Development

For more information, refer to the Android Plugins document.

Steps are as follows:

  • Switch to Plugin APK development workspace
  • Open the workspace with the desired Android Development Tool
  • Unzip the template project into your plugin source.
  • Build your APK
  • Make sure that the APK is a signed version, otherwise assets folder will be missing.
  • Put your APK and other Plugin related files (except APK) in a folder

Generating Plugin zip

After performing the necessary steps as described above, plugin zip file can be created using the following CLI command. Change Directory (CD) to workspace folder and type:

smfc –task= [–playerPath=….apk] [–Xmx=…]

Sample iOS generate code:

smfc –task=generate_iOSPluginZip

Sample Android Generate code is:

smfc –task=generate_AndroidPluginZip –playerPath=C:\Users\smartface\Desktop\helloplugin.apk –path=C:\Users\smartface\Desktop\plugin

During the creation of the zip file, this tool also performs some validations. Validation warnings & errors are displayed. The operation may stop with an error.

PlayerPath is the plugin APK, it is to be provided while generating Android Plugins.

"Xmx" is an Android only optional parameter. It is used to limit the memory size of the Java APK Tool, useful in low memory environments. Sample usage is like: "–Xmx=200m" This parameter also applies to publishing when used during publishing.

If the operation is completed successfully, a zip file will be created inside the workspace folder. This file is ready to use and ready to distribute. Feel free to rename plugin zip file.

Anatomy of a Plugin zip file

Every plugin consists of three items:

  • “package.json” file, describing the plugin
  • “node_modules” folder. Automatically created with the create task.
  • Plugin files & resources
Android Content
  • “apk” folder which is the decompiled version of the APK used during generation. Some files may have been stripped out or modified during the zip creation process.
iOS Content
  • Zip file(s) containing the “Smartface/Plugin” folde
    • List of zip files are specified in “package.json”
  • Delta of:
    • “SmartfaceAppDelegate.mm”
    • “project.pbxproj”

 Custom Content

  • JavaScript file(s) (entry mapped in “package.json” as “main” field)
  • Custom node_modules to distribute

Using Plugins in Your Project

Starting from this step, the processes are carried out by the Smartface (JavaScript) Developer.

During the publishing process, CLI is used to integrate plugins with the published package. Plugin zip files should be present while publishing. With the tool arguments, list of plugins for inclusion can be provided. A plugin cannot be added after the package is published. Internally, integrating plugins is the last step of publishing the package.

–plugin “::”

Additional plugins can be added to the package with following style :

–plugin “::” –plugin “::”

Smartface Android and iOS Emulator contains only a few number of predefined plugins. Plugins cannot be added dynamically to the Emulator. If you’d like to use an Emulator with custom plugins please contact Smartface Team.

Smartface performs its own integration with CLI tool. In order to use a plugin within Smartface, put the zip file inside “\Data\Plugins<ios|android>\” folder. When the project details screen is displayed in Smartface, content of the zip file is read to access to “package.json” file without extracting. The list of the plugins is populated in project details screen accordingly. You can select which plugins to be used during publishing process.

Automated Integration

Android
In an Android Plugin integration, content of the APK folder is automatically merged by creating a new “smali” folder per plugin. The cases, where a plugin has more than one “smali” folder, are handled by the integration tool. Some files are deleted from the plugin in order to avoid conflicts with the player.

Yet still, some plugins may still conflict with each other. Automated tool will scan “smali” folders within each plugin and list the conflicting plugins. Resolution of such conflicts usually depends on the plugin developer; user of the plugin may contact the plugin developer for a solution. In such conflict cases, warnings are fired and the process continues. The APK is expected to be compiled successfully even with conflict warnings; though it is more likely to crash during run-time when the conflicting feature is being accessed.

iOS
Changes during the iOS publishing are made within the “Publish.zip” file without extracting (Symbolic references are corrupt when extracted on Windows). During the integration process, the delta files are applied to the corresponding files. Zip files are added to the published zip file and their extract commands are added to “project.pbxproj” file to extract them before building on Xcode. There is no way to understand conflicting libraries before compiling on Xcode. Smartface player converts most of the error messages regarding conflicts into more meaningful messages.

Developing Custom Plugin Post Integrator

Since the Smartface CLI tool runs on NodeJS; the custom integration code will also be running on NodeJS.

Fill in the “packge.json” dependencies accordingly. The zip creator command will not include the contents of “node_modules” folder inside the workspace. If the plugin developer wants to distribute the module specifically with the plugin, the custom node module can be put inside the “node_modules” folder of the zip file after the file is created. Dependent and not-distributed modules are installed with the “npm install” command. This process may require an active internet connection in order to download missing node modules.

The JavaScript file mentioned in “package.json” file is the entry point. The plugin manager in the CLI tool expects a function object if that file is “require”d with the necessary entry. The expected function is called with the “pluginContext” argument provided by the plugin manger. To read more about the plugin manger please check the plugin manager code on github.

module.exports = function (pluginContext) {
	// content
};

The argument provided may vary based on target OS. Common items are :

  • Inherited from EventEmmiter
  • cpu – String[]
  • os – String
  • hasCustomProcessor – Boolean (true in this case)
  • pfs – Object
    Similar to fs in NodeJS. Used to access contents of published package. Only following methods are supported :
    • writeFileSync
    • readFileSync
  • path – String
    Provides the extraction location of the plugin zip file. Files in this path can be accessed by using fs in NodeJS.
  • pkg – Object
    Parsed “package.json”
  • error – String
    Gets or sets if the plugin integration has an error or not. (Null or empty string if no error)
  • name – String
    Name of the plugin

There are predefined events of the context. These events are not to be called within the custom plugin integrator:

  • start
  • done
  • postProcess

The context object is not shared across different plugins.

While developing the JavaScript code, please consider that this code will run on both Windows and Unix file systems. This is important while specifying the path separators.

Exception Handling


Exception Handling is the process of responding to the occurrence, during computation, often changing the normal flow of program execution.

For Smartface Plugins, exception handling is available. All of the JavaScript errors including wrong parameters, invalid/non-existing method names, invalid return types result in exception.

For example, if a method takes 3 parameters and it is called with only 2 parameters, it will give an exception.

Or, if a method takes string as parameter and an integer is used, again it will give an exception. Same thing is valid for return type. If return type of a method is an integer value and it is set as string, it will give an exception.

Exceptions will include description about the error and it will exactly show in which line the error occurs.