Albert Renshaw
Albert Renshaw

Reputation: 17902

iOS - is a user in the United States?

Is there any way for me to detect whether or not a user is in the US without asking for their location? For example, when I go to Fandango on my computer it knows which county and state I'm in just based on my WiFi.

If I have a device, perhaps an iPod Touch, that doesn't have GPS, and I wanted to verify it is in the United States, and they are connected to WiFi... or if I had an iPhone and it was connected with 3G and I wanted to make sure the users were in the US, is there a way I can check that information without the little alert view "__ would like to use your current location"? I don't need exact coordinates, I just need to confirm that these users are in the USA (including Hawaii and Alaska)... locale?

Upvotes: 7

Views: 4158

Answers (9)

Scott Bartell
Scott Bartell

Reputation: 2840

I would first try to check the carrier's Mobile Country Code. It will tell you the numeric mobile country code for the user's cellular service provider and cannot be changed by the user unless they switch to a service provider in a different country.

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

CTTelephonyNetworkInfo *netInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [netInfo subscriberCellularProvider];
NSString *mcc = [carrier mobileCountryCode];

This of course will not work with devices that are not connected to a mobile carrier (iPod Touch, some iPads, ect). Therefor, as a fall back, I would use or create my own IP geolocation API. You can get a free database that is 99.5% accurate on a country level. This will work great to detect the country of a device that doesn't have a mobile provider.

Upvotes: 5

jturolla
jturolla

Reputation: 6756

Ok, how do you do that with the IP.

So, geoplugin.net has it's amazing JSON api, it defaults the IP to the currently conection, so what you have to do is make a request to this address:

http://www.geoplugin.net/json.gp

Astunishing! It returns, for me, this data:

geoPlugin({
  "geoplugin_request":"201.6.226.233",
  "geoplugin_status":200,
  "geoplugin_city":null,
  "geoplugin_region":"S&atilde;o Paulo",
  "geoplugin_areaCode":0,
  "geoplugin_dmaCode":0,
  "geoplugin_countryCode":"BR",
  "geoplugin_countryName":"Brazil",
  "geoplugin_continentCode":"SA",
  "geoplugin_latitude":-23.473301,
  "geoplugin_longitude":-46.665798,
  "geoplugin_regionCode":27,
  "geoplugin_regionName":"S&atilde;o Paulo",
  "geoplugin_currencyCode":"BRL",
  "geoplugin_currencySymbol":"&#82;&#36;",
  "geoplugin_currencyConverter":2.0198
})

Well, now what you have to do is just parse this "JSON". It's not actually a JSON as it has this geoplugin( {data} ) wrapper. So you could lazily execute some filtering, removing those parts of a NSSTring, maybe.

I See you are in a hurry, so I took my spare time to write some code for you. It's very non-standard as I don't know if you are using any REST framework that would help, but here goes:

NSString *url = [NSString stringWithFormat:@"http://www.geoplugin.net/json.gp"];


    NSString *locationData = [[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]
                                                encoding:NSUTF8StringEncoding]];

    locationData = [locationData stringByReplacingOccurrencesOfString:@"geoPlugin(" withString:@""];
    locationData = [locationData stringByReplacingOccurrencesOfString:@")" withString:@""];

    //user some json parser here.
    if([[[locationData JSONValue] valueForkey:@"geoplugin_countryCode"] isEqualToString:@"US"]){

        //proceed.
    }

Upvotes: 7

Jim
Jim

Reputation: 5960

You said you can't ask the user for the location. Are you able to use CoreLocation for location services? If you are, then you are very likely going to be able to obtain their location without asking them, simply by using location services. GPS is not required, as long as wifi is enabled. There are several good points about this made in this thread.

Once you have obtained the location, you can use a geocoder to determine if it's located in the US.

If you need more details, just ask, but this method is really very simple.

Upvotes: 0

Rayvyn
Rayvyn

Reputation: 77

have alook at geoPlugin, it has several webservices you can use to get the users location based of the IP and its free.

Upvotes: 1

Asad Nauman
Asad Nauman

Reputation: 969

You will easily find the database on the web that will tell you about user country based on their IP then make a web-service that will detect the user IP and return the flag for US.

Upvotes: 0

relower
relower

Reputation: 1313

if you want to reach information about your current city - country etc. with your current location info (latitude, longitude) you can use this

hope works for you. good luck.

EDİT:

ohh sorry, i didnt see the info about GPS.

Upvotes: 0

Mars
Mars

Reputation: 361

The simplest solution is to query an existing web service, like hostip.info.

Please note that this is merely a sample (you should query the web service differently), but for the sake of simplicity:

NSError* error = nil;
NSString* country = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://api.hostip.info/country.php"] encoding:NSUTF8StringEncoding error:&error];
//will show US if user is in the United States
NSLog(@"%@", country);

You'd also acquire a (free) database yourself from http://www.maxmind.com/app/installation and either create a web service or include it in your application (not recommended.)

Upvotes: 1

Carl Veazey
Carl Veazey

Reputation: 18363

If you are not allowed to ask for the user's location, using an IP based reverse geolocation service is the only way to go. I've never used any public services so I can't comment on the quality of any of them, unfortunately. This can be inaccurate as far as regions within the USA (I've seen IPs from 3G connections be way off). This will probably defeat the casual user.

Of course, sophisticated 'attackers' will get around this easily with a proxy. There seem to be ways of detecting if requests come from proxies but these don't seem to be 100% either.

If using the user's location becomes an option, then you can use either CLGeocoder, or use a web service that does reverse geocoding from latitude and longitude values collected via Core Location. For an even greater level of security, sign the latitude and longitude values to help ensure their integrity. I think that's probably the best option if you really need to have the best possible protection from international users participating.

Hopefully this helps put you on the right track. There are a lot of options out there so I'm confident depending on your needs you'll be able to find a good solution.

Upvotes: 0

I&#39;m with Monica
I&#39;m with Monica

Reputation: 329

In a networked environment the user's location is usually "identified" through the IP address.

What is the purpose of the inside/outside US determination? How accurate/fail safe has it to be? What are the consequences, when a user is wrongly identified as being inside the US? What are the consequences, when you produce a false negative? Are you violating contracts or licenses, when you have a false positive? Or even commiting a crime? Or do you just dislike foreigners and it is your (or your employer's) dignity that is injured?

The real question is: How reliable is the information you gain by localizing an IP address and is this reliability enough for your purpose?

As you have a way to get a country code for a given IP address, you just have to compare it to the given set of allowed codes and you are done. If, that is, the quality of the source of said code meets your requirements.

Upvotes: 3

Related Questions