I want to use a messaging protocol that works fine over 3G, but not over some corporate firewalls. How can my app force the use of the cellular network when it fails to connect over WiFi even in the case that the WiFi network is reachable?
EDIT: After reading through the implementation of the Reachability class I remain unsure whether the two are indeed mutually exclusive. It could well be possible to discover both interfaces via gethostbyname()
, which I might try just to see what comes out.
Use getifaddrs to enumerate the network interfaces. Look for ifa_name that starts with "pdp." This will be the cellular interface (e.g., pdp_ip0). Test (ifa_flags & IFF_UP) to make sure the interface is up, and get the IP address from ifa_addr. Then use bind() to bind your socket to that address.
Not sure how you activate the cellular interface if it is not already up. Normally, I just make a high level http call to get iOS to wake up the network, but not sure under what conditions the cellular service becomes active when wifi is also available. I suspect it is usually there as a fallback to the wifi.
http://iphonedevsdk.com/discussion/comment/120957
From the looks of that thread, it seems like its impossible. Your best bet may be to try using the protocol, and saying something like "please disconnect from wifi and retry" if it doesn't work.
This thread says just about the same thing:
how to programatically start 3g connection on iphone?
You can use the Reachability class which apple wrote in order to test whether the network connection is currently over 3G or WiFi, and even to check if a specific resource is available on the network.
You can use any of the socket library to force to use cellular. Find the cellular interface from getifaddrs, pass the interface to the socket function, socket bind will happen with cellular. e.g. CocoaAsyncSocket