I have a WKWebView which should load the following url:
我有一个WKWebView,应该加载以下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
注意:我使用SDK iOS 8.4
Why does mobile Safari loads this url but WKWebView
does not?
为什么移动Safari加载这个url而WKWebView不加载?
4 个解决方案
#1
20
Add this to your plist
把它添加到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/
以下是9.0 http://ste.vnn5//2015/06/10/configuring-app-transportsecurity-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.
如果你想把它设置得更安全它会给你一种更复杂的方法。
#2
1
not sure if the same error reason, but the problem was the same for me under iOS9
不确定是否有相同的错误原因,但是iOS9下的问题对我来说是一样的
some domains couldn't be loaded
有些域无法加载。
turned out that the problem was in
原来问题出在里面
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
and providing back
并提供回
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
where I should have returned
我应该在哪里回来
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
I was using WRONG code from https://github.com/ShingoFukuyama/WKWebViewTips
我使用了来自https://github.com/ShingoFukuyama/WKWebViewTips的错误代码
#3
1
I had a similar problem with a site that was also protected with a high security TLS 1.2 certificate. To get the WKWebView to accept the server's certificate, I added this code to my web view controller delegate:
我也遇到过类似的问题,这个站点也受到高安全性TLS 1.2证书的保护。为了让WKWebView接受服务器的证书,我在我的web view controller委托中添加了以下代码:
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
if ([[[challenge protectionSpace]authenticationMethod] isEqualToString: @"NSURLAuthenticationMethodServerTrust"]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
CFDataRef exceptions = SecTrustCopyExceptions(serverTrust);
SecTrustSetExceptions(serverTrust, exceptions);
CFRelease(exceptions);
newCredential = [NSURLCredential credentialForTrust:serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, newCredential);
}
}
#4
1
For me, the issue was caused by server trust check from the WKWebView.
对我来说,这个问题是由来自WKWebView的服务器信任检查引起的。
To fix this I had to handle the challenge authentication callback and return a server trust credential.
为了解决这个问题,我必须处理挑战身份验证回调并返回服务器信任凭据。
Swift 4
斯威夫特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)
}
}
#1
20
Add this to your plist
把它添加到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/
以下是9.0 http://ste.vnn5//2015/06/10/configuring-app-transportsecurity-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.
如果你想把它设置得更安全它会给你一种更复杂的方法。
#2
1
not sure if the same error reason, but the problem was the same for me under iOS9
不确定是否有相同的错误原因,但是iOS9下的问题对我来说是一样的
some domains couldn't be loaded
有些域无法加载。
turned out that the problem was in
原来问题出在里面
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
and providing back
并提供回
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
where I should have returned
我应该在哪里回来
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
I was using WRONG code from https://github.com/ShingoFukuyama/WKWebViewTips
我使用了来自https://github.com/ShingoFukuyama/WKWebViewTips的错误代码
#3
1
I had a similar problem with a site that was also protected with a high security TLS 1.2 certificate. To get the WKWebView to accept the server's certificate, I added this code to my web view controller delegate:
我也遇到过类似的问题,这个站点也受到高安全性TLS 1.2证书的保护。为了让WKWebView接受服务器的证书,我在我的web view controller委托中添加了以下代码:
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
if ([[[challenge protectionSpace]authenticationMethod] isEqualToString: @"NSURLAuthenticationMethodServerTrust"]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
CFDataRef exceptions = SecTrustCopyExceptions(serverTrust);
SecTrustSetExceptions(serverTrust, exceptions);
CFRelease(exceptions);
newCredential = [NSURLCredential credentialForTrust:serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, newCredential);
}
}
#4
1
For me, the issue was caused by server trust check from the WKWebView.
对我来说,这个问题是由来自WKWebView的服务器信任检查引起的。
To fix this I had to handle the challenge authentication callback and return a server trust credential.
为了解决这个问题,我必须处理挑战身份验证回调并返回服务器信任凭据。
Swift 4
斯威夫特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)
}
}