Search code examples
videoswift4embedinlinewkwebview

WKWebView video does not play inline


So according to Apple's documentation : https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1614793-allowsinlinemediaplayback

I should be able to play videos inline easily using Swift 4, but no matter what I do it always opens the video in the native video player.

This is my code :

convenience init(style: UITableViewCell.CellStyle, reuseIdentifier: String?, url: String = "", title: String) {
        self.init(style: style, reuseIdentifier: reuseIdentifier)
        self.videoTitleLabel.text = title
        self.urlToVideo = url
        setUpUI()
        setUpLayout()
        webView.backgroundColor = .smalt
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.configuration.allowsInlineMediaPlayback = true
        webView.configuration.preferences.javaScriptEnabled = true
        webView.load(URLRequest(url: URL(string: self.urlToVideo + "?playsinline")! ))
    }

What Am I doing wrong?


Solution

  • From looking at some other issues people have reported and the detail in the Apple documentation, I think the issue is that WKWebViewConfiguration has to be set before the WKWebView is created.

    From the apple documentation:

    Using the WKWebViewConfiguration class, you can determine how soon a webpage is rendered, how media playback is handled, the granularity of items that the user can select, and many other options.

    WKWebViewConfiguration is only used when a web view is first initialized. You cannot use this class to change the web view's configuration after it has been created.

    This aligns with the example that apple provide for using a WKWebView (https://developer.apple.com/documentation/webkit/wkwebview) where you cans see the WKWebViewConfiguration is passed to the WKWebView set up. I've added in the playsinline as an example for your case.

    import UIKit
    import WebKit
    class ViewController: UIViewController, WKUIDelegate {
        
        var webView: WKWebView!
        
        override func loadView() {
            let webConfiguration = WKWebViewConfiguration()
            webConfiguration.allowsInlineMediaPlayback = true //** Added as an example for your case
            webView = WKWebView(frame: .zero, configuration: webConfiguration)
            webView.uiDelegate = self
            view = webView
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let myURL = URL(string:"https://www.apple.com")
            let myRequest = URLRequest(url: myURL!)
            webView.load(myRequest)
        }}
    

    It would seem to make more sense if the property could not be set subsequently to avoid this confusion, but it appears from the documentation this is how it works.