【问题标题】:How do I prevent a WKWebView from presenting the Camera modal if a user has denied access to the camera?如果用户拒绝访问相机,如何防止 WKWebView 显示相机模式?
【发布时间】:2018-01-12 20:13:46
【问题描述】:

在我的应用程序中,我有一个 WKWebView 加载带有文件输入的网站,允许用户通过相机或照片库上传图像。

我的应用同时包含相机和照片库的隐私使用说明。

如果用户拒绝访问相机,WKWebView 仍将显示通过相机上传图像的选项,并显示相机模式(尽管它仅在您通常会看到的图像显示黑色相机正在显示)。如果用户在“相机”模式中滑动到“视频”选项,应用就会崩溃。

相关堆栈跟踪显示:

3   TCC __TCCAccessRequest_block_invoke_2.80 + 222
4   TCC __CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 682

在这种情况下,是否可以从本机应用程序端(假设我无法编辑加载的 HTML)阻止 WKWebView 呈现相机模式?

【问题讨论】:

    标签: ios iphone camera ios10 wkwebview


    【解决方案1】:

    因为你提到了__CRASHING_DUE_TO_PRIVACY_VIOLATION__,所以应用程序可能真的崩溃了,因为你没有添加iOS10使用麦克风的权限描述。如果您选择视频,相机视图将触发此额外的麦克风权限弹出窗口。在 iOS10 中,您必须填写呈现给用户的描述,否则应用程序将如您所报告的那样崩溃。在 iOS9 中,它只是呈现通用权限弹出窗口。

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

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

    【讨论】:

      【解决方案2】:

      这似乎是一个错误,因为它仅在选择视频时崩溃。我通过注入 JS 找到了解决方法:

      • 将内容类型设置为仅允许照片。 (示例代码如下)
      • 删除/隐藏输入文件
      • 禁用输入文件
      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 的请求

      【讨论】:

      • 这是一个有趣的解决方法。我投了赞成票,因为它可以帮助解决崩溃,但我会等待接受,以防其他人有可能解决核心问题的答案。感谢您的回复!
      • 太棒了。我发送了一个错误报告以防万一,如果支持团队有任何答复,我会更新帖子
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 2021-12-17
      • 2020-10-09
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多