jasonelle - jasonelle stars - jasonelle forks - jasonelle

Jasonelle is a nice native wrapper for your Web Application.

view - Documentation


The project requires purchasing a license if you want to:

  • Use MPLv2 code.
  • Execute in real hardware.

With this small contribution you enable us to continue creating awesome tools for your web applications.

By adquiring a License Key you agree with the following:

  • Use Jasonelle's technologies and licenses in an ethical way.
  • Respect the artifacts license terms and conditions.
  • Must put a link to Jasonelle's Webpage (jasonelle.com) somewhere visible in your app.
  • Must not share the license keys with third parties.
  • Must not create direct competitors to Jasonelle by rebranding, customizing and reselling the framework and related technologies or services.

Please select the License Key that better fits your project.

Jasonelle Friend's Membership SubscriptionThank you Key
Monthly Payment RequirementSingle Payment
Jasonelle's Membership Keys can be used up to 5 projects, as long as the subscription is maintained.This license allows Jasonelle framework to be used by you or one client, in a single commercial end product.
The license expires if the membership is terminatedThank you key licenses do not expire. That's why they are a little more expensive than the subscription.
Join SubscriptionPurchase Thank you Key

Please go to Jasonelle Store to purchase a license and edit Love.h to allow real device execution and MPLv2 licensed code.

If no license is purchased then the code is under AGPLv3. And will not execute using real devices. Although you can activate the full mode if you want to test if Jasonelle is good for your use case (some features like GPS need real hardware for testing).

Please purchase a license key if you want to use Jasonelle's solutions in your project.

Since we cannot enforce this. We rely on your good heart. We trust you are a kind person who will activate this mode ethically.


For help and general chat go to our Telegram group.

The main repository is:


The latest releases are available at:


The current version is v3.


The projects documentation is inside the jasonelle.github.io repository. You can access it online at:


Jasonelle Project is dual licensed. You can choose between AGPLv3 or MPLv2. MPLv2 is only valid if the software has a unique Jasonelle Key which was purchased in official channels.

Read More.

🤩 Credits

Proudly Coded in - 🇨🇱 Chile Made With ❤️ By - Ninjas.cl


iOS Version

This small guide will help you getting started.


  • XCode 13 or greater
  • iOS 14 or greater


1 - Download the project

Download Bleeding Edge or Stable version.

  • Bleeding Edge: Latest updates, features and bug fixes. Built-in extensions enabled by default.

  • Stable version: Battle tested. Built-in extensions disabled by default.

Decompress and open App.xcworkspace file (White icon).

Find sources/xcode/App/JS/lib/screens/main.js.

2 - Configure your website

Put your URL for your application. This can be an external url or an HTML file.


Local Files

If you use res:// you can access local html files such as the example index.html.

You can store local files in the Files directory.


Is the example html file with code examples to test different Jasonelle features.

3 - Allowed URLs

By default Jasonelle will open all urls. If you wish to limit this behaviour you can use an allowed urls property in the configuration file.

Any url that is not present in the allowed list will force open using the native browser.

Check the Configuration File

config file


List the allowed urls. Otherwise it will launch native browser If not present will allow all urls

Put the same URL from main.js here to allow it (just the domain)

allowed: ["file://", "google.cl"]

4 - Done

You can now configure your project as a normal XCode iOS. Change your App Icon and other settings.

Happy Coding!.

ARM Processors (M1, M2...)

Ensure that you are running the arm binaries by appending -arm to the binaries names inside build file, as shown below.

Note: Since 3.0.2 this is automatically detected.

  • ESBUILD=${SRCROOT}/../Tools/esbuild/esbuild-arm
  • DPRINT=${SRCROOT}/../Tools/dprint/dprint-arm



Jasonelle's architecture is mainly composed of two different JavaScript Contexts. One is in the Kernel and the other is in the WKWebView instance.


The JLKernel is the main project for bootstrapping Jasonelle. It allows to communicate with the WKWebView and other tasks.


It's main tasks are:

  • Load configurations and other Javascript files, evaluate them and return the results.
  • Inject Javascript code to a Kernel Javascript Context (separated from the WebView).
  • Can use node_modules to allow use of external dependencies (they must be web browser compatible).

You can use the JSEngine by modifing the main.js. file.


The main.js file is capable of the following:

  • Import code from node_modules.
  • Define new actions than can be called from the webview using $agent.call().
  • Listen to native events in hooks.
  • Configure native components ($pull).

Built-in JS Functions

Some of the built-in functions are the following:

  • i18n: Enables using native translation strings functions. So you can translate using Localizable.strings files.
  • color: Enables generating colors in native formats.
  • uuid: Enables generating uuidv4 strings.
  • log: Enables logging with native logger.
  • openURL: Enables opening an URL like sms://, tel://, mailto://, facetime://.


Is the project that will render the WKWebView. You can inject Javascript code directly using the webview.js file.

Extensions will be mainly interacting with this component to inject new native functionality.

This is the Web Browser, it will have access to all your Javascript files and DOM. You can use it to modify behaviours and pass special params.

The following variables are injected to window by default:

  • $agent: Use this to call methods defined in Extensions and main.js.
  • $logger: Use this to call the native logger.
  • jasonelle: This variable contains info like Jasonelle's version. Use this to detect if you are inside a Jasonelle Web Wrapper in your website.
if (window.jasonelle && window.jasonelle.ready) {
  // Jasonelle Detected


All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog.

v3.0.2 (next)


  • [JLClipboard] Added $clipboard.set(text) and $clipboard.get() functions. This will allow copy and access text in native clipboard.

  • [JLDevice] Added $device.info() function. To provide access to native device information.

  • [JLContacts] Added $contacts.authorize() function. Now the extension would not trigger authorization on install.

  • [JLAudio] Added $audio extension. It has $audio.player, $audio.recorder and $audio.vibrate functions.

  • [JLPhotoLibrary] Added $photolibrary.camera.authorize() and $photolibrary.camera.granted() functions. The extension no longer triggers authorization on install.

  • [Core] Added a Makefile command to fix "bad interpreter: Operation not permitted" errors. This error maybe caused by downloading bash files from untrusted sources. Execute make permissions inside sources/xcode directory to fix any compilation problems with that issue.

  • [Core] Add a example.html file. Fill it with the examples for the extension.

  • [Core] Add a Build Phase Script in the framework project.


  • [Core] Improved the way the example html file is generated. Now extensions can add the examples on compilation time.

# Only copy the examples if the examples directory exists
if [ -d "${EXAMPLES_DIR}" ]
 cat "${SOURCES_DIR}/examples.html" > "${EXAMPLES_DIR}/${NAME}.example.html"


  • [ARM Macs]. Automatically detects processor and selects the proper build tool.
  • [Core]. Fixed crash when clicking a non html link (now shows SFSafariViewController).


v3.0.1 (March 2023)


  • Ability for extensions to inject Javascript to the WKWebView instance.

  • Ability for the WKWebView instance to load url by using deep links like: jasonelle://href?=https://google.cl.

  • Added JLPhotoLibrary extension that helps requesting access to photo library.

  • $keychain extension: $keychain.set, $keychain.get, $keychain.remove for usage within the WebView. This will enable storing data securely in the iOS's keychain.

  • $cookies extension: $cookies.set, $cookies.get, $cookies.remove for usage within the WebView. This will help with storing cookies in the keychain. Requires $keychain extension to be enabled. Also you can use $cookies.Cookies to access js-cookie library.

  • $contacts extension: $contacts.all for usage within the WebView.

  • Ability to have allowed list of urls in configuration. Not allowed urls will launch native browser.

  • Added LaunchScreen file (Both in SwiftUI and Storyboard file).

  • Added WebView.edgesIgnoringSafeArea(.all). Some websites need this, specially when using a navbar. Thanks to @Mättu in Telegram for pointing this out.

  • Added meta viewport js fix for websites that do not have proper metatag. In webview.js.

  • Added example extension.

  • Added hook triggering for extensions.

  • Added event triggering in webview for extensions.

  • Added Reachability Events Extension.


  • WKWebView triggered appdidLoad event more than once. Now it only triggers the event when loaded.

  • build.sh crashed when using paths with spaces.


v3.0.0 (September 2022)

This is a new engine created from scratch by Camilo in 2022. (AGPLv3 or MPLv2 Licenses). It was ditched the old json based approach to a javascript one. Consists of mainly a WebView engine, because there are lots of competition of "native over the wire" frameworks, and was better to focus on the Web App market such as Bubble users.

  • New rewrite of the engine from scratch.
  • Will only focus on webview workflow.
  • No need for Cocoapods, Carthage or Swift PM.
  • Native over the wire workflows delegated to other frameworks like Native Live.


Legacy Versions (2016 - 2022)

These versions are not currently supported, but maybe something can be learned or be useful. These were using the old engine created originally by Ethan. (MIT License).



A template is a pre configured App.xcworkspace file that is tailored for a specific use case.

They are meant to be used as an starting point for your application.

You can easily update the core if needed, just by replacing the directories.

Cocoapods Template

If you want to use Cocoapods you can use this starter template.

OneSignal Template

If you want to use OneSignal SDK you can use this starter template.

It contains the pre configured project. But it needs the specific configurations, such as capabilities, groups and other user related settings.

Agora SDK Template

This template uses the Agora SDK for realtime video application. It contains a bridge to show a view controller configured for Agora.

  • Use: $agora.start(appId, token, channel) in your webview to show the controller.
  • See Examples.

You can use it as a base for your own projects. It needs proper configuration and setup for your Agora Keys.


Extensions are a great way to add new functionality and helpers to Jasonelle. They can be updated separately from the core and be added or removed at will.

Adding an Extension

Extensions are a single *.xcodeproj (blue icon) that contains the project that can be added to the App.xcworkspace (white icon) file.

Step 1

Open App.xcworkspace with Xcode and look for the *.xcodeproj file in Finder.


Step 2

Draw it to the Extensions directory inside Xcode.



Step 3

Add it to the frameworks in App.xcproj file. Be sure that Embed & Sign option is selected.

added frameworks

Step 4

import the extension in AppExtensions.m.


and add it to the extension registry in install method using the class attribute.

Example: [self.extensions add: JLContacts.class];



If everything is ok then the extension was installed successfully, maybe some other configurations would be needed depending on the extension itself.

Removing an Extension

If you don't need an extension you can remove it from the workspace.

Step 1

Remove (or comment) the setup code in AppExtensions.m file described in Adding an Extension: Step 4.



Step 2

Remove the framework from the App.xcproj file.

added frameworks

Step 3

Delete the *.xcodeproj file from the Workspace. It will pop up a confirmation dialog. We recommend Remove Reference option.

remove reference

Create Extensions

Creating extensions requires some knowledge of Objective-C and JavaScript. These instructions are for advanced users.

Step 1

Create a new xcodeproj file.


Select Framework as the template. Be sure that is in the iOS tab.


Add it to the Extensions directory inside the App.xcworkspace.



Step 2

Configure the iOS Deployment Target to 14.0 (or the recommended version for your project).


Add the JLKernel framework. Select Do Not Embed as the option. Since all the frameworks will be embeded in App.xcproj later.


Step 3

Create the *.h and *.m files that inherits from JLExtension.






#import <Foundation/Foundation.h>

//! Project version number for MyExtension.
FOUNDATION_EXPORT double MyExtensionVersionNumber;

//! Project version string for MyExtension.
FOUNDATION_EXPORT const unsigned char MyExtensionVersionString[];

#import <JLKernel/JLKernel.h>


@interface MyExtension : JLExtension



#import "MyExtension.h"

@implementation MyExtension



Now you can install it as any other extension in your App.xcodeproj file.

Extension Coding

When coding an extension you can access some events and properties that will enable to add new features to Jasonelle.

- (void) install

This method will be executed when installing the extension in AppDelegate lifecycle. This is before all the extensions are ready, because a single extension is being installed at the time.

Be sure to call the [super install] method.

- (void) install {
    [super install];
    // your code here


The handlers are the names of the native bridges that will be called when used inside the webview. Must be configured in the install method.

See JLKeychain extension as an example with using handlers.

- (void) install {
  // ...
  self.handlers = @{
        @"$keychain.set": setHandler,
        @"$keychain.get": getHandler,
        @"$keychain.remove": removeHandler,
        @"$keychain.clear": clearHandler

A handler is a native function that is called within the webview.

Handlers will be called using $agent.trigger() inside the webview.

  • Example: $agent.trigger('$keychain.get')

They will return a JS Promise.

A wrapper can be created to call directly.

 (() => {
     if (window && window.$myextension) {
     window.$myextension = {};
     window.$myextension.run = () => $agent.trigger("$myextension.run", {});

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions

This method is called in AppDelegate after the setup and before loading the webview. Normally for post install logic. All the other extensions would be available at this point.

- (nonnull WKWebView *)appDidLoadWithWebView:(nonnull WKWebView *)webView

This method is called when the WKWebView is ready. You can use it to inject JavaScript files or make additional configurations to the webview element.

- (nonnull WKWebView *)appDidLoadWithWebView:(nonnull WKWebView *)webView {
    [super appDidLoadWithWebView:webView];
    return webView;


See JLCookies as an example extension that only loads a JS file.

More methods

See which other methods are available in JLApplicationExtensions

FileSystem Helper

You can access the filesystem by using the app.utils.fs helper.


Reads a file named JLContacts.js inside the self bundle.

NSString * js = [self.app.utils.fs

// If is named the same as the class then can be used like this
NSString * js = [self.app.utils.fs

WebView Helper

To help injecting scripts to webview you can use app.utils.webview helper.

webView = [self.app.utils.webview inject:@"js.cookie.min" intoWebView:webView for:self];

// Reads the filename as Classname.js
return [self.app.utils.webview inject:self intoWebView:webView];

Extension Service Locator

You can fetch the extension instance by using the app.ext service locator.

return (JLATTrackingManager *) [self.app.ext get:JLATTrackingManager.class];

return (JLApplicationBadge *) [self.app.ext get:JLApplicationBadge.class];


Optionally install ATTracking Support Request user authorization to access app-related data for tracking the user or the device. Ensure to configure the plist as well. If your app calls the App Tracking Transparency API, you must provide custom text, known as a usage-description string, which displays as a system-permission alert request. The usage-description string tells the user why the app is requesting permission to use data for tracking the user or the device.

  • Since: 3.0.1


Request user authorization to access app-related data for tracking the user or the device.



The ATTracking message will be triggered on install.


Configure your info.plist and include the NSUserTrackingUsageDescription key and fill it with the description.



Returns the current status for the ATTracking.


Can manipulate Application Icon Badge Number

  • Since: 3.0.1


The number currently set as the badge of the app icon on the Home screen.



  • $badge.clear: Cleans the badge number icon.
  • $badge.set: Sets the badge number icon.




A helper to work with the WebView cookies.

  • Since: 3.0.1


Requires $keychain extension.



  • $cookies.set: Stores document.cookie in keychain.
  • $cookies.get: Gets cookie value stored in keychain.
  • $cookies.remove: Removes cookies value from keychain.
  • $cookies.write: Gets the cookie value stored in keychain and write it to document.cookie.
  • $cookies.Cookies: js-cookie Helper.


Sets the cookie and save it to keychain

// Set a value inside document.cookies
$cookies.Cookies.set('name', 'Ethan'); 

// Save the document.cookies to keychain.
$cookies.set().then(val => alert(val));

Gets the current cookie value from keychain

$cookies.get().then(val => alert(val));

Reads cookie from keychain and then writes to document.cookie

$cookies.write().then(val => alert(val));

Removes cookies from keychain

$cookies.remove().then(val => alert(val));


Keychain extension allows storing values inside iOS Keychain

  • Since: 3.0.1


Keychain is made as a key - value secure storage.



  • $keychain.set: Sets a key to store a value.
  • $keychain.get: Gets the value for a given key.
  • $keychain.remove: Removes a key from the keychain.
  • $keychain.clear: Removes all keys and values from the keychain.


// Stores the number 3 in keychain
$keychain.set('number', 3);

// Get the number 3 and show an alert with it
$keychain.get('number').then(num => alert(num));

// Removes the stored number

// Clears the keychain


Provides methods to requesting Photo Library and Camera permissions

  • Since: 3.0.1


It would be required if your app wants to access camera or photo library.




  • Since 3.0.1

Returns Promise.resolve(Bool) if the permission is granted.


$photolibrary.granted().then(granted => alert(granted));

$photolibrary.authorize(showAlert = true)

  • Since 3.0.1

Returns Promise.resolve(Int) with the Authorization Status.

If showAlert = true then it will prompt an alert requesting the user go Settings.

The returned number corresponds to PHAuthorizationStatus

By default will request access to all photos.


$photolibrary.authorize().then(status => $logger.trace(status));


  • Since 3.0.2

Returns Promise.resolve(Bool) if the camera permission is granted.


$photolibrary.granted().then(granted => alert(granted));

$photolibrary.camera.authorize(showAlert = true)

  • Since 3.0.2

Returns Promise.resolve(Int) with the Camera authorization status.

If showAlert = true then it will prompt an alert requesting the user go Settings.

The returned number corresponds to AVAuthorizationStatus


$photolibrary.camera.authorize().then(status => $logger.trace(status));


Add the following permissions to info.plist:

<string>If you want to use the photolibrary, you have to give permission.</string>
<string>If you want to use the camera, you have to give permission.</string>


The Contacts extension provides APIs to access the user’s contact information.

  • Since: 3.0.1


An iOS app linked on or after iOS 10 needs to include in its Info.plist file the usage description keys for the types of data it needs to access or it crashes. To access Contacts data specifically, it needs to include NSContactsUsageDescription.

More Info



"name": String,
"lastname": String,
"phone": String,
"phones": Array,
"email": String,
"emails: Array,
"address": String,
"addresses": Array



Returns a promise with all the contacts.

  • Since 3.0.1

  • Return

    "phone": "5555648583",
    "phones": ["5555648583", "4155553695"],
    "emails": ["kate-bell@mac.com"],
    "address": "165 Davis Street\nHillsborough CA 94010",
    "lastname": "Bell",
    "addresses": ["165 Davis Street\nHillsborough CA 94010"],
    "email": "kate-bell@mac.com",
    "name": "Kate"
}, {
    "phone": "5554787672",
    "phones": ["5554787672", "4085555270", "4085553514"],
    "emails": ["d-higgins@mac.com"],
    "address": "332 Laguna Street\nCorte Madera CA 94925\nUSA",
    "lastname": "Higgins",
    "addresses": ["332 Laguna Street\nCorte Madera CA 94925\nUSA"],
    "email": "d-higgins@mac.com",
    "name": "Daniel"
}, {
    "phone": "8885555512",
    "phones": ["8885555512", "8885551212"],
    "emails": ["John-Appleseed@mac.com"],
    "address": "3494 Kuhl Avenue\nAtlanta GA 30303\nUSA",
    "lastname": "Appleseed",
    "addresses": ["3494 Kuhl Avenue\nAtlanta GA 30303\nUSA", "1234 Laurel Street\nAtlanta GA 30303\nUSA"],
    "email": "John-Appleseed@mac.com",
    "name": "John"
}, {
    "phone": "5555228243",
    "phones": ["5555228243"],
    "emails": ["anna-haro@mac.com"],
    "address": "1001  Leavenworth Street\nSausalito CA 94965\nUSA",
    "lastname": "Haro",
    "addresses": ["1001  Leavenworth Street\nSausalito CA 94965\nUSA"],
    "email": "anna-haro@mac.com",
    "name": "Anna"
}, {
    "phone": "5557664823",
    "phones": ["5557664823", "7075551854"],
    "emails": ["hank-zakroff@mac.com"],
    "address": "1741 Kearny Street\nSan Rafael CA 94901",
    "lastname": "Zakroff",
    "addresses": ["1741 Kearny Street\nSan Rafael CA 94901"],
    "email": "hank-zakroff@mac.com",
    "name": "Hank"
}, {
    "phone": "5556106679",
    "phones": ["5556106679"],
    "emails": [],
    "address": "1747 Steuart Street\nTiburon CA 94920\nUSA",
    "lastname": "Taylor",
    "addresses": ["1747 Steuart Street\nTiburon CA 94920\nUSA"],
    "email": "",
    "name": "David"


Starts the authorization flow. Returns an Promise. Resolves with object with the authorization status. Rejects with an error message.

  • Since 3.0.2
  • Schema
"granted": "Bool",
"status": {
    "id": "CNAuthorizationStatus",
    "name": "String"

status.id referes to CNAuthorizationStatus.



Join all the contacts by the first name in a single string. And present an alert.

$contacts.all().then(val => alert(val.reduce((acc, v) => acc + v.name + ' ', '')))


Logs the resulting object.

$contacts.all().then(info => $logger.trace(JSON.stringify(info)))


const authorizeContacts = () => $contacts.authorize().then(res => alert(res.status.name));


Helps to detect when access to internet was lost.

  • Since: 3.0.1


Sends a notification event inside the WebView and NSNotificationCenter.



Be sure to add SystemConfiguration.framework in Bundle Without Signing mode.


const reachability = {
    // Apple NetworkStatus Compatible Names.
    status: {
        not_reachable: 0,
        wwan_reachable: 1,
        cellular_reachable: 1, // the same as wwan, just to have ubiquotus language
        wifi_reachable: 2
    status_names: {
       0: "No Connection",
       1: "Cellular",
       2: "Wifi"


  • $reachability.get: Returns the current reachability object.


    "status": Number, // Status of the Connection
    "reachable": Boolean, // true if is reachable
    "label": String // String with the current connection label


$reachability.get().then(result => alert(result.label));


  • $reachability.events.changed: Triggered when a change in reachability is detected.


document.addEventListener("$reachability.events.changed", function(e) {
    $logger.trace("Reachability Changed: " + JSON.stringify(e.detail));


An NSNotification is sent with the name kReachabilityChangedNotification.

// Here we set up a NSNotification observer. The Reachability that caused the notification
// is passed in the object parameter
[[NSNotificationCenter defaultCenter] addObserver:self

See more details at Tony Million's Reachability Docs.


A simple wrapper to record and play audio files using the native device apis.

  • Since: 3.0.2





  • Since 3.0.2

Sends the vibration alarm sound. Works for iPhones regardless of silent switch position.

Audio Player Actions

This interacts directly with AVPlayer.

The current player support up to 16 channels. With channel 0 as the default. You can individually play each channel and set options such as volume.

$audio.player.load(url, options = {channel = 0, volume = 1})

  • Since: 3.0.2

Loads an audio file from a remote url.

$audio.player.play(channel = 0, options = {})

  • Since: 3.0.2

Plays the audio file at the given channel with options. Defaults to channel 0.

$audio.player.pause(channel = 0, options = {})

  • Since: 3.0.2

Pauses the audio file playing at given channel with options. Defaults to channel 0.

Audio Recording Actions


  • Since 3.0.2

Authorizes audio recording capabilities. Must set NSMicrophoneUsageDescription in info.plist.

Returns a Promise. Rejects it if access was not granted.


$audio.recorder.authorize().then(granted => $logger.trace(`Audio Recording is granted?: ${granted}`))
   .catch(message => $logger.trace("Audio Recording Authorization Not Granted"));


  • Since 3.0.2

Starts recording. Triggers $audio.recorder.status.event every 0.5 seconds.


  • Since 3.0.2

Stops the current recording. Triggers $audio.recorder.finished.event.


  • Since 3.0.2

Pauses/Resumes the current recording.


  • Since 3.0.2

Returns the current status for the recording and additional information.


    "file": {
        "url": self.file.absoluteString,
        "url_components": self.file.pathComponents
    "state": self.state,
    "settings": self.settings,
    "time": {
        "audio": {
            "formatted": [self timeStringForTimeInterval:self.recorder.currentTime],
            "current": self.recorder.currentTime,
        "device": {
            "formatted": [self timeStringForTimeInterval:self.recorder.deviceCurrentTime],
            "current": self.recorder.deviceCurrentTime
  • Since 3.0.2

The recording ended and returns the information for the file. Audio data is encoded in a Base64 string so it can be easily send via http requests.


    "status": self.currentStatus,
    "file": {
        "url": self.file.absoluteString,
        "url_components": self.file.pathComponents,
        "data": self.base64Data,
        "uri": self.base64DataURI,
        "content_type": self.contentType,
        "time": {
            "formatted": self.duration,
            "total": self.seconds,
  • Since 3.0.2

Returns some information if there was an error recording.


   "message": error.localizedDescription,
   "code": error.code,
   "info": error.userInfo,
   "file": {
        "url": self.file.absoluteString,
        "url_components": self.file.pathComponents


Enables access to device's info.


Provides access to the current device model, size, system and vendor identifiers.



  • $device.info()

  • Since: 3.0.2

Returns an object with current device info.


const deviceInfo = () => $device.info().then(info => {
    env =     {
        hw =         {
            id = 0;
            name = simulator;
        type =         {
            id = 1;
            name = develop;
    license =     {
        enabled = 1;
    process =     {
        device =         {
            model =             {
                localized = iPhone;
                name = iPhone;
            name = "iPhone SE (2nd generation)";
            orientation =             {
                id = 1;
                portrait = 1;
            size =             {
                height = 667;
                width = 375;
            system =             {
                name = iOS;
                simulator = 1;
                version = "14.0.1";
        identifiers =         {
            vendor = "32DD46B4-323B-4396-B3CA-BE232104423";


Handles native Clipboard actions


Provides access to native clipboard



  • $clipboard.set(text)
  • Since 3.0.2

Copy text to the native clipboard.

  • $clipboard.get()
  • Since 3.0.2

Returns the current text in the native clipboard.

$clipboard.get().then(text => alert(text));


Present different message Toast and banners that allow displaying quick information using native features.


Useful if you want to present information to the user.


Loading Indicator

The loading indicator can show a task is executing and will block any other interaction until the task is ready.


  • Since: 3.0.2

It will show a loading indicator (will block any other interaction).



  • Since: 3.0.2

It will hide the loading indicator (if present).



The toast is a small message that can appear from top, center or bottom of the screen for a few seconds.

$toast.show(text, options = {type, position, duration})

  • Since: 3.0.2

It will show a text for a given duration (defaults 3 seconds).


$toast.dark(text, options = {})

  • Since: 3.0.2

It will show a text in dark background for a given duration (defaults 3 seconds).


$toast.error(text, options = {})

  • Since: 3.0.2

It will show a text in red background for a given duration (defaults 3 seconds).


$toast.success(text, options = {})

  • Since: 3.0.2

It will show a text in green background for a given duration (defaults 3 seconds).


$toast.warning(text, options = {})

  • Since: 3.0.2

It will show a text in yellow background for a given duration (defaults 3 seconds).


$toast.info(text, options = {})

  • Since: 3.0.2

It will show a text in white background for a given duration (defaults 3 seconds).


The banner is an element that always appears from the upper part. Similar to a Push Notification UX.

$toast.banner.show(text, options = {type, duration})

  • Since: 3.0.2

It will show a text for a given duration (defaults 3 seconds).


$toast.banner.dark(text, options = {})

  • Since: 3.0.2

It will show a text in dark background for a given duration (defaults 3 seconds).


$toast.banner.error(text, options = {})

  • Since: 3.0.2

It will show a text in red background for a given duration (defaults 3 seconds).


$toast.banner.success(text, options = {})

  • Since: 3.0.2

It will show a text in green background for a given duration (defaults 3 seconds).


$toast.banner.warning(text, options = {})

  • Since: 3.0.2

It will show a text in yellow background for a given duration (defaults 3 seconds).


$toast.banner.info(text, options = {})

  • Since: 3.0.2

It will show a text in white background for a given duration (defaults 3 seconds).



Enables using UIActivityViewController.


Useful if you want to share text, links and other content to other applications.



  • Since 3.0.2

Will open share dialog with a text.

const shareText = () => {
  $share.text("Hello World!");


  • Since 3.0.2

Will open share dialog with an url value. The url must be a valid url, otherwise it will be interpreted as a text.

You can point to public files like images, pdf, audios and videos and they will be recognized as such and shared properly.

const shareImage = () => {
    return $share.url("https://jasonelle.com/docs/jasonelle.png");