My app use socket API to download content from http server. When it is downloading by 4G connection, iPhone auto joined a WiFi hotspot. But app still use 4G network, but not switch to WiFi automatically. Once the app restarted, it will use WiFi to download content again.
I am wondering that is there any limitation when switching from 4G network to WiFi?
It seems there is no such issue when switching from WiFi to 4G.
Anyone have suggestion on it?
iOS uses a technique called scoped routing, which ensures that, if a connection is running over interface A, it does not break when the default interface changes from A to B. If you’re using BSD Sockets directly then you don’t benefit from any of the smarts of the higher-level APIs. In that case you must specifically watch for interface changes and, if it’s appropriate, shut down your existing connection and re-establish a new connection over the new default interface. The most obvious way to do this check is via the reachability API. In a situation like this you need to set up two long-running reachability queries when you start your connection:
You should create an address pair query (
) with the source and destination addresses of the connection (which you get usingSCNetworkReachabilityCreateWithAddressPair
andgetsockname
, respectively). This will allow you to detect when the source address being used for the connection goes away. For example, if you have a BSD Sockets connection running over Wi-Fi and the user turns off Wi-Fi, the source addressed being used by the TCP connection goes away and thus the connection is effectively dead. However, BSD Sockets won’t tell you about that, so the connection will keep on doing nothing until it times out.getpeernameYou should create a DNS name query (
) with the destination DNS name and monitor it for changes in theSCNetworkReachabilityCreateWithName
flag. If you start a connection while the default interface is WWAN, this flag will be set. If the default interface changes to Wi-Fi, this flag will get cleared. At that point you can schedule the switch from WWAN to Wi-Fi (which you do by closing the WWAN connection and opening a new connection, which will run over Wi-Fi because that’s now the default interface).kSCNetworkReachabilityFlagsIsWWAN
IMPORTANT It’s generally a good idea to ‘debounce’ reachability queries, only taking action if the system is in the ‘wrong’ state for a second or two. It’s very common to get transient reachability changes, and if you immediately take action on the change then you can end up doing the wrong thing (for example, closing a connection unnecessarily).
Finally, I should point out that higher-level APIs make this easier. For example, NSURLSession stream tasks will automatically close if their source address becomes invalid. They also have the handy-dandy
-URLSession:betterRouteDiscoveredForStreamTask: delegate callback to tell you about default interface changes.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"