Detect airplane mode on iOS
Asked Answered
G

5

65

How can I detect if the phone is in airplane mode? (It's not enough to detect there is no internet connection, I have to be able to distinguish these 2 cases)

Gaw answered 26/1, 2011 at 12:9 Comment(5)
Would you explain why you need to distinguish these two cases? What difference does it make if the user has no connection because of coverage or no connection because of airplane mode?Pelerine
Becuase we can distinguish this on other mobile platforms and we would like to have the same functionality accross platforms as much as possible. We show different status messages depending on this and we try to guide user to correct the problem.Gaw
I know this is an old question, but just to clarify the need for this 'extraordinarily narrow situation': When an iPhone is in airplane mode, GPS locations are extremely unreliable, but do not cause errors. I subscribed to GPS events and left my app running for 2 hours. No errors, no gps locations, and all checks for 'can receive location events' return YES. However, disabling 3g and wifi manually gave me NO for the internal 'can receive location' checks. There is definitely a need for detecting Airplane mode explicitly as opposed to a general reachability check.Tonsure
This question shouldn't have been closed. Whoever closed it either didn't understand the question or didn't understand how many other people would be interested in it. It's a valid question and it includes useful answers. Please don't be so quick to close questions.Inlaid
On some devices, at least, airplane mode turns off GPS as wellObregon
I
21

Try using SCNetworkReachabilityGetFlags (SystemConfiguration framework). If the flags variable handed back is 0 and the return value is YES, airplane mode is turned on.

Check out Apple's Reachability classes.

Inquiline answered 26/1, 2011 at 12:21 Comment(3)
Hi, the return value is YES and I get zero in both of these situations: 1) Wifi is disabled from settings and there is no sim card in the phone 2) airplane mode. So unfortunately your suggestion doesnt solve my problem.Gaw
isn't the reachability status the same in both situations? okay, the bluetooth status could be different.Inquiline
Apple's choice of the term "reachability" is unfortunate. It's really closer to "am I connected now?" than "will I be reachable in the future?" An app might care because if you're in Airplane Mode, you won't be reachable in the future. That message you sent won't get a reply, that game invite can't be accepted, etc.Geulincx
C
5

You can add the SBUsesNetwork boolean flag set to true in your Info.plist to display the popup used in Mail when in Airplane Mode.

Cool answered 26/1, 2011 at 23:26 Comment(1)
EXCEPT that this is undocumented and may break in a future release of iOS.Hectograph
T
4

Since iOS 12 and the Network Framework it's somehow possible to detect if airplane mode is active.

import Network

let monitor = NWPathMonitor()

monitor.pathUpdateHandler = { path in
    if path.availableInterfaces.count == 0 { print("Flight mode") }
    print(path.availableInterfaces)
}

let queue = DispatchQueue.global(qos: .background)
monitor.start(queue: queue)

path.availableInterfaces is returning an array. For example [en0, pdp_ip0]. If no interface is available is probably on flight mode.

WARNING If airplane mode and wifi is active then path.availableInterfaces is not empty, because it's returning [en0]

Teriann answered 24/3, 2019 at 13:31 Comment(4)
This is a good approach, actually. The problem is you can't distinguish the missing interfaces from a device that doesn't have a SIM card and shouldn't have those interfaces.Geulincx
This is sufficient for most "use cases".Boonie
I think only checks if the device can access data from cellular. If the device does not have "bars" this will return true and so does not determine if aroplane mode is on.Aggressor
In Airplane mode, this will print Flight mode and then crash, since you are printing the path.availableInterfaces array when it is empty. I think you should put the second print into the else statement.Intravasation
S
2

For jailbroken tweaks/apps:

@interface SBTelephonyManager : NSObject
+(id)sharedTelephonyManager;
-(BOOL)isInAirplaneMode;
@end

...

bool isInAirplaneMode = [[%c(SBTelephonyManager) sharedTelephonyManager] isInAirplaneMode];
Singlecross answered 8/6, 2017 at 6:14 Comment(0)
A
1

We can not get this information without using private libraries. Here is some code but it will not work when carrier signal is not available.

UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];

NSString *dataNetworkItemView = nil;

for (id subview in subviews) {
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]]) {
            dataNetworkItemView = subview;
            break;
     }
}
double signalStrength = [[dataNetworkItemView valueForKey:@"signalStrengthRaw"] intValue];
 if (signalStrength > 0) {
        NSLog(@"Airplane mode or NO signal");
  }
  else{
        NSLog(@"signal available");
  }
Anility answered 29/11, 2016 at 11:21 Comment(1)
iOS 13 broke this, throwing a moderately obscure exception if you try it. We were using (roughly) the above, opened a Tech Support Incident with Apple, and they replied: "We have reviewed your request and have concluded that there is no supported way to achieve the desired functionality given the currently shipping system configurations."Geulincx

© 2022 - 2024 — McMap. All rights reserved.