after several user reports started with iOS 13, I found the root cause of an issue with my VPN app.
- My networking code runs in a custom DispatchQueue with QoS .utility, as per a suggestion by eskimo in another thread.
- The NEVPNProtocol.disconnectOnSleep flag is set to false.
- I do not override the sleep/wake handlers in NEPackeTunnelProvider.
Until iOS 12, the VPN would keep working across the sleep/wake cycles, with the socket handlers surviving the sleep state. This doesn't seem to be the case in iOS 13, so I dug further.
By overriding sleep() and wake() in the provider, for logging purposes, I noticed that after a "longer" sleep, DispatchQueue.async() blocks hang up. They literally stop running, to then revive immediately after waking up the device. The effect is that the VPN doesn't disconnect on the sleep event, but triggers a ping timeout as soon as the device is turned on again. Due to inactivity.
I can't find a way to restore former "Keep alive on sleep" behavior, because even if the VPN is not actively disconnected on sleep, it still stops working. I mean, does Apple want us to kill the VPN on sleep? Is it an option or a requirement? It's not 100% clear to me from the documentation:
> NEProvider subclasses should override this method if the provider needs to perform any tasks before the device sleeps, such as disconnecting a tunnel connection.
Had this been a requirement, it would IMHO be in contradiction with the existence of "disconnectOnSleep". At this point I even wonder if former behavior (iOS 12) was the side-effect of a bug (= queue surviving sleep), eventually fixed in iOS 13.
I'd like to know more about this, before looking for a fix in an app that TBH had performed very well until iOS 13.