iOS App Crash when calling UDPSocket.Write

Yeah definitely Apple causing the socket to be disconnected. Though Xojo should be able to handle it more gracefully than a hard crash I would think

1 Like

When the app is in the background, the UDPSocket works fine. It gets data and updates data in the app. I’ve left it in the background for over 30 seconds.

TCPSockets seem to function fine as well.

it’s locking that causes the problem. And I’m fine if Xojo detects that the socket has disconnected and then allows me to reconnect. That is no issue. But the socket is disconnecting and Xojo is not seeing that.

For now I think you have to manually take down the socket and recreate it. And wait for a bug fix that handles SIGPIPE properly for the socket being disconnected to avoid the crash/tell you the socket no longer exists

Looks like it. That SigPipe issue has been around a while it seems. That thread you linked to was 2 years old.

Obviously something very different happens between when the phone is locked vs. the app just being in the background. When the phone is unlocked with the app in the background, the UDPSocket stays connected. I just let it sit for at least five minutes and changes I made in the desktop app where reflected in the iOS app when I came back into the iOS app.

But since UDPSocket and TCPSocket both are subclasses of Socket.Core I’d expect to see the same issue with TCPSockets but I don’t.

Xojo hasn’t responded yet to my bug report. It’s also curious that you don’t see this with the simulator either.

How long did you wait before you said “xojo didn’t see the disconnect” ?
After a (error) disconnection (internally) it could be up to 60-75 seconds (or more) depending on the system settings before you’d get an error.

It would be great if xojo could investigate this a little more, for better socket support (since apple locks down almost everything due to privacy reasons) xojo should stay in the race here.

Well, then that’s part of the problem. People lock and unlock their phones all the time. It seems to take about 10 seconds before writing to the socket results in a crash. You can’t tell a user to wait 75 seconds after unlocking their phone to use an app! But it’s a good sanity check.

At the very least writing to a disconnected socket should throw an exception. I can handle that…

1 Like

did you try:

it should be available for ios

also note that in iOS 14 there is a new Private Address setting in your wifi settings, this may cause different results in networking, Try to turn it off perhaps this may be bugged (as it’s one of apple’s newest features)

This setting:

So some more info for you:

1.) I have not tried the MBS class. I’m not sure if it’s been updated for API2 and 2020r2 yet. Previously there was an MBS UDP class for iOS but it was not part of Christian’s normal plugins.

2.) Turning off the private network did not help.

3.) Waiting longer than 75 seconds (like 10 minutes) after unlocking the phone did not solve the issue. Xojo still doesn’t see the socket as gone. The crash still occurs.

4.) Locking/Unlocking the phone definitely cause the socket to go down. Packets are not received either.

Seems like the socket goes completely nil.

But the challenge is to figure out when to re-create the socket. I don’t want to use the activated/deactivated event of the app because if the app is just sent to the background, but the phone not locked, it still works fine. And do these events fire anyhow if the app is in the foreground but the phone locked and unlocked?

Did you try to write a packet to a network listener first? That may present a message to the user to allow local networking (seems to be a bug in ios14 not sure of this is fixed already)
It will request the message from NSLocalNetworkUsageDescription which may be required

By write i mean write a datagram to a listener that is known without binding first.

More info;

If you read the whole topic you’ll see even apple’s apis don’t seem to provide error handling on this. Since the port will be released while the app is gone to the background. Perhaps you can re-create the socket in App.Activated to be sure you can use it again. Other apps way want to use the ports when your app is to the background. This is not the same as desktop in xojo. iOS is a different thing completely. However it would be great if xojo did find a way to not have it crashing.

The more I look and read about this, the more it seems that UDP sockets are taken apart and shut down when the phone is locked. That thread is from 3 years ago and a lot has changed in iOS since then. It does seem like the socket stays open when the app is in the background - but I’m not sure how long the app will stay active in the background. That’s an unknown. With 65,000+ ports, I don’t think my port number that is above 65,000 is going to be used by any other app. And if a port is in use, iOS should know how to handle it.

I think the real answer is like you said - recreate the socket in the activate event of the app. My remaining question is does that event fire when the app is in foreground and the phone unlocked? That is my next step to investigate. One would assume this is the case, but with Xojo I learned (and especially Xojo and iOS), I learned long ago, never to assume.

just make a small sample project that logs a known string.
Use console to monitor the output value of System.Debuglog on the actual device.

Put it in App.Activated and App.Deactivated.

I had the test app that I used in the bug report. I just added code to display a message box in the app’s activate event.

Yes, it does fire when unlocking the phone even when it is the primary app.

I don’t want to necessarily tear down the socket on de-activating although maybe I should as I’m going to recreate it when activating the app anyhow.

So I just implemented constructing the UDPSocket in the Activate event and then tearing it down in the Deactivate event.

It works great. No more crashing. For some reason my initial request for data from the desktop app is going unanswered but that’s more of an issue with my own protocol than the underlying framework.

I’m going to go out on a limb here and assume that iOS is not informing Xojo that it has taken the socket down. And Xojo is not realizing this and assuming it is up. And as this is probably a SIGPIPE error, it fails silently.