Levix

Levix's zone

x
telegram

iOS 12.1 +版本 DeviceMotionEvent 和 DeviceOrientationEvent 事件使用问题

在 iOS 12. 1 以上版本,已经无法正常在浏览器或者 webview 中正常使用这两个事件,以前可以直接对 deviceorientation 进行监听,然后愉快地去获取设备的倾斜值,从而应用到实际的项目中,比如可以利用扩展设计器编写移动端扩展,从而可以在慧编程移动端上编写适合的小游戏,类似于重力感应可以实现很多有趣的东西。

而在 12.1 版本,官方默认将 Motion & Orientation settings 设置为禁用状态,可以打开 iPad 或者 iPhone 12.1 + 设备进入 settings - Safari - PRIVACY & SECURITY 中查看 Motion & Orientation Access 是否设置为可用,而在 13 版本中,官方已经将该入口隐藏,反正就是找不到了,一顿爆改。

IMG_0331

但其实不用担心,iOS 12.1 + 版本提供 DeviceMotionEvent.requestPermission()|DeviceOrientationEvent.requestPermission() 用于获取动作和方向权限,这样一调用会弹出系统框,用于获取该权限,当用户点了允许后,采取监听 deviceorientation|devicemotion 方法,这样问题就解决了,也可以引导用户去点击上图的设置,设置为可用状态即可,但是只针对 13 以下的版本,13 版本已经找不到该入口。

Untitled

实际的处理代码,可以参考下面示例。

		const getDeviceOrientationEventPermission = function () {
        if (DeviceOrientationEvent
            && DeviceOrientationEvent.requestPermission
            && typeof DeviceOrientationEvent.requestPermission === 'function'
        ) {
            DeviceMotionEvent.requestPermission().then(permissionState => {
							if(permissionState === "granted") {
								window.addEventListener("devicemotion", function (e) {}, false);
							} else if(permissionState === "denied") {
								console.warn("用户拒绝授权。");
							}
						});
        }
        if (DeviceOrientationEvent
            && DeviceOrientationEvent.requestPermission
            && typeof DeviceOrientationEvent.requestPermission === 'function'
        ) {
            DeviceOrientationEvent.requestPermission().then(permissionState => {
							if(permissionState === "granted") {
								window.addEventListener("deviceorientation", function (e) {}, false);
							} else if(permissionState === "denied") {
								console.warn("用户拒绝授权。");
							}
						});
        }
    }

而且需要注意的是,需要的进行授权的网站必须要有合格的 https 证书,否则在触发的时候,会抛出 Call to requestPermission() failed, reason: Browsing context is not secure. 错误,可以直接调试 iPad 端 Safari 打开的网站,直接输入 DeviceOrientationEvent.requestPermission() 即可知道是否允许授权,但实际应用中还是需要用户主动去触发获取权限,否则会抛出 Unhandled Promise Rejection: NotAllowedError: Requesting device orientation or motion access requires a user gesture to prompt 错误,可以直接打开 [baidu.com](http://baidu.com) 模拟一下,例如 document.getElementById('s_logo').onclick = getDeviceOrientationEventPermission ,这样只要点击以外的区域就可以正常弹出授权框。如果用户点了取消授权,会发现无论如何触发,授权窗口将不会再次唤起,只会输出 用户拒绝授权。 这一点跟 chrome 浏览器差不多,只能弹一次,后续只能用户自己去设置里进行授权。

Untitled 1

由于 iOS 12.1 + 版本对动作和方向事件的使用变得很严格,所以想在 webview 中正常使用该功能,其实就变得很麻烦,首先你通过 getDeviceOrientationEventPermission 想去打开授权窗口,肯定是打不开的,所以如果想在 webview 中使用类似于动作或者方向的事件,不仅要 web 端去获取权限,而且原生端也要提供对应的支持,iOS 13 版本已经添加了 DeviceMotionEvent and DeviceOrientation 接口。

综上所述,如果用户想在扩展设计器编写移动端扩展,想用到动作和方向事件,实际上是没法做到全设备支持的,所以需要做好实际区分,用户在使用扩展的时候,若用户实际版本是 12.1 + ,需要告知用户无法正常使用该功能。

参考链接

Safari 12.1 Release Notes

Safari 13 Release Notes

iOS13 にて javascript の devicemotion を取得する

Get device motion and orientation back on iOS 13

解决 ios13 中 safari 等浏览器无法启动陀螺仪 / 重力问题

DeviceMotion and DeviceOrientation in WKWebView iOS 13

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。