I'm making an app that has voice chat via WKWebVew in Swift.
The voice you speak should be heard by other users even when the screen is off.
However, if the screen of the device is turned off while using WKWebView, the broadcast ends and WKWebView is refreshed.
import UIKit
import WebKit
class WebViewController: UIViewController {
@IBOutlet var webView: WKWebView!
override func loadView() {
super.loadView()
let webConfiguration = WKWebViewConfiguration()
webConfiguration.ignoresViewportScaleLimits = true
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.allowsAirPlayForMediaPlayback = true
webConfiguration.allowsPictureInPictureMediaPlayback = true
webConfiguration.mediaTypesRequiringUserActionForPlayback = []
webView = WKWebView(frame: self.view.bounds, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
self.view = self.webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.scrollView.bounces = false
let localFilePath = Bundle.main.url(forResource: "www/test", withExtension: "html")
let request = URLRequest(url: localFilePath!)
webView.load(request)
}
}
The following is handling of alert window and avoiding duplicate reload.
extension WebViewController: WKUIDelegate {
//alert
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default,
handler: { (action) in completionHandler() }))
self.present(alertController, animated: true, completion: nil)
}
//confirm
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in completionHandler(true) }))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in completionHandler(false) }))
self.present(alertController, animated: true, completion: nil)
}
//prompt
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String,
defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alertController = UIAlertController(title: "", message: prompt, preferredStyle: .alert)
alertController.addTextField { (textField) in textField.text = defaultText }
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(nil) }))
self.present(alertController, animated: true, completion: nil)
}
// href="_blank"
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
}
extension WebViewController: WKNavigationDelegate {
// prevent reload
public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
webView.reload()
}
}
It is said that WKWebView stops working when the screen goes off in WKWebView due to view hierarchy.
Even if the screen is turned off through Background Mode, is there a way to fix the view?
In Android, you can Intent WebView through Foreground Service, so the WebView works even when the screen is turned off. I wonder if there is no such way in Swift.
No, there is no such way. When the screen is off. i.e the device is locked you will not be able to use functionality of the WKWebView. Even if you app is in Background mode. You will have to find another solution to leave the microphone on and send it to the remote server. Read about the different background modes that iOS supports. You can ask to leave the microphone on for some reasons. Record voice in background(when i tapped home button) using AVAudioRecorder