I know that this question was asked many times but after hours of testing I'm still for something which works.. I try to load an url from a WKWebView in Swift. That's the easy part. In this pointed website the user can start automatically (if permission granted) the camera feed. This works fine from a computer with camera.
With this code below I try to achieve the same goal but natively with an iOS App in Swift. The webview is loaded, I prompted for the camera permission because I filled the Infos.plist but the camera feed never starts.. If someone has an idea ? Thanks!
import UIKit
import WebKit
import AVFoundation
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
if response {
//access granted
DispatchQueue.main.async {
self.webView = WKWebView(frame: .zero)
self.view.addSubview(self.webView)
let layoutGuide = self.view.safeAreaLayoutGuide
self.webView.translatesAutoresizingMaskIntoConstraints = false
self.webView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
self.webView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
self.webView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
self.webView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
if let url = URL(string: "https://webrtc.github.io/samples/src/content/devices/input-output/") {
self.webView.load(URLRequest(url: url))
self.webView.load(URLRequest(url: url, cachePolicy: .reloadRevalidatingCacheData, timeoutInterval: 15))
}
}
}
}
}
}
CodePudding user response:
After hours of testing I finally found a working solution. A WKWebViewConfiguration was needed AND a javascript code called as WKUserScript. Here is where I find the solution: https://developer.apple.com/forums/thread/134216
Swift code :
import UIKit
import WebKit
class ViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
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.mediaTypesRequiringUserActionForPlayback = []
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.userContentController.addUserScript(userScript)
self.webView = WKWebView(frame: .zero, configuration: webConfiguration)
self.view.addSubview(self.webView)
let layoutGuide = self.view.safeAreaLayoutGuide
self.webView.translatesAutoresizingMaskIntoConstraints = false
self.webView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
self.webView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
self.webView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
self.webView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
if let url = URL(string: "https://webrtc.github.io/samples/src/content/getusermedia/gum/") {
self.webView.load(URLRequest(url: url))
}
}
}
UserScript.js :
//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);
}
})();
