如果用户拒绝访问相机,如何防止 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)
}

流程如下:

  1. 允许使用相机吗?
    • 是的
      1. 正常加载WKWebView
    • 没有
      1. 注入JS
      2. 设置 WKWebView
      3. 加载WKWebView的请求

因为您提到 __CRASHING_DUE_TO_PRIVACY_VIOLATION__ 应用可能实际上崩溃了,因为您没有添加 iOS10 使用麦克风的权限说明。如果您选择视频,摄像头视图将触发此额外的麦克风权限弹出窗口。在 iOS10 中,您必须填写呈现给用户的描述,否则应用会像您报告的那样崩溃。在 iOS9 中,它仅显示通用权限弹出窗口。

尝试在 Info.plist 文件中为密钥 NSMicrophoneUsageDescription 添加描述。在 Xcode 中,这称为 Privacy - Microphone Usage Description

将为您提供有关各种隐私密钥及其描述的更多详细信息。