webentwicklung-frage-antwort-db.com.de

WKWebView lädt keine https-URL?

Ich habe eine WKWebView, die folgende URL laden sollte: 

https://buchung.salonmeister.de/place/#offer-details-page?id=907599&venueId=301655

Ihr ist der Code, den ich verwende: 

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
      }
    }
  }


}

Hinweis: Ich verwende SDK iOS 8.4

Warum lädt mobile Safari diese URL, WKWebView jedoch nicht?

21
confile

Fügen Sie dies Ihrer Liste hinzu

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Hier ist die Erklärung für diese Änderung in 9.0 http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Auch wenn Sie es sicherer einrichten möchten, gibt es einen komplexeren Weg, dies zu tun.

23
Randall Meyer

Für mich wurde das Problem durch die Überprüfung der Server-Vertrauenswürdigkeit in der WKWebView verursacht.

Um dieses Problem zu beheben, musste ich den Challenge-Authentication-Callback behandeln und einen Berechtigungsnachweis für den Server zurückgeben.

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)
    }
}
7
Matthew Cawley

Ich hatte ein ähnliches Problem mit einer Site, die ebenfalls mit einem TLS 1.2-Zertifikat mit hoher Sicherheit geschützt war. Damit WKWebView das Serverzertifikat akzeptiert, fügte ich diesen Code zu meinem Controller für die Webansicht hinzu:

-(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);
    }
}
2
saswanb

ich bin nicht sicher, ob der gleiche Fehlergrund vorliegt, aber das Problem war für mich unter iOS9 das gleiche

einige Domains konnten nicht geladen werden 

stellte sich heraus, dass das Problem in war 

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {

und wieder zur Verfügung stellen

completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);

wo ich hätte zurückkehren sollen 

completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);

Ich habe falschen Code von https://github.com/ShingoFukuyama/WKWebViewTips verwendet.

1
Peter Lapisu
// Add plist file 
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
    <key>google.com</key>
    <dict>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
        <key>NSIncludesSubdomains</key>
        <true/>
    </dict>
</dict>

wenn WKWebView nicht unterstützt wird, deklarieren Sie die .m-Datei unter dem folgenden Code:

code hier eingeben

@interface WebScannerViewController()
{

 WKWebView *webView;

}

@Ende

@implementation WebScannerViewController - (void) viewDidLoad {

[super viewDidLoad];
webView.hidden=YES;

webView.UIDelegate = self;
webView.navigationDelegate = self;
self.loadingSign.hidden = NO;


    webView.frame=CGRectMake(0, 94, Width, Height-128);

}

0
Ramani Hitesh

Wenn Sie sich in einer Sandkasten-MacOS-App befinden, müssen Sie die Outgoing Connections (Client) -Funktion einstellen. Sie müssen sich nicht mit Allow Abitrary Loads ändern, das für vertrauenswürdige https nicht zum Tragen kommen sollte Anfragen. Xcode Capabilities Screenshot showing the Outgoing Connections (Client) checkbox checked

Für iOS ist das Erlauben von Clientverbindungen jedoch die Standardeinstellung. Daher müssen Sie möglicherweise WKNavigationDelegate-Methoden implementieren, um die Sicherheit zu gewährleisten. Stellen Sie jedoch sicher, dass Sie nicht nur nicht vertrauenswürdigen Zertifikaten vertrauen. Dieses Swift Talk-Video von objc.io ist die beste Ressource, die ich kenne, und ist auf jeden Fall 20 Minuten wert, wenn Sie in diesem Bereich arbeiten: https://talk.objc.io/episodes/S01E57-certificate-pinning

0
nteiss