从ios12.2(具体版本可能有些许出入)开始,ios限制http地址的陀螺仪事件,必须https才可以,我们的站点必须是https才能正常生效,于是乎一大堆程序员吭哧吭哧的填好了坑。
当然虽然我们每天如履薄冰,战战兢兢,并不能改变线上某功能突然bug的现象。
于是乎突然有一天用户反馈,iphone xr的微信作品摇一摇不生效,在确认https无误后,便开始痛苦的联机调试,发现监听事件devicemotion未生效,从而查阅资料显示最新版系统陀螺仪功能增加了限制,必须用户手动授权才能正常,拉起授权的事件为
DeviceMotionEvent.requestPermission()
.then( response => {
if ( response == "granted" ) {
// 同意
} else {
// 拒绝
}
}).catch(() => {
// 一般为非用户主动授权
})
这里有几点需要注意:
- 整个app生命周期授权仅会被拉起一次,之后再次调用也不回拉起,会沿用之前的授权结果,可通过关闭微信来重新发起授权。
- 如果为第一次授权,必须通过用户交互后方可拉起授权。
因此根据上述情况,我们的流程图大概如下:
function iosCheck() {
return new Promise((resolve, reject) => {
if (typeof( DeviceMotionEvent ) !== "undefined" && typeof( DeviceMotionEvent.requestPermission ) === "function") {
getPermission().then(() => {
resolve();
}).catch((e) => {
// 用户拒绝
if (e.type === 1) {
// 用户上次状态为拒绝,提示弹窗
} else if (e.type === 2) { // 用户首次进入,获取权限失败,需手动开启,弹窗引导
// bind event
$(modal).on('touchstart', () => {
getPermission().then(() => {
resolve();
}).catch(() => {
// 用户拒绝授权,提示
});
})
}
});
} else {
resolve();
}
})
}
function getPermission() {
return new Promise((resolve, reject) => {
DeviceMotionEvent.requestPermission()
.then( response => {
if ( response == "granted" ) {
resolve();
} else {
reject({type: 1});
}
}).catch(() => {
reject({type: 2});
})
})
}
iosCheck().then(() => {
window.addEventListener('devicemotion', deviceMotionHandler, false);
})
当然如果更谨慎一些的话,我们可以在iosCheck方法中增加当前版本的限制。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。