JavaScript API: Best Practices

Accessing API Functions

The following are recommended best practices for accessing Kiosk Pro's JavaScript API.  We highly recommend reviewing these prior to starting any development with the API. 

Access the JavaScript API > By Import.

  • This is configured in the app settings under 'Content' > 'JavaScript API'. This is the default for our Enterprise version, but must be updated prior to calling any API functions in Basic or Plus. 
  • If accessing the JavaScript API by import, you must include a reference to the app's 'kiosk_functions.js' file in the page before any JavaScript calls to the API. Kiosk Pro uses this file to initialize any calls to the API.
  • Accessing the API by injection is currently only supported for backward-compatibility and may be deprecated in a future release.

Do not modify the 'kiosk_functions.js' file.

  • Include any calls to the API in the page calling the API functions (as shown in the sample code provided) or maintain and link in a file that is separate from the 'kiosk_functions.js' file generated by Kiosk Pro.
  • Modifying the file makes it significantly more complex to update later if required. While we try to prevent any breaking changes to the 'kiosk_functions.js' file when updating the app, there have been changes at the operating system level that have necessitated updating this file in the past. If a breaking change occurs, it will be noted in the app's change logs.

Store 'kiosk_functions.js' with your content.

  • Be aware that the 'kiosk_functions.js' file referenced in our sample code may be updated or moved without warning. If this occurs and you are referencing the file directly from our server, this would prevent your kiosks from working correctly.
  • To get a current version of the 'kiosk_functions.js' file for the version of the app you are using, open the app's settings menu > JavaScript API > Generate API Functions File. The file will be generated locally on the device in Kiosk Pro's documents folder and can be transferred to a desktop computer using iTunes if needed.
  • If you are storing your content locally, the file can be referenced directly from the apps's documents folder using a relative filepath.
  • If your content will be online, host 'kiosk_functions.js' on your own server or a content delivery network (CDN).
  • Make sure to change the filepath in your code to reflect the new location.


Using API Callbacks

Kiosk Pro's JavaScript API uses two types of callbacks: 

App-defined Callbacks

App-defined callbacks are named by the app and are triggered every time a specific event occurs. 

For example, the Screen Orientation API callback kp_Device_didRotateToOrientation(deviceOrientationInDegrees) is triggered when the page is loaded (to return the initial screen orientation) and then again whenever the tablet's orientation changes. 

To use this type of callback, define the callback in a script at the top of your page and tell the page what to do when the callback is triggered inside that function: 

	function kp_Device_didRotateToOrientation(deviceOrientationInDegrees) {
		switch(deviceOrientationInDegrees) {
		  case 90:
			document.getElementById('orientationMessage').innerHTML = 'I'm right side up!';
			break;
		  default:
			document.getElementById('orientationMessage').innerHTML = 'Whoops, turn me over!';
			break;
		}
	}

User-defined Callbacks

User-defined callbacks are triggered automatically after executing certain API function calls.  This type of callback will only be triggered after the associated function call and may also have specific return values.

Unlike an app-defined callback, a user-defined callback is named in the function call triggering it as a parameter.

While the name of this type of callback is defined by the user, the structure of the callback and its possible return values are defined by the app and will be shown in our API documentation. For example: 

When you trigger this function, you name the callback as a parameter on the call itself.  For example: 

kp_requestKioskId('requestKioskId_callback');

Just like the app-defined callbacks above, you then define the callback in a script at the top of your page and tell the page what to do when the callback is triggered inside that function: 

	function requestKioskId_callback(kioskId) {
		if (kioskId === "") {
			// code to execute when Unique iPad ID is not configured in Kiosk Pro's settings goes here
			document.getElementById('requestKioskId_result').innerHTML = 'Unique iPad ID is not configured in Kiosk Pro\'s settings.';	
		} 
		else {
			// code to execute when Unique iPad ID is returned goes here
			document.getElementById('requestKioskId_result').innerHTML = 'Unique iPad ID is \'' + kioskId + '\'';
		}
	}

The main value of user-defined callbacks is that they allow you to trigger a single API function multiple times and treat the result differently.  

For example, let's say you were using the External Screen API and wanted to show a short video, then ask the visitor a question about that video, then play a success or failure video depending on the result. You could trigger the first video playback with a user-defined callback that set a variable telling the page to trigger the survey at the end of playback, then you could trigger the success or failure video using the same API function call, but a user-defined callback with a different name that set a variable telling the page to trigger the idle timer at the end of playback. Same function call, but different results. 

Creating a chain of callbacks

You can call multiple API functions in a row by chaining callbacks together. Using External Screen API functions as an example:

function setBackground() {
	kp_ExternalScreen_setBrowserBgColor('255,255,255','setBrowserBgColor_callback');	
}
function setBrowserBgColor_callback() {
	kp_ExternalScreen_openDocument('img/logo-screen.png','openDocument_callback');
}
function openDocument_callback(success) {
	window.kp_ExternalScreen_setPlayVideoParams('1','0,0,0','setPlayVideoParams_callback');
}
setBackground();

In this scenario, the 'setBackground()' function triggers an API function to set the background color and names a user-defined callback, 'setBrowserBgColor_callback'. This 'setBrowserBgColor_callback' callback triggers another API function to open a document and names another user-defined callback. The third callback is used to set the parameters for playing a video.


Debugging JavaScript in Kiosk Pro

When working with JavaScript, there isn't a standard console interface for Kiosk Pro, which can be challenging.

The only way iOS/iPadOS currently allows third-party apps to access the native Web Inspector tool is through the iOS Simulator in Xcode or on a device with a development provisioning profile for that app installed. This means that this level of debugging is only available to our internal development team.

When we are working on a project in-house and don’t have immediate access to the simulator, we’ll often use simple 'alert();' statements to determine what is being executed and what isn't.

For more complex projects, we frequently use a console print debugger developed by E.J. Dyksen and the team at Mutually Human. In this set-up, you drop a console div into the bottom of the page you are working on and then any calls to console.log are shown there. The debugger also includes a text box below the console, allowing you to evaluate JavaScript expressions directly on the page.

<div id="consolelog" style="font-family: 'Courier New', Courier, monospace; font-size: 12px; margin: 40px 30px 0px; background-color: white; border: 2px solid black; padding: 10px;"></div>

<input type="text" id="consoleinput" style="margin: 0px 30px; width: 400px;" onkeypress="return evalConsoleInput(event, this.value);" />

<script type="text/javascript">
	var appendConsole = function(message, type) {
		var color = "black";
		if (type === "error") {
			color = "red";
		} else if (type === "debug") {
			color = "blue";
		}
		var div = document.createElement('div');
		div.style.color = color;
		div.style.marginBottom = "10px";
		div.innerHTML = message;
		document.getElementById("consolelog").appendChild(div);
	}
	var originalConsole = null;
	if (window.console != null) {
		originalConsole = window.console;
	}
	window.console = {
		log: function(message) {
			appendConsole(message, "info");
			originalConsole.log(message);
		},
		info: function(message) {
			appendConsole(message, "info");
			originalConsole.info(message);
		},
		debug: function(message) {
			appendConsole(message, "debug");
			originalConsole.debug(message);
		},
		error: function(message) {
			appendConsole(message, "error");
			originalConsole.error(message);
		}
	};
	function evalConsoleInput(e, message) {
		if (e.keyCode == 13) { // 13 is the keycode for the enter key
			var inputField = document.getElementById("consoleinput");
			var evalString = inputField.value;
			console.log("> " + evalString);
			try {
				var returnValue = eval(evalString);
				console.log(returnValue);
    			} catch (e) {
				console.error(e.message);
			} finally {
				inputField.value = "";
			}
		}
	}
</script>

More details on this debugger are available here.

Still stuck? How can we help? How can we help?