iOS WebSocket error: Default TLS Trust evaluation failed

I'm trying to connect to a web socket server using WatchKit. I already have a Javascript app and a Windows application that can connect to this WebSocket server, but with iOS and WatchOS it fails with the errors below. Any idea how I can figure out what's wrong? I already added the App Transport Security Settings to my plist file.

Connection 1: default TLS Trust evaluation failed(-9807) Connection 1: TLS Trust encountered error 3:-9807 Connection 1: encountered error(3:-9807) Connection 1: unable to determine interface type without an established connection

but with iOS and watchOS it fails with the errors below.

The story is different for iOS and watchOS. On the watchOS side of things, WebSocket, like all low-level networking, will only work in very specific circumstances. See Low-Level Networking on watchOS.

That restriction does not apply on iOS, so there’s an open question as to why things are failing there. Based on the error you posted I presume you’re using secure WebSocket, that is, a wss:// URL. Is that right?

If so, does your WebSocket server have a fixed DNS name and a TLS certificate that was issued by a standard CA? Oh, and if so, is it available on the wider Internet? Could you post the host name here?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I'm pretty sure the answer is Yes to both of those questions, but I'm not 100%. Would rather not post the URL publicly, can I email it to you at the address in your post? Thanks!

Would rather not post the URL publicly, can I email it to you at the
address in your post?

Absolutely. I put that URL into a test project and it seems to connect just fine. Specifically, this code:

Code Block
class MainViewController: UITableViewController {
var connection: NWConnection?
func test() {
if let connection = self.connection {
connection.cancel()
self.connection = nil
}
let params = NWParameters.tls
let webSocketOptions = NWProtocolWebSocket.Options()
params.defaultProtocolStack.applicationProtocols.insert(webSocketOptions, at: 0)
let url = URL(string: "wss://example.com:443")!
let connection = NWConnection(to: .url(url), using: params)
connection.stateUpdateHandler = { state in
print(state)
}
connection.start(queue: .main)
}
… rest of the view controller …
}


prints:

Code Block
preparing
ready


indicating that the TCP + TLS + WebSocket connection went through.

IMPORTANT In the code posted here I’m using example.com but in my test project I used the URL you sent me.

This suggests one of two problems:
  • There’s something in your environment that’s triggering this issue.

  • Your code is doing something different from my code.

To make progress I’d like you to create a small test app with the code above. Does it reproduce the problem? That’ll tell us whether this is an environmental issue or a code difference.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I was trying it with NSURLSessionWebSocketTask on WatchOS. Looks like NWConnection isn't available in Objective-C. Would this work the same?

NSURL * url = [NSURL URLWithString:@"wss://domain.com:443"];
NSURLSessionConfiguration *conf = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * URLSession = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:nil];
webSocketTask = [URLSession webSocketTaskWithURL:url];
[webSocketTask resume];

I was trying it with NSURLSessionWebSocketTask on watchOS.

That’s not going to work, for the reasons I outlined in my first post on this thread. I ran my test on iOS because, of the two platforms you mentioned, that’s the only one where WebSocket is feasible (unless you happen to be an audio streaming app).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I was able to connect to 'wss://echo.websocket.org' in my WatchOS app and send/receive messages with the code above. What is different about my website that it's not letting me connect? Thanks
So you are an audio streaming app?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I'm not doing audio streaming. I understand I can't do low level network programming on WatchOS, but the post you linked to said to use NSURLSession, which is what I'm trying to use. I was able to get it to communicate with the test server URL I posted, but what is different about my server that it's not allowing the connection?
Thanks

the post you linked to said to use NSURLSession

Right. Matt glossed over an important detail here. NSURLSession supports many different task types. The high-level ones (data task, download task, upload task) are supported on watchOS. The low-level ones (stream task, WebSocket task) are not (except in the context of streaming audio). When folks say “URL session”, they usually refer to the high-level ones, and Matt’s post just follows that convention. Sorry about the confusion. I’ve pinged Matt asking that he update his post.

Anyway, let me be very clear here: There’s no supported way to implement WebSocket on watchOS except in the context streaming audio. You need to find a different way to approach your problem.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I have update the post for Low-Level Networking on watchOS. Thank you for calling this out the situation with NSURLSessionWebSocketTask and NSURLSessionStreamTask on watchOS.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thanks for explaining, that saved me a lot of time debugging something that was never going to work. Is there any reason Apple hasn't added more robust networking to WatchKit? Either full fledged WebSockets and/or regular Sockets would make a world of difference. Our app is severely stifled by having to route our data through our iPhone app, both in terms of unusable performance and the fact that we can't make a standalone Watch app without it. We have so many cool features that we have been wanting to add since WatchOS 1 that still aren't possible because of the lack of sockets. Keeping my fingers crossed for WWDC 2021. 🤞🏻
Thanks for your help!

Is there any reason Apple hasn't added more robust networking to
WatchKit?

watchOS already has robust low-level networking, as illustrated by the fact that this stuff works just fine in the context of streaming audio. As to why ‘normal’ apps aren’t allowed to access this, I don’t think we’ve ever offered any official explanation for that (but I expect that it relates to power management, because everything on watchOS relates to power management :-).

Keeping my fingers crossed for WWDC 2021.

Absolutely!

And if you don’t receive good news there my advice is, as always, file an enhancement request that captures your specific requirements.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
iOS WebSocket error: Default TLS Trust evaluation failed
 
 
Q