Использование NSURLConnection с действующим сертификатом SSL в Swift
Я относительно новичок в разработке IOS. Поэтому, пожалуйста, потерпите меня и прости что угодно, noddy!
Я пытаюсь вернуть данные из веб-службы SOAP с помощью NSURLConnection, и она работает нормально.
Однако, как только я изменяю URL с http на https, я больше не получаю никаких данных и не получаю сообщение об ошибке или что-то подобное, как я ожидал.
Сертификат https является действительным сертификатом от Godaddy, и он правильно настроен и корректно просматривается во всех браузерах и т. Д., Поэтому в принципе любой может указать мне правильное направление, почему ничего не происходит при переходе с http на https......
Код находится в Swift и выглядит следующим образом:
// Create the SOAP Message to send
var soapMessage = "<?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ns1='http://tempuri.org/'><SOAP-ENV:Body><ns1:get_Test/></SOAP-ENV:Body></SOAP-ENV:Envelope>"
NSLog("soapMessage generated is: %@", soapMessage)
// Soap URL Works
var urlString = "http://api.domain.com/testservice.svc"
//Below https URL does not work
//var urlString = "https://api.domain.com/testservice.svc"
var url = NSURL(string: urlString)
var theRequest = NSMutableURLRequest(URL: url!)
//Get Length of request
var msgLength = String(countElements(soapMessage))
// POST Header values
theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length")
theRequest.addValue("http://tempuri.org/IService/get_Test", forHTTPHeaderField: "SoapAction")
theRequest.HTTPMethod = "POST"
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
NSLog("Request is: %@", theRequest.allHTTPHeaderFields!)
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
if (connection == true) {
var mutableData : Void = NSMutableData.initialize()
}
Дополнительный код NSURLConnection:
// NSURLConnectionDelegate
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
func connection(connection: NSURLConnection, didFailWithError error: NSError) {
NSLog("Error with Soap call: %@", error)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var xmlParser = NSXMLParser(data: mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
// NSURLConnectionDelegate
Затем у меня есть парсеры, такие как didStartElement, didEndElement, foundCharacters, parserDidEndDocument и т. Д.
Я также добавил некоторых дополнительных делегатов NSURLConnection, как показано ниже, но ничего не изменилось. Они вызываются, когда регистрируется регистрация.
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace?) -> Bool
{
NSLog("am here")
return protectionSpace?.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge?)
{
NSLog("am here 2")
if challenge?.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
{
if challenge?.protectionSpace.host == "api.domain.com"
{
NSLog("yep")
let credentials = NSURLCredential(forTrust: challenge!.protectionSpace.serverTrust)
challenge!.sender.useCredential(credentials, forAuthenticationChallenge: challenge!)
}
}
challenge?.sender.continueWithoutCredentialForAuthenticationChallenge(challenge!)
}
он проходит через код, попадает в "да", и поэтому, насколько я понимаю, следует доверять сертификату, но все равно ничего не отображается при использовании URL-адреса https.
Таким образом, нет никакой разницы между любым кодом, кроме https, и сертификат правильно действителен, так как я могу получить данные обратно, используя https, а не http?
Большое спасибо - и извините, если это глупый вопрос!
Дейв
Дополнительно:
Хорошо, я изменил соединение сейчас:
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: false)
connection?.start()
if (connection == true) {
var mutableData : Void = NSMutableData.initialize()
} else {
NSLog("Error with connection, details: %@", connection!)
}
Так что теперь это регистрирует "Ошибка с соединением", когда я запускаю его с SSL!
Итак, я изменил и получил ответ:
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
var httpresponse = response as? NSHTTPURLResponse
println("status \(httpresponse?.statusCode)")
println("headers \(httpresponse?.allHeaderFields)")
}
и я вижу, что код статуса обратно - 404 - что я просто не понимаю, так как веб-сервис явно присутствует и может быть проанализирован с помощью онлайн-анализаторов!
Так что все еще застрял, но, по крайней мере, это указывает на проблему. У кого-нибудь есть мысли, чтобы помочь мне в дальнейшем?
1 ответ
Если кто-то еще застрянет на этом, то веб-конфигурация для веб-службы SVC была изменена на:
<bindings>
<basicHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Service.Service">
<endpoint address="" binding="basicHttpBinding" contract="Service.IService" />
</service>
</services>
Это исправлено, поэтому приведенный выше код swift теперь работает нормально! Фу, это было сложно!