URLSession.webSocketTask tries to connect with https instead of provided was

I am trying to connect to a socket using a url, which I can confirm connects successfully when using a socket connect tool, but when I try using URLSessionWebSocketTask it fails with the error:

Note: have had to replace url domain and endpoint with *example.com/endpoint` for work reasons

... NSLocalizedDescription=A server with the specified hostname could not be found.}
FAIL: Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={NSErrorFailingURLStringKey=https://example.com/endpoint, NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLKey=https://example.com/endpoint}

The url I provide starts with the wss prefix:

let socketUrl = "wss://example.com/endpoint"
...
webSocketTask = urlSession.webSocketTask(with: socketUrl)
webSocketTask?.resume()

but the error posted earlier indicates that the task is trying to connect using https instead (which the server does not support).

I don't remember having to setup anything last time, but it has been about a year since working with these things. Have I missed something setup or app transport security settings etc?

You’re putting too much faith in the details of that error. Under the covers WebSocket does an initial HTTP-style request to set up the connection, so it doesn’t surprise me that URL is leaking out into the error message.

Consider this tiny test project:

import Foundation

class Main: NSObject, URLSessionWebSocketDelegate {

    func run() {
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config, delegate: self, delegateQueue: .main)
        let url = URL(string: "ws://localhost:12345/foo")!
        let t = session.webSocketTask(with: url)
        t.resume()
        withExtendedLifetime(t) {
            dispatchMain()
        }
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error {
            print("did fail, error: \(error)")
        } else {
            print("did succeed")
        }
    }
}

func main() {
    let m = Main()
    m.run()
}

main()

If you just run it, you get this:

did fail, error: Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo={NSErrorFailingURLStringKey=http://localhost:12345/foo, NSErrorFailingURLKey=http://localhost:12345/foo, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalWebSocketTask <CEDBB285-3FC2-47E8-8672-F5C02CB1F99D>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalWebSocketTask <CEDBB285-3FC2-47E8-8672-F5C02CB1F99D>.<1>, NSLocalizedDescription=Could not connect to the server.}

As you can see, the URL is http. However, if you run a local server and run it again, you see that it make a WebSocket request:

% nc -l 12345
GET /foo HTTP/1.1
Host: localhost:12345
User-Agent: xxst (unknown version) CFNetwork/1406.0.4 Darwin/22.4.0
Sec-WebSocket-Key: xAEQQY98xxpQGoPXqShvjQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
Accept: */*
Sec-WebSocket-Extensions: permessage-deflate
Accept-Language: en-GB,en;q=0.9
Accept-Encoding: gzip, deflate
Connection: Upgrade

…

Regarding your real issue, the error you’re getting is NSURLErrorCannotFindHost, which suggests that you have a DNS issue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the response, I resolved the issue after reading this. And this is completely developer error - the updated entitlements for the app running this were not included in the git branch I was working from. The incoming/outgoing connection entitlements were not enabled at all 🤦‍♂️- I have fixed the entitlements and it's all good now.

Apologies, this is something I should have confirmed before bugging folks (end of day brain) 😅

URLSession.webSocketTask tries to connect with https instead of provided was
 
 
Q