Is there any way to determine if the iphone is roaming?

Aftermathew picture Aftermathew · May 23, 2009 · Viewed 15.6k times · Source

I am working on an iPhone application and would really like to determine if the device is roaming so that I can intelligently avoid costing my users expensive connections if out of their home network.

The application I am writing is for jailbroken phones, however I would prefer to use standard SDKs if possible.

Here is what I've already found:

1. Apple SDKs: In the apple documentation, I found the promise in Apple's SCNetworkReachability API. The API provides access to such things as whether you are on a WIFI or a cell phone network, whether a network connection is currently established, etc. However searching the SCNetworkReachability API reference pdf for 'roam' or 'roaming' both turn up nil. So does their sample code.

2. Grep of a Jailbroken iPhone FS: The preferences -> general -> networking tab is where users can turn on or off their roaming. Looking in the plist file for this ("/Applications/Preferences/Network.plist") I was able to find the following references:

        PostNotification = "com.apple.commcenter.InternationalRoamingEDGE.changed";
        cell = PSSwitchCell;
        default = 1;
        defaults = "com.apple.commcenter";
        key = InternationalRoamingEDGE;
        label = "EDGE_ROAMING_TOGGLE";
        requiredCapabilities =             (
            telephony
        );

This is certainly a lead, as it appears I can sign up for notifications that the user has changed the InternationalRoaming settings. Still, I'm not certain how to turn this into the knowledge that they are in fact, presently roaming.

3. Check the class dumped sources of SpringBoard: I've dumped the classes of SpringBoard using class-dump. I was unable to find any references to 'roam' or 'roaming'

4. Obviously I started by checking at SO for this: Couldn't find anything related.

Further steps: Does anyone have any advice here? I know this is possible. Apple clearly has made it very difficult to find however. I highly doubt this is possible without using a private framework. (such as CoreTelephony). As this is a jailbroken app, I may resort to screen-scraping the the carrier name with injected code in the SpringBoard, but I would really rather prefer not to go that route. Any advice much appreciated. Thanks.

Answer

Aftermathew picture Aftermathew · Jun 8, 2009

There is! It's not documented at all, and I highly doubt this would work on a non-jailbroken phone (as it requires using files not in the sandbox). However, here is how it is done.

The iPhone file system keeps two softlinks:

static NSString *carrierPListSymLinkPath = @"/var/mobile/Library/Preferences/com.apple.carrier.plist";
static NSString *operatorPListSymLinkPath = @"/var/mobile/Library/Preferences/com.apple.operator.plist";

when these links are pointing at the same file, the telephone is not roaming. When pointing at different files, the telephone is romaing.

Simplified code (no error checking, etc):

- (BOOL)isRoaming
{
    NSFileManager *fm = [NSFileManager defaultManager];
    NSError *error;
    NSString *carrierPListPath = [fm destinationOfSymbolicLinkAtPath:carrierPListSymLinkPath error:&error];
    NSString *operatorPListPath = [fm destinationOfSymbolicLinkAtPath:operatorPListSymLinkPath error:&error];
    return (![operatorPListPath isEqualToString:carrierPListPath]);
}