I have a weird problem with HTTPS connection.
Task <A19A5441-F5CD-4F8C-8C88-73FC679D8AE0>.<1> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made."
I am trying to bypass server certificate of my website because it's self-signed.
The following code works in a test app, but not in another app. They have exactly have the same entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
let protectionSpace = challenge.protectionSpace
guard protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
protectionSpace.host.contains("mywebsite.net") else {
completionHandler(.performDefaultHandling, nil)
return
}
guard let serverTrust = protectionSpace.serverTrust else {
completionHandler(.performDefaultHandling, nil)
return
}
let credential = URLCredential(trust: serverTrust)
completionHandler(.useCredential, credential)
}
@IBAction func testMenuItem_select(_ sender: Any) {
print("\(sender)")
Preferences.instance.openTipShowed = false
testURLSession()
func testURLSession() {
let session = URLSession(configuration: URLSessionConfiguration.ephemeral,
delegate: self, delegateQueue: nil)
let url2 = "https://www.mywebsite.net/spiders.txt"
let url3 = "https://www.apple.com/"
let url = URL(string: url2)!
var request = URLRequest(url: url)
let task = session.dataTask(with: request) { data, response, error in
if let error { print(error) }
if let data {
let text = String(data: data, encoding: .utf8)
print("HTTP response object:", response ?? "")
print("HTTP resonse text:", text ?? "<empty response>")
}
}
task.resume()
}
}
I found the answer myself. It's a misunderstanding of ATS (Apple Transport Security) feature.
I thought only non-HTTPS protocol needs the following ATS in info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But it turned out that connecting to HTTPS also needs the above setting.