[英]Using NSURLConnection with a valid SSL certificate in Swift
我對IOS開發比較陌生。 因此,請忍受我並原諒任何點頭!
我正在嘗試使用NSURLConnection從SOAP Web服務獲取數據,並且工作正常。
但是,只要將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!)
}
它貫穿代碼到達“是”,因此據我所知應該信任證書,但是當我使用https url時仍然沒有任何顯示。
因此,除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運行它時,它現在記錄“連接錯誤”!
因此,我將didreceiveresponse更改為:
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
var httpresponse = response as? NSHTTPURLResponse
println("status \(httpresponse?.statusCode)")
println("headers \(httpresponse?.allHeaderFields)")
}
而且我看到的狀態碼是404-我只是不明白,因為Web服務顯然在那兒,並且可以使用在線解析器進行解析!
因此仍然存在,但至少它指出了問題所在。 有人有什么想法可以進一步幫助我嗎?
如果其他人對此感到困惑,那么SVC Web服務的Web配置將更改為:
<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>
這樣就解決了,因此上面的快速代碼現在可以正常工作了! ew,那真是艱難!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.