Reputation: 15042
I am using swift 3 and hitting a web service for the first time. My web service runs over HTTPS and I want to test with encryption in place.
Here's my code so far:
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: webService.getLoginUrl())!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error == nil {
do {
if let json =
try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
//Implement your logic
print(json)
}
} catch {
print("error in JSONSerialization")
}
} else {
print(error!.localizedDescription)
}
})
task.resume()
When I run this against my test server, which is self-signed, I get:
The certificate for this server is invalid. You might be connecting to a server that is pretending to be “10.0.0.51” which could put your confidential information at risk.
So what I'd like to do is accept all certificates when testing, but not in production.
I've found a couple of sites like:
http://www.byteblocks.com/Post/Use-self-signed-SSL-certificate-in-iOS-application https://github.com/socketio/socket.io-client-swift/issues/326
But these appear to predate swift 3.
How do I solve this problem?
Upvotes: 2
Views: 7767
Reputation: 15042
After much research, I learned about how delegates work with URLSession objects in swift 3. Too many pieces to post a link, but in the end, this was the most helpful: https://gist.github.com/stinger/420107a71a02995c312036eb7919e9f9
So, to fix the problem, I inherited my class from URLSessionDelegate and then added the following function:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
//accept all certs when testing, perform default handling otherwise
if webService.isTesting() {
print("Accepting cert as always")
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
else {
print("Using default handling")
completionHandler(.performDefaultHandling, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
}
The isTesting() call determines if I'm using the test server, and then we accept all certificates if we're in testing mode.
Upvotes: 7