WKWebView does not allow camera access in application
Asked Answered
C

6

8

We are trying to make a conference call with multiple users, So by using Kurento server we have achieved this and it's working on safari browser. But when it comes to implementation in WebView / WKWebView. It does not even ask for permissions.

@IBOutlet weak var webViewContainer: UIView!
var webView: WKWebView!

override open func loadView() {
    super.loadView()

    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.ignoresViewportScaleLimits = true
    webConfiguration.suppressesIncrementalRendering = true
    webConfiguration.allowsInlineMediaPlayback = true
    webConfiguration.allowsAirPlayForMediaPlayback = false
    webConfiguration.allowsPictureInPictureMediaPlayback = true
    webConfiguration.mediaTypesRequiringUserActionForPlayback = .all
    webConfiguration.requiresUserActionForMediaPlayback = true
    webView = WKWebView(frame: webViewContainer.frame, configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    webView.sizeToFit()
    webView.backgroundColor = .black
    webView.isOpaque = false
    self.webViewContainer.addSubview(webView)

}

func webContentController()-> WKUserContentController {
    let contentController = WKUserContentController()
    let script = try! String(contentsOf: Bundle.main.url(forResource: "WebRTC", withExtension: "js")!, encoding: String.Encoding.utf8)
    contentController.addUserScript(WKUserScript(source: script, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true))
    contentController.add(self, name: "callbackHandler")
    return contentController
}

override func viewDidLoad() {
    super.viewDidLoad()
    guard let url = URL (string: urlStr) else { return
    }
    let myRequest = URLRequest(url: url)
    self.webView.load(myRequest)
}

I even have tried this link in safariViewController, but it does not ask for camera permissions.

Cowell answered 18/6, 2019 at 10:2 Comment(1)
I don't know why but [] and .all give diferent results: webConfiguration.mediaTypesRequiringUserActionForPlayback = [] webConfiguration.mediaTypesRequiringUserActionForPlayback = .allRogers
T
4

This

Did you follow the steps from the documentation? The most important part is the NSCameraUsageDescription / NSMicrophoneUsageDescription must be present inside the info.plist file

Timpani answered 18/6, 2019 at 10:41 Comment(4)
Yes, it's present in plistCowell
Are you using the latest iOS? The safariViewController camera problem should have been fixed in 11.3? Release notes: > Safari Resolved Issues > - WebApps saved to the home screen and webpages > in SafariViewController can now use the camera to capture images. > (35542231)Timpani
no, if you want to support lower version you have to use native code + a javascript bridgeTimpani
@vk.edwaard.li can you share any example, or refer to the project that has done this?Cowell
C
1

This is a known limitation of WKWebView for now, see the chrome issue for details

Croesus answered 18/6, 2019 at 12:6 Comment(0)
S
1

It's a Bug, the WkWebView has limited support to the WebRTC It's now working since IOS 14.3 version

But to get this working, you need to set properties requiresUserActionForMediaPlayback = false allowsInlineMediaPlayback = true

Skiffle answered 2/12, 2021 at 17:30 Comment(0)
F
0

Doing the following worked for me:

  1. Add NSCameraUsageDescription, NSMicrophoneUsageDescription in info.plist

  2. Make sure to add the following configurations before loading the url:

    let config = WKWebViewConfiguration()
    config.userContentController = contentController
    
    config.allowsInlineMediaPlayback = true
    if #available(iOS 14.0, *) {
        config.mediaTypesRequiringUserActionForPlayback = []
    } else {
        config.requiresUserActionForMediaPlayback = false
    }
    self.webview = WKWebView(frame: .zero, configuration: config)
    self.webview.load(URLRequest(url: url!))
    

If it doesn't work for you, try to give the permissions before webview is initialised. For me this worked even after giving the permissions inside webview.

Fragrant answered 26/7 at 11:41 Comment(0)
C
-1

I had to do this:

import AVFoundation

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        AVCaptureDevice.requestAccess(for: .audio) { haveMicAccess in
            print("Access to Microphone: \(haveMicAccess)")
        }

        return true
    }

    ...

}

It still asks me each time I use the camera with getUserMedia() in the page script too. But without the above code getUserMedia is null. The above code triggers the request for access to the microphone so long as you provide a message in the info.plist for NSMicrophoneUsageDescription

Coverlet answered 11/2, 2022 at 12:10 Comment(0)
H
-1

In my case, I need camera open for account identifier. Setting config for webview below work for me:

webConfiguration.allowsInlineMediaPlayback = true webConfiguration.mediaTypesRequiringUserActionForPlayback = []

Huynh answered 11/10, 2022 at 8:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.