Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "EXC_BAD_ACCESS" when creating WKPreferences variable in Swift 4

In my code, I have a part that creates a new WKWebView with a specific WKWebViewConfiguration, which in turn has a WKPreferences reference. All of this then gets added to the view of the application.

The problem is that up until this point, my code has been running perfectly, with no problems.

Now, for some bizarre reason, when I launch the application, I get

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeec686fc0)

on the line when I create a variable for the WKPreferences.

I am working with Xcode 10.1, Swift 4, and I have Alamofire and NetworkReachability pods installed. I have tried just creating the WKWebView without the WKPreferences, but the error just moves on to the WKWebViewConfiguration instead.

func createWebView() {
    let preferences = WKPreferences()   //<-- EXC_BAD_ACCESS
    preferences.javaScriptEnabled = true
    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.preferences = preferences
    webConfiguration.allowsInlineMediaPlayback = true
    webViewVar = WKWebView(frame: self.view.bounds, configuration: webConfiguration)
    webViewVar.uiDelegate = self
    self.view = webViewVar
}

override func loadView() {
    createWebView()
}

The expected behavior is that the app would launch and show a web page, that doesn't change, specified elsewhere in the code. The actual result is that the app crashes with the EXC_BAD_ACCESS error upon startup.

like image 428
MattChris Avatar asked Dec 27 '18 02:12

MattChris


1 Answers

I'd have to say you've found a bug. For some reason, the runtime isn't letting you create a WKPreferences object this early in the life of the app.

The workaround is that you'll have to postpone creation of the web view until the app is up and running. To do so, delete loadView and implement viewDidLoad instead, and do all the work there, making the web view a subview of the main view rather than trying to make it be the main view.

var webViewVar : WKWebView!
func createWebView() {
    let preferences = WKPreferences()
    preferences.javaScriptEnabled = true
    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.preferences = preferences
    webConfiguration.allowsInlineMediaPlayback = true
    webViewVar = WKWebView(frame: self.view.bounds, configuration: webConfiguration)
    webViewVar.uiDelegate = self
    self.view.addSubview(webViewVar)
    webViewVar.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
override func viewDidLoad() {
    super.viewDidLoad()
    createWebView()
}

It's annoying, and you should file a bug report with Apple, but at least this will keep you going for now.

like image 118
matt Avatar answered Oct 17 '22 05:10

matt