I have a app that can download files from a webview. It was working fine in ios 12 but isnt working. I'm getting the error
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
and
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
This is my view.controller code:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
print(request.url as Any)
if request.url!.absoluteString.range(of: "/download/") != nil {
let extention = request.url!.absoluteString.slice(from: "&fileextension=", to: "&")?.lowercased()
var name = request.url!.absoluteString.slice(from: "&name=", to: "&")?.lowercased()
name = name?.replacingOccurrences(of: "+", with: " ")
DownlondFromUrl(request.url! as URL,name!, extention!)
return false
}
return true
}
func DownlondFromUrl(_ url: URL,_ name:String,_ extensionfile:String){
// Create destination URL
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let destinationUrl = documentsUrl!.appendingPathComponent(name + ".\(extensionfile)")
//Create URL to the source file you want to download
let fileURL = url
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
let dataFromURL = NSData(contentsOf: tempLocalUrl)
dataFromURL?.write(to: destinationUrl, atomically: true)
let alert = UIAlertController.init(title: "Download", message: "File download Successful. Do you want open file ", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Open", style: .default , handler:{ (UIAlertAction)in
let fileBrowser = FileBrowser()
self.present(fileBrowser, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Share", style: .default , handler:{ (UIAlertAction)in
let activityViewController = UIActivityViewController(activityItems: [destinationUrl], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler:{ (UIAlertAction)in
}))
self.present(alert, animated: true, completion: {
print("completion block")
})
} else {
print("Error took place while downloading a file. Error description: %@", error?.localizedDescription as Any);
}
}
task.resume()
}
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.isNavigationBarHidden = true;
}
}
I have found this post (Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread) but I'm very much a beginner and not sure how to implement this.