如果用户拒绝访问相机,如何防止 WKWebView 显示相机模式?
How do I prevent a WKWebView from presenting the Camera modal if a user has denied access to the camera?
在我的应用程序中,我有一个 WKWebView
加载带有文件输入的网站,允许用户通过相机或照片库上传图像。
我的应用有相机和照片库的隐私使用说明。
如果用户拒绝访问相机,WKWebView
仍会显示通过相机上传图像的选项,并且会显示相机模式(尽管它只在您通常看到的地方显示黑色相机显示的图像)。如果用户在相机模式中滑动到视频选项,应用程序会崩溃。
相关堆栈跟踪显示:
3 TCC __TCCAccessRequest_block_invoke_2.80 + 222
4 TCC __CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 682
在这种情况下,是否可以从本机应用程序端(假设我无法编辑 HTML 加载)来防止 WKWebView
呈现相机模态?
这似乎是一个错误,因为它只会在选择视频时崩溃。我通过注入 JS 找到了解决方法:
- 将内容类型设置为仅允许照片。 (下面包含示例代码)
- Delete/Hide 输入文件
- 禁用输入文件
func requestCamera() {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { response in
if response {
self.injectJavascript()
} else {
self.webView = WKWebView(frame: .zero)
}
self.setupRequest()
}
}
func injectJavascript() {
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
let js = "var fileInput = document.getElementById('allMedia'); fileInput.setAttribute('accept', 'image/*');"
let userScript = WKUserScript(source: js, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(userScript)
webConfiguration.userContentController = contentController
webView = WKWebView(frame: .zero, configuration: webConfiguration)
}
func setupRequest() {
let url = URL(string: "...")!
let request = URLRequest(url: url)
webView.load(request)
}
流程如下:
- 允许使用相机吗?
- 是的
- 正常加载WKWebView
- 没有
- 注入JS
- 设置 WKWebView
- 加载WKWebView的请求
因为您提到 __CRASHING_DUE_TO_PRIVACY_VIOLATION__
应用可能实际上崩溃了,因为您没有添加 iOS10 使用麦克风的权限说明。如果您选择视频,摄像头视图将触发此额外的麦克风权限弹出窗口。在 iOS10 中,您必须填写呈现给用户的描述,否则应用会像您报告的那样崩溃。在 iOS9 中,它仅显示通用权限弹出窗口。
尝试在 Info.plist
文件中为密钥 NSMicrophoneUsageDescription
添加描述。在 Xcode 中,这称为 Privacy - Microphone Usage Description
此 将为您提供有关各种隐私密钥及其描述的更多详细信息。
在我的应用程序中,我有一个 WKWebView
加载带有文件输入的网站,允许用户通过相机或照片库上传图像。
我的应用有相机和照片库的隐私使用说明。
如果用户拒绝访问相机,WKWebView
仍会显示通过相机上传图像的选项,并且会显示相机模式(尽管它只在您通常看到的地方显示黑色相机显示的图像)。如果用户在相机模式中滑动到视频选项,应用程序会崩溃。
相关堆栈跟踪显示:
3 TCC __TCCAccessRequest_block_invoke_2.80 + 222
4 TCC __CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 682
在这种情况下,是否可以从本机应用程序端(假设我无法编辑 HTML 加载)来防止 WKWebView
呈现相机模态?
这似乎是一个错误,因为它只会在选择视频时崩溃。我通过注入 JS 找到了解决方法:
- 将内容类型设置为仅允许照片。 (下面包含示例代码)
- Delete/Hide 输入文件
- 禁用输入文件
func requestCamera() {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { response in
if response {
self.injectJavascript()
} else {
self.webView = WKWebView(frame: .zero)
}
self.setupRequest()
}
}
func injectJavascript() {
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
let js = "var fileInput = document.getElementById('allMedia'); fileInput.setAttribute('accept', 'image/*');"
let userScript = WKUserScript(source: js, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(userScript)
webConfiguration.userContentController = contentController
webView = WKWebView(frame: .zero, configuration: webConfiguration)
}
func setupRequest() {
let url = URL(string: "...")!
let request = URLRequest(url: url)
webView.load(request)
}
流程如下:
- 允许使用相机吗?
- 是的
- 正常加载WKWebView
- 没有
- 注入JS
- 设置 WKWebView
- 加载WKWebView的请求
- 是的
因为您提到 __CRASHING_DUE_TO_PRIVACY_VIOLATION__
应用可能实际上崩溃了,因为您没有添加 iOS10 使用麦克风的权限说明。如果您选择视频,摄像头视图将触发此额外的麦克风权限弹出窗口。在 iOS10 中,您必须填写呈现给用户的描述,否则应用会像您报告的那样崩溃。在 iOS9 中,它仅显示通用权限弹出窗口。
尝试在 Info.plist
文件中为密钥 NSMicrophoneUsageDescription
添加描述。在 Xcode 中,这称为 Privacy - Microphone Usage Description
此