[HTML5] Accelerometer and iOS

A web app I’ve built has no issues registering a shake from Android (LG/Sony) phones, when using Chrome.

However, users have reported that Chrome under iOS is not registering a shake. I have implemented checks that determine if Accelerometer is supported (Accelerometer.isSupported) and not muted (accelerometer.muted), hiding the “shake” feature in the app if it fails either. It appears to be passing both of these checks on iOS, enabling the “shake” feature, but failing to actually trigger a shake.

Is anyone familiar with Accelerometer under iOS with the HTML5 target, and what might cause this?

A listener on the document.window is added here for DeviceMotionEvent:

Here is the listener callback:

Hmm, looks like it needs to request permission?

I wonder if there’s a simple way to know if it will be allowed. isSupported is probably true always on HTML5 right now

Thanks @singmajesty.

I think you’re right about needing to request permission. With at least iOS 13+, permission is explicitly required for accelerometer access.

It would also seem permission is automatically declined if the connection is not HTTPS (fortunately I already have this web-app running over HTTPS):

  • As per security considerations, iOS will auto-decline the requestPermission call if the page is not loaded over HTTPS.

I’ve put in the request permission code, but as yet I’ve still not been able to make things behave under iOS. Using the handy ExternalInterface class, I was at least able to adjust the apps behaviour based on whether it’s iOS 13+ or not.


<script type="text/javascript">		
	function isIOSCheck() {
		var isIOS = false;
		// If iOS 13+, the requestPermission() function will exist, in which case set isIOS to true and requestPermission.
		if (typeof DeviceMotionEvent.requestPermission === 'function')
			DeviceMotionEvent.requestPermission(); // Request permission, but don't wait for it.
			isIOS = true;
		// OpenFL callback.
		document.getElementById ("openfl-content").isIOSAnswer(isIOS);

Haxe code:

var accelerometerAvailable:Bool = false;
// Checks with an externally defined function, whether the device is using iOS 13+.
if (ExternalInterface.available) {
	// Define the callback function.
	ExternalInterface.addCallback ("isIOSAnswer", function (isIOS) {
		if (isIOS == false) accelerometerAvailable = true;
	// Call the external function.
	ExternalInterface.call ("isIOSCheck");