Prevent for reprompting webRTC webView Permissions - ios15

Hello i am trying to make use of the new WKWebView additions so my App doesnt need to reprompt for webRTC webView camera permission every time i ran my app. →
https://developer.apple.com/documentation/webkit/wkuidelegate/3763087-webview#discussion

I created a custom view controller like described here (Capacitor - build cross platform apps with the web) but i am failing to implement the new WKWebView additions to my custom view controller.

The following give me an error of Value of tuple type '()' has no member 'deny'

import UIKit
import Capacitor

@available(iOS 15.0, *)
class ViewController: CAPBridgeViewController, WKUIDelegate {


    override func viewDidLoad() {
        super.viewDidLoad()
        webView?.uiDelegate = self
        
        // Do any additional setup after loading the view.
    }
    
    
    @available(iOS 15.0, *)
    func webView(_ webView: WKWebView,
    requestMediaCapturePermissionFor origin: WKSecurityOrigin,
         initiatedByFrame frame: WKFrameInfo,
                     type: WKMediaCaptureType,
                 decisionHandler: @escaping (WKPermissionDecision) -> Void) {
               return type == .camera ? .prompt : .deny
}

}

i also tried it like this

import UIKit
import Capacitor

@available(iOS 15.0.0, *)
class ViewController: CAPBridgeViewController, WKUIDelegate {


    override func viewDidLoad() {
        super.viewDidLoad()
        webView?.uiDelegate = self
        
        // Do any additional setup after loading the view.
    }
    
    @available(iOS 15.0.0, *)  
    func webView(_ webView: WKWebView,
    requestMediaCapturePermissionFor origin: WKSecurityOrigin,
         initiatedByFrame frame: WKFrameInfo,
                     type: WKMediaCaptureType,
          decisionHandler: @escaping (WKPermissionDecision) -> Void) {
        return type == .camera ? .prompt : .deny
    }

}    

but no luck so far.

I am now always getting a AbortError on camera access - no permission prompt at all.
What am i doing wrong?

Found an easy solution but should be integrated directly in @capacitor/ios and had no time to work on a pull request

I had to add these lines in the file node_modules/@capacitor/ios/Capacitor/Capacitor/WebViewDelegationHandler.swift after the function public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!):

    @available(iOS 15, *)
    func webView(
        _ webView: WKWebView,
        requestMediaCapturePermissionFor origin: WKSecurityOrigin,
        initiatedByFrame frame: WKFrameInfo,
        type: WKMediaCaptureType,
        decisionHandler: @escaping (WKPermissionDecision) -> Void
    ) {
        decisionHandler(.grant)
    }

This delegates the permission request to your app and also remembers the user’s decision.

2 Likes

Thanks for this @7freaks_otte
But how do I actually implement this? Your sample is in the @capacitor/ios plugin. You adding that manually all the time?

@capacitor/ios 3.4.0 and newer already have similar code, so if you are in an older version update.
If you are in 3.4.0 or newer, then make sure you are using Xcode 13, that code won’t work on Xcode 12.

1 Like

Thanks man. This worked but if I turn off permission from settings of the app. It doesnt ask again, Do I need to manually ask for microphone permission?

iOS only ask for permissions once, if you change turn the permission off on settings app it won’t work, asking for permissions yourself will just get a deny result without prompting the user, the only thing you can do is to detect the permission status and display a message to the user.

1 Like