Jasonelle
Jasonelle is a nice native wrapper for your Web Application.
Price
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 Subscription | Thank you Key |
---|---|
Monthly Payment Requirement | Single 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 terminated | Thank you key licenses do not expire. That's why they are a little more expensive than the subscription. |
Join Subscription | Purchase 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.
Community
For help and general chat go to our Telegram group.
The main repository is:
Releases
The latest releases are available at:
Downloads
The current version is v3.
Documentation
The projects documentation is inside the jasonelle.github.io
repository. You can access it online at:
License
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.
🤩 Credits
iOS Version
This small guide will help you getting started.
Requirements
- XCode 13 or greater
- iOS 14 or greater
Steps
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.
index.html
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
Example
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
Architecture
Jasonelle's architecture is mainly composed of two different JavaScript Contexts. One is in the Kernel and the other is in the WKWebView instance.
JLKernel
The JLKernel is the main project for bootstrapping Jasonelle. It allows to communicate with the WKWebView and other tasks.
JSEngine
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.
main.js
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 generatinguuidv4
strings.log
: Enables logging with native logger.openURL
: Enables opening an URL likesms://
,tel://
,mailto://
,facetime://
.
WebViewRenderer
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 andmain.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
}
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
v3.0.2 (next)
Added
-
[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
insidesources/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.
Changed
- [Core] Improved the way the example html file is generated. Now extensions can add the examples on compilation time.
NAME="MyExtension"
EXAMPLES_DIR="${PWD}/../../App/Files/Examples"
TEMPLATES_DIR="${EXAMPLES_DIR}/Templates"
SOURCES_DIR="${PWD}/${NAME}"
# Only copy the examples if the examples directory exists
if [ -d "${EXAMPLES_DIR}" ]
then
cat "${SOURCES_DIR}/examples.html" > "${EXAMPLES_DIR}/${NAME}.example.html"
fi
Fixed
- [ARM Macs]. Automatically detects processor and selects the proper build tool.
- [Core]. Fixed crash when clicking a non html link (now shows SFSafariViewController).
Downloads
v3.0.1 (March 2023)
Added
-
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.
Fixed
-
WKWebView
triggeredappdidLoad
event more than once. Now it only triggers the event when loaded. -
build.sh
crashed when using paths with spaces.
Downloads
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.
Downloads
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).
Downloads
Templates
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
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.
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];
Done
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.
Step 3
Delete the *.xcodeproj
file from the Workspace.
It will pop up a confirmation dialog. We recommend Remove Reference
option.
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.
Example
MyExtension.h
#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>
NS_ASSUME_NONNULL_BEGIN
@interface MyExtension : JLExtension
@end
NS_ASSUME_NONNULL_END
MyExtension.m
#import "MyExtension.h"
@implementation MyExtension
@end
Done
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
}
self.handlers
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
};
}
Handlers
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.
- Example: JLContacts.js
(() => {
if (window && window.$myextension) {
return;
}
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;
}
Examples
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.
Example
Reads a file named JLContacts.js inside the self bundle.
NSString * js = [self.app.utils.fs
readJS:@"JLContacts"
for:self];
// If is named the same as the class then can be used like this
NSString * js = [self.app.utils.fs
readJSFor:self];
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];
JLATTrackingManager
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
Overview
Request user authorization to access app-related data for tracking the user or the device.
Topics
Installation
The ATTracking message will be triggered on install
.
info.plist
Configure your info.plist
and include the NSUserTrackingUsageDescription
key and fill it with the description.
Properties
status
Returns the current status for the ATTracking.
JLApplicationBadge
Can manipulate Application Icon Badge Number
- Since:
3.0.1
Overview
The number currently set as the badge of the app icon on the Home screen.
Topics
Actions
$badge.clear
: Cleans the badge number icon.$badge.set
: Sets the badge number icon.
Example
$badge.set(3);
$badge.clear();
JLCookies
A helper to work with the WebView
cookies.
- Since:
3.0.1
Overview
Requires $keychain
extension.
Topics
Actions
$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.
Examples
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.Cookies.remove('name');
$cookies.remove().then(val => alert(val));
JLKeychain
Keychain extension allows storing values inside iOS Keychain
- Since:
3.0.1
Overview
Keychain is made as a key - value secure storage.
Topics
Actions
$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.
Example
// 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
$keychain.remove('number');
// Clears the keychain
$keychain.clear();
JLPhotoLibrary
Provides methods to requesting Photo Library and Camera permissions
- Since:
3.0.1
Overview
It would be required if your app wants to access camera or photo library.
Topics
Actions
$photolibrary.granted()
- Since
3.0.1
Returns Promise.resolve(Bool)
if the permission is granted.
Example
$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.
Example
$photolibrary.authorize().then(status => $logger.trace(status));
$photolibrary.camera.granted()
- Since
3.0.2
Returns Promise.resolve(Bool)
if the camera permission is granted.
Example
$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
Example
$photolibrary.camera.authorize().then(status => $logger.trace(status));
info.plist
Add the following permissions to info.plist
:
-
PHPhotoLibraryPreventAutomaticLimitedAccessAlert Set to
YES
. -
NSPhotoLibraryAddUsageDescription Description.
<key>NSPhotoLibraryUsageDescription</key>
<string>If you want to use the photolibrary, you have to give permission.</string>
<key>NSCameraUsageDescription</key>
<string>If you want to use the camera, you have to give permission.</string>
JLContacts
The Contacts extension provides APIs to access the user’s contact information.
- Since:
3.0.1
Overview
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
Topics
Schema
"name": String,
"lastname": String,
"phone": String,
"phones": Array,
"email": String,
"emails: Array,
"address": String,
"addresses": Array
Actions
$contacts.all()
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"
}]
$contacts.authorize()
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.
Examples
Alert
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 + ' ', '')))
Log
Logs the resulting object.
$contacts.all().then(info => $logger.trace(JSON.stringify(info)))
Authorize
const authorizeContacts = () => $contacts.authorize().then(res => alert(res.status.name));
JLReachability
Helps to detect when access to internet was lost.
- Since:
3.0.1
Overview
Sends a notification event inside the WebView and NSNotificationCenter.
Topics
Configuration
Be sure to add SystemConfiguration.framework in Bundle Without Signing mode.
Status
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"
}
};
Actions
$reachability.get
: Returns the current reachability object.
Schema
{
"status": Number, // Status of the Connection
"reachable": Boolean, // true if is reachable
"label": String // String with the current connection label
}
Example
$reachability.get().then(result => alert(result.label));
Events
$reachability.events.changed
: Triggered when a change in reachability is detected.
Example
document.addEventListener("$reachability.events.changed", function(e) {
$logger.trace("Reachability Changed: " + JSON.stringify(e.detail));
});
Notification
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
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
See more details at Tony Million's Reachability Docs.
JLAudio
A simple wrapper to record and play audio files using the native device apis.
- Since:
3.0.2
Overview
Topics
Vibration
$audio.vibrate()
- 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
$audio.recorder.authorize()
- Since
3.0.2
Authorizes audio recording capabilities. Must set NSMicrophoneUsageDescription
in info.plist
.
Returns a Promise
. Rejects it if access was not granted.
Example
$audio.recorder.authorize().then(granted => $logger.trace(`Audio Recording is granted?: ${granted}`))
.catch(message => $logger.trace("Audio Recording Authorization Not Granted"));
$audio.recorder.record()
- Since
3.0.2
Starts recording. Triggers $audio.recorder.status.event
every 0.5
seconds.
$audio.recorder.stop()
- Since
3.0.2
Stops the current recording. Triggers $audio.recorder.finished.event
.
$audio.recorder.pause()
- Since
3.0.2
Pauses/Resumes the current recording.
Events
$audio.recorder.status.event
- Since
3.0.2
Returns the current status for the recording and additional information.
event.detail
{
"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
}
},
}
$audio.recorder.finished.event
- 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.
event.detail
{
"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,
}
}
}
$audio.recorder.error.event
- Since
3.0.2
Returns some information if there was an error recording.
event.detail
{
"message": error.localizedDescription,
"code": error.code,
"info": error.userInfo,
"file": {
"url": self.file.absoluteString,
"url_components": self.file.pathComponents
}
}
JLDevice
Enables access to device's info.
Overview
Provides access to the current device model, size, system and vendor identifiers.
Topics
Actions
-
$device.info()
-
Since:
3.0.2
Returns an object with current device info.
Example
const deviceInfo = () => $device.info().then(info => {
$logger.trace(info);
alert(info.env.hw.name);
});
{
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";
};
};
}
JLClipboard
Handles native Clipboard actions
Overview
Provides access to native clipboard
Topics
Actions
$clipboard.set(text)
- Since
3.0.2
Copy text to the native clipboard.
$clipboard.set("Hello")
$clipboard.get()
- Since
3.0.2
Returns the current text in the native clipboard.
$clipboard.get().then(text => alert(text));
JLToast
Present different message Toast
and banners that allow displaying quick information using native features.
Overview
Useful if you want to present information to the user.
Topics
Loading Indicator
The loading indicator can show a task is executing and will block any other interaction until the task is ready.
$toast.loading.show
- Since:
3.0.2
It will show a loading indicator (will block any other interaction).
$toast.loading.show();
$toast.loading.hide
- Since:
3.0.2
It will hide the loading indicator (if present).
$toast.loading.hide();
Toast
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.show("Hello!");
$toast.dark(text, options = {})
- Since:
3.0.2
It will show a text in dark background for a given duration (defaults 3 seconds).
$toast.dark("Hello!");
$toast.error(text, options = {})
- Since:
3.0.2
It will show a text in red background for a given duration (defaults 3 seconds).
$toast.error("Hello!");
$toast.success(text, options = {})
- Since:
3.0.2
It will show a text in green background for a given duration (defaults 3 seconds).
$toast.success("Hello!");
$toast.warning(text, options = {})
- Since:
3.0.2
It will show a text in yellow background for a given duration (defaults 3 seconds).
$toast.warning("Hello!");
$toast.info(text, options = {})
- Since:
3.0.2
It will show a text in white background for a given duration (defaults 3 seconds).
$toast.info("Hello!");
Banner
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.show("Hello!");
$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.dark("Hello!");
$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.error("Hello!");
$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.success("Hello!");
$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.warning("Hello!");
$toast.banner.info(text, options = {})
- Since:
3.0.2
It will show a text in white background for a given duration (defaults 3 seconds).
$toast.info("Hello!");
JLShare
Enables using UIActivityViewController.
Overview
Useful if you want to share text, links and other content to other applications.
Topics
$share.text(value)
- Since
3.0.2
Will open share dialog with a text.
const shareText = () => {
$share.text("Hello World!");
};
$share.url(value)
- 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");
};