I have a WKWebView which should load the following url:
https://buchung.salonmeister.de/place/#offer-details-page?id=907599&venueId=301655
Her is the code I use:
import UIKit import WebKit class MMWKBrowserController: UIViewController { private let closeButtonSelector: Selector = "closeButtonTapped:" private var urlString: String private let request: NSMutableURLRequest private var webView: WKWebView! private var twoLineTitleView: UIView! private var titleLabel: UILabel? private var subTitleLabel: UILabel? private var indicator: UIActivityIndicatorView! init(urlString: String) { self.urlString = urlString println("*** Using MMWKBrowserController ***") var url: NSURL? = NSURL(string: urlString) if url == nil { var escapedString: String = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! self.urlString = escapedString url = NSURL(string: escapedString) } println("url: \(url)") request = NSMutableURLRequest(URL: url!) request.setValue("Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H141 Safari/600.1.4", forHTTPHeaderField: "UserAgent") super.init(nibName: nil, bundle: nil) } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } deinit { self.webView.removeObserver(self, forKeyPath: "loading") self.webView.removeObserver(self, forKeyPath: "title") self.webView.removeObserver(self, forKeyPath: "URL") self.webView.removeObserver(self, forKeyPath: "estimatedProgress") self.webView.stopLoading() } override func viewDidLoad() { super.viewDidLoad() createNavigationView() self.navigationController?.navigationBar.tintColor = MGColor.actionColor let config = WKWebViewConfiguration() self.webView = WKWebView(frame: self.view.bounds, configuration: config) self.view.addSubview(self.webView) indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) //indicator.backgroundColor = UIColor(white: 0.1, alpha: 0.5) webView.addSubview(indicator) self.webView.snp_makeConstraints { (make) -> Void in make.edges.equalTo(self.view) } indicator.snp_makeConstraints { (make) -> Void in make.center.equalTo(self.webView) } webView.addObserver(self, forKeyPath: "loading", options: NSKeyValueObservingOptions.New, context: nil) webView.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.New, context: nil) webView.addObserver(self, forKeyPath: "URL", options: NSKeyValueObservingOptions.New, context: nil) webView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.New, context: nil) } override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) self.webView.stopLoading() } private func createNavigationView() { let closeItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: closeButtonSelector) self.navigationItem.leftBarButtonItem = closeItem // create center view let titleViewWidth = self.view.frame.size.width - 100 twoLineTitleView = UIView(frame: CGRectMake(0, 0, titleViewWidth, 44)) titleLabel = UILabel(frame: CGRectMake(0, 6, titleViewWidth, 16)) titleLabel?.backgroundColor = UIColor.clearColor() titleLabel?.font = UIFont.boldSystemFontOfSize(16) titleLabel?.textAlignment = NSTextAlignment.Center subTitleLabel = UILabel(frame: CGRectMake(0, 21, titleViewWidth, 20)) subTitleLabel?.backgroundColor = UIColor.clearColor() subTitleLabel?.font = UIFont.systemFontOfSize(10) subTitleLabel?.textAlignment = NSTextAlignment.Center twoLineTitleView.addSubview(titleLabel!) twoLineTitleView.addSubview(subTitleLabel!) self.navigationItem.titleView = twoLineTitleView } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.webView.loadRequest(self.request) } func closeButtonTapped(sender: UIBarButtonItem) { self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil) } override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { if let wk = object as? WKWebView { switch keyPath { case "loading": if let val: AnyObject = change[NSKeyValueChangeNewKey] { if let val = val as? Bool { if val { self.indicator.startAnimating() } else { self.indicator.stopAnimating() } } } case "title": self.titleLabel?.text = self.webView.title case "URL": self.subTitleLabel?.text = self.webView.URL?.URLString case "estimatedProgress": println("progress: \(Int32(self.webView.estimatedProgress*100))") default: break } } } }
Note: I use SDK iOS 8.4
Why does mobile Safari loads this url but WKWebView
does not?
Since then, we've recommended that you adopt WKWebView instead of UIWebView and WebView — both of which were formally deprecated. New apps containing these frameworks are no longer accepted by the App Store.
Load Local HTML File to a WKWebViewlet myUrl = myProjectBundle. url(forResource: "my-html-file", withExtension: "html")!
The WKWebView is a modern API applying all the modern web security mechanisms, it's still maintained by Apple and gets updates. The good thing about WKWebView is that it does out-of-process rendering, so if the attackers find a memory corruption vulnerability in it, your application's process is still isolated.
Add this to your plist
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
Here's the explanation for this change in 9.0 http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/
Also if you want to set it up more secure it gives you a more complex way to do that.
For me, the issue was caused by server trust check from the WKWebView.
To fix this I had to handle the challenge authentication callback and return a server trust credential.
Swift 4
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!) completionHandler(.useCredential, cred) } else { completionHandler(.performDefaultHandling, nil) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With