← All extensions

Native extension

KlugSystem

com.klug.system

NO APM NEEDED. Download and enjoy. It can’t get any simpler. Just update the Adobe AIR SDK. If you need help, we are here.

The system services every app needs, in one small extension: open web pages in an in-app browser, know whether the device is online and on Wi-Fi or mobile data, confirm the user with fingerprint or Face ID, and ask for a store rating.

iOSAndroid In production From €9 / year · Buy

Overview

Help pages, terms and privacy policies should open inside the app, not throw the user out to a browser. Network status decides whether to warn before streaming over mobile data. A fingerprint or Face ID check replaces typing a password on a shared device. KlugSystem covers all three with the system's own components.

The in-app browser is a Chrome Custom Tab on Android (no extra library needed) and SFSafariViewController on iOS, with your toolbar colour; your app is told when the user is back. Network status reports reachability and Wi-Fi versus mobile data and sends an event when it changes. Biometrics use BiometricPrompt on Android 9+ and LocalAuthentication on iOS; failures come with the same error codes on both platforms, so one handler works everywhere.

KlugSystem runs in the next release of our apps, our proof of concept, for help pages, the mobile-data warning and confirming a device logout.

Features

  • Self-contained: one ANE, no core library or dependency ANEs to add
  • In-app browser: Chrome Custom Tab (Android) / SFSafariViewController (iOS), toolbar colour, closed event
  • Network: reachable, Wi-Fi or mobile data, change events (ConnectivityManager / NWPathMonitor)
  • Biometrics: fingerprint and Face ID / Touch ID with your reason text and cancel label
  • Same error codes on both platforms (cancel, fallback, locked out, not enrolled)
  • No third-party libraries; on Android the store rating uses Google's own Play review library
  • isSupported check, so the same code runs on every platform

Supported platforms

iOS browser · network · Face ID / Touch ID · arm64
Android browser · network · fingerprint (Android 9+)

Devices without a biometric sensor report canAuthenticate = false, so your app can fall back to the password.

Getting started

Add the extension to your application descriptor:

app.xml
<extensions>
    <extensionID>com.klug.system</extensionID>
</extensions>

Android: add USE_BIOMETRIC, USE_FINGERPRINT and ACCESS_NETWORK_STATE to the manifest additions. iOS: add NSFaceIDUsageDescription to the InfoAdditions.

Code examples

Five complete flows. Every call returns at once; the browser, network and biometric results arrive as events of type KlugSystem.*. Full documentation →

1 · Open a help page in the in-app browser
Help.as
import com.klug.system.KlugSystem;
import flash.events.Event;
import flash.net.URLRequest;
import flash.net.navigateToURL;

var sys:KlugSystem = KlugSystem.getInstance();
sys.addEventListener( KlugSystem.BROWSER_CLOSED, onBrowserClosed );

function openHelp():void
{
    var url:String = "https://example.com/help";
    // false: not supported here, or no browser could open the page
    if ( !sys.isSupported || !sys.openBrowser( url, 0x2B2B2B ) )   // toolbar 0xRRGGBB
        navigateToURL( new URLRequest( url ) );
}

function onBrowserClosed( e:Event ):void
{
    // iOS: the user tapped Done. Android: your app is in the foreground again.
    refreshAccount();   // your app
}
2 · Warn before streaming over mobile data
Network.as
sys.addEventListener( KlugSystem.NETWORK_CHANGE, onNetworkChange );
sys.startNetworkWatch();   // the first event usually arrives right away

function onNetworkChange( e:Event ):void
{
    // the event carries no detail: ask for the current state
    if ( !sys.isReachable() )  showOfflineBanner();       // your app
    else if ( sys.isWWAN() )   showMobileDataWarning();   // on mobile data
    else                       hideBanners();
}
3 · Confirm the user with fingerprint or Face ID
Confirm.as
sys.addEventListener( KlugSystem.AUTH_SUCCESS, onAuthOk );
sys.addEventListener( KlugSystem.AUTH_FAILED,  onAuthFailed );

function confirmLogout():void
{
    // iOS: 1 = Touch ID, 2 = Face ID.
    // Android 9+: 1 = any enrolled biometric; 2 is always false there.
    var bio:Boolean = sys.canAuthenticate( KlugSystem.BIOMETRY_FINGERPRINT )
                   || sys.canAuthenticate( KlugSystem.BIOMETRY_FACE );

    if ( !bio || !sys.authenticate( "Confirm to log out", "Cancel" ) )
        askForPassword();   // no sensor, nothing enrolled, or Android below 9
}

function onAuthOk( e:Event ):void
{
    logOut();   // your app
}

function onAuthFailed( e:Event ):void
{
    // iOS error numbers on both platforms
    if ( sys.lastAuthError == -2 ) return;   // the user tapped Cancel
    askForPassword();   // -3 fallback (iOS), -8 locked out, -4 system cancel, -1 failed
}
4 · Ask for a store rating
Rating.as
// after a good moment, for example the tenth successful session
if ( sessionCount == 10 )   // your app's counter
    sys.requestReview();

// the store decides whether the dialog really appears:
// iOS at most 3 times in 365 days and never in TestFlight;
// Google Play has its own quota and never shows it for sideloaded installs
5 · Clean shutdown
Shutdown.as
function leaveScreen():void
{
    sys.stopNetworkWatch();
    sys.cancelAuthenticate();   // closes a running prompt; AUTH_FAILED may follow

    sys.removeEventListener( KlugSystem.NETWORK_CHANGE, onNetworkChange );
    sys.removeEventListener( KlugSystem.AUTH_SUCCESS, onAuthOk );
    sys.removeEventListener( KlugSystem.AUTH_FAILED, onAuthFailed );
}

API overview

KlugSystem.getInstance()Returns the single instance.
isSupportedTrue where the native part is present (iOS and Android).
openBrowser(url, toolbarColor)Opens the in-app browser, toolbar colour 0xRRGGBB (default white). Returns false if it could not open; BROWSER_CLOSED when the user is back.
isReachable() / isWWAN()Online at all / on mobile data.
startNetworkWatch() / stopNetworkWatch()NETWORK_CHANGE on every change; read isReachable() and isWWAN() in the handler.
canAuthenticate(type)True if the biometric is available and enrolled. iOS: BIOMETRY_FINGERPRINT = Touch ID, BIOMETRY_FACE = Face ID. Android 9+: BIOMETRY_FINGERPRINT = any biometric, BIOMETRY_FACE always false.
authenticate(reason, cancelLabel)Shows the system prompt; AUTH_SUCCESS or AUTH_FAILED. Returns false if no prompt can be shown (Android below 9).
lastAuthErrorError of the last AUTH_FAILED, iOS numbers on both platforms: -1 failed, -2 cancel, -3 fallback, -4 system cancel, -6 not available, -7 not enrolled, -8 locked out.
cancelAuthenticate()Closes a running prompt.
requestReview()Asks the App Store or Google Play for the in-app rating dialog; the store decides whether it shows.
BIOMETRY_FINGERPRINT, BIOMETRY_FACETypes for canAuthenticate(): 1 and 2.

Events

BROWSER_CLOSEDThe in-app browser is closed: Done on iOS, back in your app on Android.
NETWORK_CHANGEThe network changed (after startNetworkWatch()).
AUTH_SUCCESSThe user was confirmed.
AUTH_FAILEDNo confirmation; the reason is in lastAuthError.

Buy KlugSystem

A yearly licence for one AIR application, with all updates for 12 months. After payment you receive the extension, the ActionScript library and the documentation by e-mail, usually within one business day. Licence and terms

Simple
€9 / year
  • Licence for one AIR application
  • All updates for 12 months
  • No support
Buy Simple
Standard
€39 / year
  • Licence for one AIR application
  • All updates for 12 months
  • Answer by e-mail within 7 days
Buy Standard
Priority
€79 / year
  • Licence for one AIR application
  • All updates for 12 months
  • Answer by e-mail within 48 hours
Buy Priority
Taxes are calculated at checkout by Link (Stripe). You enter the application ID of your AIR app during checkout.

Requirements

AIR SDK51.x (HARMAN)
iOSiOS 13 or later
AndroidAndroid 6 or later; biometrics Android 9 or later
PermissionsAndroid: USE_BIOMETRIC, USE_FINGERPRINT, ACCESS_NETWORK_STATE · iOS: NSFaceIDUsageDescription