一、背景
某个需求,用WKWebView打开某个H5页面,其中H5使用WebRTC技术,自行通过调用navigator.mediaDevices.getUserMedia方法来调起系统相机,询问权限。
二、问题现象
打开H5,获取系统相机时页面黑屏,H5报错文案提示设备/系统不支持。
三、问题出现时机
- 提测时测试正常通过,UAT时一直失败
- 有一部手机,安装提测包,获取相机失败,下午重启后又正常
- 有一部手机,本地跑工程,安装后获取相机失败。另外单独重新写一个webview打开H5,还是获取相机失败。最后新建一个app工程(在info.plist中写了NSCameraUsageDescription),webview打开H5页面,获取相机成功。回头进行对比排查问题。
四、结论
-
因为info.plist文件中没有写相机权限(NSCameraUsageDescription)!!!
工程中的权限声明是写在InfoPlist.strings中,用了Localization进行提示语国际化。
心路历程:
一开始,认为在InfoPlist.strings中写,和info.plist中效果一样,对比排查下来,发现是不一样的。
- 对于native来说,在询问权限时会优先取infoPlist.string的国际化文案,没有时,会取info.plist中默认文案。如果都没写,在申请权限时会crash。
对于H5来说,相机权限需要两层申请:
(1) 弹窗申请app访问系统相机的权限(和普通native申请的弹窗一样),猜测H5这一步只从info.plist中拿取!!不会管InfoPlist.strings。如果info.plist中没有,就会报错提示设备/系统不支持。
(2) 申请当前web页面访问相机的权限,用户同意后可正常使用相机。
如果在native中,之前已经申请通过了相机权限,H5只会进行上述第2步,且每次进入H5都会进行第2步申请权限。
- webRTC仅支持的iOS系统版本>=14.3,所以兼容方案:
(1) >=14.3的版本,在app中打开H5页面
(2) else,跳转到Safari中打开H5 - 在后续测试中还发现,同样的系统版本(>=14.3),在不同设备上,还存在无法调起相机的情况,最后发现在进H5入口之前native先申请好camera权限可以解决这个问题。所以最后 >=14.3的系统版本,在app中进入H5页面之前,先由native申请系统相机权限 = =
五、引用:
- WebKit getUserMedia bug 追踪:https://bugs.webkit.org/show_bug.cgi?id=208667
- WebKit getUserMedia bug 追踪2: https://bugs.webkit.org/show_bug.cgi?id=220184
- 其中提到一个solution for 《Camera for iOS is not working in inside webview》: https://github.com/react-native-webview/react-native-webview/issues/1672
- WebKit - MediaRecorder API
-
Requesting Authorization for Media Capture on iOS
心累。🙃