I have the following code (swift implementation):
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLPr
Swift 5 Solution
Note These settings are for testing purpose only, don't push changes in production app
Steps
Add "Allow Arbitrary Loads" key to "YES" under "App Transport Security Settings" in info.plist
Create new session object with delegate to self
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
Implement URLSessionDelegate protocol to current class
extension YouClass: URLSessionDelegate{ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) } }
Modified version of: https://stackoverflow.com/a/30820452/3754976
inherit class with URLSessionDelegate
create a session object
let config = URLSessionConfiguration.default
let session = Foundation.URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: httpRequest as URLRequest, completionHandler: {requestData, response, errorData -> Void in
if errorData == nil {
dataCallback(requestData! as NSData)
}
else {
let error = NSError(domain: "Err-1001", code: 11, userInfo:nil)
failureCallback(error)
}
});
task.resume()
Add delegate methad
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(
.useCredential,
URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
add this in your info.plist file
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>xyc.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
Both connection:canAuthenticateAgainstProtectionSpace:
and connection:didReceiveAuthenticationChallenge:
are deprecated in iOS 8 anyway so you should use other methods.
What I am using in my projects is a delegate method of NSURLSessionDelegate. Adhere to that protocol then add this method:
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}
Then, when you use initialize NSURLSession with delegate set to self. For example:
var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())
Then use that session instance to call dataTaskWithRequest method on:
var task = session.dataTaskWithRequest(request){
(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if error != nil {
callback("", error.localizedDescription)
} else {
var result = NSString(data: data, encoding:
NSASCIIStringEncoding)!
}
}
task.resume()
Complete working example can be found here.
For security reasons, if you use a self-signed certificate I recommend also implementing public key pinning (https://gist.github.com/edwardmp/df8517aa9f1752e73353)