Я пытаюсь использовать NSURLRequest и NSURLConnection Swift для связи с API Riot Games (League of Legends). Кажется, у меня проблемы не только с URL-адресами Riot, но и со всеми URL-адресами HTTPS.

У меня есть следующий код на 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

Как видите, запрос выполняется по URL-адресам HTTP, но не выполняется по защищенным URL-адресам HTTPS. Как я могу разрешить использование HTTPS?

0
Scott Odle 26 Фев 2015 в 02:18

3 ответа

Лучший ответ

Спасибо @Christian и @Leonardo. Похоже, проблема с брандмауэром / сертификатом на моем компьютере. Существующий код отлично работает из командной строки (swift /path/to/file), он не работает только в Xcode. Я бы хотел, чтобы в конце концов он работал в Xcode, но я перейду через этот мост, когда подойду к нему.

0
Scott Odle 26 Фев 2015 в 04:19

Вероятно, это не решит проблему https, но вы всегда должны использовать stringByAddingPercentEscapesUsingEncoding перед преобразованием ваших ссылок в NSURL

"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
Leo Dabus 26 Фев 2015 в 04:30

Ваш код должен работать в «нормальной» среде. Но как вы упомянули, что учитесь в университете, может возникнуть проблема с принятием сертификатов сервера. Поэтому я бы порекомендовал вам добавить NSURLConnectionDelegate и добавить следующие два метода. У меня есть идея из ответа Гордона здесь.

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

Случай в упомянутом вопросе - другой, но я думаю, что у вас такая же проблема с сертификатами сервера.

1
Community 23 Май 2017 в 11:44