Access camera and microphone in WKWebView

I am trying to access camera and microphone in WKWebView. I tried many ways but it didn't work. I tried injecting js in web view and tried to call navigator.getusermedia but didn't work. I have added required keys for permission in info.plist. Granted access befor opening webview but it didn't work. It will be very helpful if I get any help regarding this. Thanks in advance.

Replies

If this information is valid, that seems impossible at the time:

https://stackoverflow.com/questions/56646575/wkwebview-does-not-allow-camera-access-in-application


Also read this: https://forums.developer.apple.com/thread/88052

WebRTC is only supported in Safari. No WKWebView, not even SFSafariViewController.

This is possible, but you have to use a workaround. First of all you indeed need to set your permissions in the info.plist.

<key>NSMicrophoneUsageDescription</key>
<string>If you want to use the microphone, you have to give permission.</string>
<key>NSCameraUsageDescription</key>
<string>If you want to use the camera, you have to give permission.</string>

After this you have to inject Javascript at the start of the document of the WebView. You could to this by adding a .js document to your project. the code in here would look like this:

//injects this into webpage to listen to the camera request

(function() {

  if (!window.navigator) window.navigator = {};

    //if getuserMedia is called -> If the user requests native camera

        window.navigator.getUserMedia = function() {

            webkit.messageHandlers.callbackHandler.postMessage(arguments);

  }

})();

In your viewController file, injecting this into the WebView would look like this:

 override func loadView() {

        let userScriptURL = Bundle.main.url(forResource: "UserScript", withExtension: "js")!

        let userScriptCode = try! String(contentsOf: userScriptURL)

        let userScript = WKUserScript(source: userScriptCode, injectionTime: .atDocumentStart, forMainFrameOnly: false)

        let webConfiguration = WKWebViewConfiguration()

        webConfiguration.userContentController.addUserScript(userScript)
}

This works for both camera and microphone use like you are trying to do.

  • It is not clear how the system would find the .js file, as there seems to be no place in that code to specify the name chosen. I saved it as UserScript.js in the same folder of ViewController.swift, but regardless of the name, I keep getting "Fatal error: Unexpectedly found nil while unwrapping an Optional value”

  • add another key: NSSpeechRecognitionUsageDescription solve the problem.

  • For me, I need to add the url to localhost or file:/// when loading the html (readmore: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#privacy_and_security)

    So, the microphone access prompt doesn't show if I load webview.loadHTMLString("<html>...some html use audio...</html>", baseURL: nil)

    It work if with: webview.loadHTMLString("<html>...some html use audio...</html>", baseURL: URL(string: "file:///index.htm")!)

Add a Comment

Ok, I just put this code and now I am not getting more errors (I saved the .js as camera.js in the same folder of ViewController.swift)

	if let userScriptURL = Bundle.main.url(forResource: "camera", withExtension: "js") 
	{
    let userScriptCode = try! String(contentsOf: userScriptURL)
    let userScript = WKUserScript(source: userScriptCode, injectionTime: .atDocumentStart, forMainFrameOnly: false)
    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.userContentController.addUserScript(userScript)
	}

is it accepted by Apple , i need similar functionality to be added in my project. Anyone gone through Apple review with this approach?