Я пытаюсь использовать 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?
3 ответа
Спасибо @Christian и @Leonardo. Похоже, проблема с брандмауэром / сертификатом на моем компьютере. Существующий код отлично работает из командной строки (swift /path/to/file
), он не работает только в Xcode. Я бы хотел, чтобы в конце концов он работал в Xcode, но я перейду через этот мост, когда подойду к нему.
Вероятно, это не решит проблему 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")
}
}
Ваш код должен работать в «нормальной» среде. Но как вы упомянули, что учитесь в университете, может возникнуть проблема с принятием сертификатов сервера. Поэтому я бы порекомендовал вам добавить 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)
}
Случай в упомянутом вопросе - другой, но я думаю, что у вас такая же проблема с сертификатами сервера.
Похожие вопросы
Связанные вопросы
Новые вопросы
swift
Swift — это язык программирования общего назначения, разработанный Apple Inc., впервые выпущенный в 2014 году для своих платформ и Linux. Swift имеет открытый исходный код. Используйте тег только для вопросов о языковых функциях или необходимости кода в Swift. Используйте теги [ios], [ipados], [macos], [watch-os], [tvos], [swiftui], [cocoa-touch] и [cocoa] для (не зависящих от языка) вопросов о платформах или рамки.