Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accurately reading of iPhone signal strength

There are a few questions on this already, but nothing in them seems to provide accurate results. I need to determine simply if the phone is connected to a cell network at a given moment.

http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Reference/CTCarrier/Reference/Reference.html

This class seems to be documented incorrectly, returning values for mobileCountryCode, isoCountryCode and mobileNetworkCode where no SIM is installed to the phone. carrierName indicates a 'home' network or a previous home network if the phone has been unlocked.

I also looked up and found some people claiming the following to work, which uses an undocumented method of the CoreTelephony framework, but the results have been useless to me, reporting seemingly random figures, where perhaps it is not itself updating consistently.

-(int) getSignalStrength
{
    void *libHandle = dlopen("/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony", RTLD_LAZY);
    int (*CTGetSignalStrength)();
    CTGetSignalStrength = dlsym(libHandle, "CTGetSignalStrength");
    if( CTGetSignalStrength == NULL) NSLog(@"Could not find CTGetSignalStrength");
    int result CTGetSignalStrength();
    dlclose(libHandle);
    return result;
}

Thanks.

Edit: The app is connected to an internal wifi and must remain so, making a reachability check more difficult.

like image 547
stevepkr84 Avatar asked Jan 30 '13 12:01

stevepkr84


People also ask

How many bars should my iPhone have?

A display of two bars or higher should be more than adequate in certain circumstances. What counts the most is reliability. In other words, if you're using a Smart Signal Booster® like Cel-Fi, the real measure of success is if you have consistent service in all areas of your home or office where you need it.

What is an acceptable cell phone signal strength?

Cell phone signal strength is measured in decibels (dBm). Signal strengths can range from approximately -30 dBm to -110 dBm. The closer that number is to 0, the stronger the cell signal. In general, anything better than -85 decibels is considered a usable signal.


2 Answers

I'm playing with this function and I've noticed you're calling it in an interesting way. I'm calling it by adding CoreTelephony.framework as a compile-time link. For the function itself, you'll want to declare it's prototype somewhere (perhaps immediately above the method you call from):

int CTGetSignalStrength();

This needs to be declared since it isn't in a public header for CoreTelephony.

Now, I built a simple app that prints signal strength every second.

int CTGetSignalStrength();

- (void)viewDidLoad
{
    [super viewDidLoad];

    while (true) {
        printf("signal strength: %d\n", CTGetSignalStrength());
        sleep(1);
    }
}

I ran it on my iPad mini and it shows steady values until I picked it up, where the number went up. Wrapping my iPad in tin foil (tin foil is a debugging tool I have never used before) caused the number to go down. When I put my iPad in airplane mode, it kept repeating the last value, so this will not be an accurate measure for you.

If you want to test if a device currently has a cellular data network connection, you may be more interested in Reachability, specifically kSCNetworkReachabilityFlagsIsWWAN.

like image 150
wjl Avatar answered Oct 05 '22 22:10

wjl


Ok I think I have the correct solution now, which was a bit simpler in the end.

The issue with the CTGetSignalStrength() method is that it works normally, but if you remove a sim, it reports the last signal before the removal. I found another method in the same framework called CTSIMSupportGetSIMStatus(), also undocumented, which can tell you if a SIM is currently connected. Using both as follows should confirm the current network signal.

First declare the methods:

NSString * CTSIMSupportGetSIMStatus();
int CTGetSignalStrength();

Then check connectivity to cell network like so:

NSString *status = CTSIMSupportGetSIMStatus();
int signalstrength = CTGetSignalStrength();
BOOL connected = ( [status isEqualToString: @"kCTSIMSupportSIMStatusReady"] && signalstrength > 0 );
like image 34
stevepkr84 Avatar answered Oct 06 '22 00:10

stevepkr84