2

I am building an app that should only be used if airplane mode is activated. The app is for people that are not tech savvy to say the very least. Therefore, I cannot expect them to swipe up and click the airplane icon. What is the closest I can get to simply turning on airplane mode form within my app?

Basically, I am looking for the opposite of UIRequiresPersistentWifi.

David H
  • 40,852
  • 12
  • 92
  • 138
Zia
  • 14,622
  • 7
  • 40
  • 59
  • You basically want to ensure that no network is available, right? – Gabriele Petronella Oct 23 '13 at 19:03
  • Yes but not exactly. No network availability still leaves the chance for connecting to wifi if the device comes in range of a network. I need to be sure that there is no possibility of connecting to a network. – Zia Oct 23 '13 at 19:10
  • Out of curiosity, what is the reason behind? I can not imagine any reason (beside try to cheat app store or similar). – Matthias Oct 23 '13 at 19:28
  • 1
    Even with airplane mode on, a user can still switch on wifi – Allen Zeng Mar 04 '14 at 09:48

3 Answers3

3

There's currently no public API for direct checking whether the airplane mode is on.

The closest solution would be to use the SystemConfiguration framework and monitor whether the device can connect to the network.

Using the Reachability class (by tonymillion) you can do something like

Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];
reach.reachableBlock = ^(Reachability*reach) {
    // do something to prevent the app to be used
    // NOTE: this block is called on a background thread
    // so if you need to change the UI, do 
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI related stuff
    });
};
reach.unreachableBlock = ^(Reachability*reach) {
    // ok continue using the app
};
[reach startNotifier];
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • Thank you, I suspected so. The device shouldn't be connected to any network. Even one that has no access to the internet. So that leaves out reachability. – Zia Oct 23 '13 at 19:26
  • Then I'm afraid you're out of luck. You can file a feature request via https://bugreport.apple.com/ – Gabriele Petronella Oct 23 '13 at 19:28
1

Well, I can give you an easier and faster technique. Run the the getIPaddresses method from this answer before asking the user, and save the info (or at least the count). You should see something like this:

"awdl0/ipv6" = "0:0:fe80::6456:66ff";
"en0/ipv4" = "192.168.1.4";
"en0/ipv6" = "0:0:fe80::4e5:772f";
"lo0/ipv4" = "127.0.0.1";
"lo0/ipv6" = "0:0:fe80::";
"pdp_ip0/ipv4" = "10.226.14.199";

These are all the active IP addresses. Now ask them to turn Airplane Mode on. When they tap yes, then run that code again, and the returned dictionary should be nil. If it isn't, and its the same as before, they lied!

I did look to see if Airplane mode would turn the interfaces OFF (interface->ifa_flags & IFF_UP) but it does not, and the two loopback addresses are always active.

Community
  • 1
  • 1
David H
  • 40,852
  • 12
  • 92
  • 138
  • I think this is my best option to look into. The code in the answer you linked to ignores loopback addresses. Do you think the dictionary should be nil if the device is in airplane mode? How about if it's not in airplane mode but not connected to a network either? – Zia Oct 23 '13 at 21:17
  • @user2891327, the loopback addresses are there in airplane mode - you can verify by commenting out the one test. If the phone can connect to a cellular network then that address will be set. So the algorithm stands - if there are addresses before you ask them, then none after, you know they switched it off. If there are none to start with, well, then you don't know for sure. For the record, I entered a bug report asking for apple to make an API for this years ago, it obviously was never addressed. – David H Oct 23 '13 at 21:49
  • So then does this test need to be done every time the app is used? I filed a bug report for it too. – Zia Oct 23 '13 at 22:27
  • You said you want to insure your app is only used when Airplane mode is on. So if this is so, when your app launches, you do the test, pop the alert, get the answer, and decide to go on. From then on, every time your app "wakes up" i.e. enters the foreground, you need to retest to see if all addresses are gone. There is no magic. You could even test periodically - the cost to do this is very small - and if you ever see an address the user has cheated and you can call "exit(0)", or scold them, or whatever you want to do. – David H Oct 24 '13 at 00:25
0

You can do better than having the user teach you what airplane mode looks like, the pdp_ interfaces are the cellular interfaces, so if they're not there, then the phone is either in airplane mode or doesn't have cellular to begin with. This is good enough for my purposes, at least.

Here's what my code looks like in Xamarin:

        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            if ((OperationalStatus.Up == ni.OperationalStatus) && (ni.Description.StartsWith("pdp_")))
                return false;
        }
        return true;
Eliot Gillum
  • 832
  • 9
  • 18