问题
I'm using Xcode 7, Swift 2, and iOS9. I want to connect to a web service using NSURLSession but I get the following error when I try to connect:
2015-10-13 16:07:33.595 XCTRunner[89220:4520715] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
2015-10-13 16:07:33.604 XCTRunner[89220:4520571] Error with connection, details: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “domainapi.com” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fac7b6facc0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?,
Here is my code:
func request( dataPost : String, successHandler: (response: String) -> Void)-> String {
let destination:String = "https://domainapi.com:8743/WebService/sendData"
let request = NSMutableURLRequest(URL: NSURL(string: destination as String)!)
request.HTTPMethod = "POST"
let postString = dataPost
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
request.setValue("0", forHTTPHeaderField: "Content-Length")
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")
request.setValue("gzip,deflate", forHTTPHeaderField: "Accept-Encoding")
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
NSLog("Body is: %@", request.HTTPBody!)
NSLog("Request is: %@", request.allHTTPHeaderFields!)
NSLog("URL is: %@", destination)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
NSLog("Error with connection, details: %@", error!)
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
successHandler(response: responseString as String!);
NSLog("Data received: %@", data!)
}
task.resume()
return "worked"
}
func viewDidLoad() {
let dataPost : String = "<webservices>xml data sending</webservices>"
request(dataPost, successHandler: {
(response) in
let text = response
print(text)
});
I've looked into NSURLAuthenticationChallenge
but I can't seem to figure that out with the code I currently have in place. So my question is how can I connect to the server anyway? I've already tried adding the domain to my NSAppTransportSecurity
in Info.plist but that did not work. Turning on NSAllowsArbitraryLoads
didn't work either. Any help would be appreciated.
回答1:
Take a look at this article.Shipping an App With App Transport Security particularly the sections about self-signed certificates.
You'll most likely need the delegate method of the form,
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
completionHandler(
.UseCredential,
NSURLCredential(trust: challenge.protectionSpace.serverTrust!)
)
}
Adding this to my own comms class that uses NSURLSession fixed the issue.
回答2:
When creating the URL Session, use the initializer, that sets the delegate along with the configuration, like below:
let urlSession = URLSession(configuration: urlSessionConfiguration, delegate: self, delegateQueue: nil)
Then, implement the following delegate method, it should work.
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, urlCredential)
}
However, it is very important to note, that this is a security issue, and we should not be trying to connect to servers with invalid certificates.
回答3:
open your info.plist as a source code Add following:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This should help.
回答4:
For SWIFT 4:
func URLSession(session: URLSession, didReceiveChallenge challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(
.useCredential,
URLCredential(trust: challenge.protectionSpace.serverTrust!)
)
}
来源:https://stackoverflow.com/questions/33128240/connect-to-a-server-with-invalid-certificate-using-nsurlsession-swift2-xcode7-i