在wkwebview中启用摄像头和麦克风访问

我有一个移动优化的网络应用程序,利用getUserMedia访问网络摄像头和麦克风资源。

我将此应用程序包装在WKWebView因为我想提供本机应用程序体验。 我知道iOS不允许通过浏览器访问摄像头 – 但是有没有办法获得使用本机代码(与包装器一起)的网络摄像头/麦克风的权限并将其提供给Web应用程序 – 也许通过某种方式将getUserMedia指向本地流源?

是的,看一下cordova-plugin-iosrtc和cordova-plugin-wkwebview-engine 。 插件背后的想法如下:

1.创建一个JavaScript文件(WebRTC.js),定义各种WebRTC类和函数,并将调用传递给WKWebView,例如:

 (function() { if (!window.navigator) window.navigator = {}; window.navigator.getUserMedia = function() { webkit.messageHandlers.callbackHandler.postMessage(arguments); } })(); 

2.在WKWebView中,在文档start处注入脚本:

 let contentController = WKUserContentController(); contentController.add(self, name: "callbackHandler") 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)) let config = WKWebViewConfiguration() config.userContentController = contentController webView = WKWebView(frame: CGRect.zero, configuration: config) 

3.侦听从JavaScript发送的消息:

 class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler { var webView: WKWebView! func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "callbackHandler" { print(message.body) // make native calls to the WebRTC framework here } } } 

4.如果需要在JavaScript-land中执行成功或失败回调,请直接在WKWebView中评估函数调用:

 webView.evaluateJavaScript("callback({id: \(id), status: 'success', args: ...})", completionHandler: nil) 

调用postMessage 之前 ,需要将这些回调存储在JavaScript中的哈希值中,然后必须将哈希键发送到WKWebView。 这是插件中的commandId

 int exec_id = 0; function exec(success, failure, ...) { // store the callbacks for later if (typeof success == 'function' || typeof failure == 'function') { exec_id++; exec_callbacks[exec_id] = { success: success, failure: failure }; var commandId = exec_id; } webkit.messageHandlers.callbackHandler.postMessage({id: commandId, args: ...}) } // the native code calls this directly with the same commandId, so the callbacks can be performed and released function callback(opts) { if (opts.status == "success") { if (typeof exec_callbacks[opts.id].success == 'function') exec_callbacks[opts.id].success(opts.args); } else { if (typeof exec_callbacks[opts.id].failure == 'function') exec_callbacks[opts.id].failure(opts.args); } // some WebRTC functions invoke the callbacks multiple times // the native Cordova plugin uses setKeepCallbackAs(true) if (!opts.keepalive) delete exec_callbacks[opts.id]; } 

5.当然,将NSCameraUsageDescriptionNSMicrophoneUsageDescription权限添加到项目的Info.plist中。

请记住,这是一项非常重要的任务,但这是使用异步回调桥接JavaScript,WKWebView和本机框架代码的总体思路。