通过Swift访问HTTPS URL时出现错误-9807

时间:2015-02-25 23:18:00

标签: swift https

我正在尝试使用Swift的NSURLRequestNSURLConnection与Riot Games(英雄联盟)API进行通信。我似乎不仅遇到Riot URL问题,而且还有所有HTTPS URL问题。

我在Swift Playground中有以下代码:

func doGET(url: String) {
  if let urlhandle = NSURL(string: url) {
    var request = NSURLRequest(URL: urlhandle)

    var response: NSURLResponse?
    var error: NSErrorPointer = nil
    var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: error)
    println("\n\(url)\n")
    println("\(response)\n\n")
  } else {
    println("Bad URL: \(url)")
  }
}

doGET("http://google.com")

doGET("https://na.api.pvp.net/api/lol/na/v1.2/champion/1?api_key=\(apikey)")

doGET("https://google.com")

我收到以下错误/输出:

http://google.com

Optional(<NSHTTPURLResponse: 0x7fcff2443d60> { URL: http://www.google.com/ } { status code: 200, headers {
"Accept-Ranges" = none;
"Alternate-Protocol" = "80:quic,p=0.08";
"Cache-Control" = "private, max-age=0";
"Content-Type" = "text/html; charset=ISO-8859-1";
Date = "Wed, 25 Feb 2015 23:13:45 GMT";
Expires = "-1";
Server = gws;
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
"X-Frame-Options" = SAMEORIGIN;
"X-XSS-Protection" = "1; mode=block";
} })


2015-02-25 16:13:45.357 URL Requests[36397:3779864] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9807)

https://na.api.pvp.net/api/lol/na/v1.2/champion/1?api_key=<redacted>

nil


2015-02-25 16:13:45.402 URL Requests[36397:3779864] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9807)

https://google.com

nil

如您所见,请求在HTTP URL上成功,但在安全HTTPS URL上失败。如何允许使用HTTPS?

3 个答案:

答案 0 :(得分:1)

它可能无法解决https问题,但在将链接转换为NSURL之前应始终使用stringByAddingPercentEscapesUsingEncoding

"http://google.com".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!

"https://na.api.pvp.net/api/lol/na/v1.2/champion/1?api_key=any key".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! // "https://na.api.pvp.net/api/lol/na/v1.2/champion/1?api_key=any%20key"


func doGET(link: String) {
  if let url = NSURL(string: link.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!) {
    var response: NSURLResponse?
    var error: NSErrorPointer = nil
    let data = NSURLConnection.sendSynchronousRequest(NSURLRequest(URL: url), returningResponse: &response, error: error)
    println("\n\(url)\n")
    println("\(response)\n\n")
  } else {
    println("Bad URL")
  }
}

答案 1 :(得分:1)

您的代码应该在正常情况下运行。环境。但是,当您提到您在大学时,接受服务器证书可能存在问题。所以我建议你添加NSURLConnectionDelegate并添加以下两种方法。我从戈登的回答here得到了这个想法。

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool {
    return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
}

func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
    challenge.sender.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust), forAuthenticationChallenge: challenge)
}

提到的问题中的案例是另一个案例,但我认为您在服务器证书方面遇到了同样的问题。

答案 2 :(得分:0)

谢谢@Christian和@Leonardo。它似乎是我自己的机器上的防火墙/证书问题。现有代码从命令提示符(swift /path/to/file)完美运行,它只在Xcode中失败。我想最终让它在Xcode中工作,但是当我来到它时,我会越过那座桥。