// How to get user external IP and Geolocation Programmatically in iOS – Guilmo

How To IP Geolocation

Published on February 18th, 2013 | by Guilherme Mogames

1

How to get user external IP and Geolocation Programmatically in iOS


So the app you’re building requires for some reason that you get the user’s external ip and not the local device IP and you don’t know where to start.

Well this is where I come in. Find below two different alternatives for getting the user’s external IP.

Regardless of your choice, you will need a webservice that returns the IP to you, and in both methods I have included available webservices.

Method 1 – Using AFNetworking Library with Geolocation

download library at: www.github.com/AFNetworking/AFNetworking

First step is to download the AFNetworking library from the link above and adding that to your project. After adding the library to your project, you first need to import the files in the header of your .m or .h file

#import "AFHTTPClient.h"
#import "AFJSONRequestOperation.h"

Then in your method/function you will need to open a request with the webservice URL

    // Defines the webservice URL
    NSURL *URL = [NSURL URLWithString:@"http://ip-api.com/json"];

    // Start Connection
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:URL];

    // Define the JSON header
    [httpClient setDefaultHeader:@"Accept" value:@"text/json"];

    // Set the Request
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:@"" parameters:nil];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        NSString *myIP = [JSON valueForKey:@"query"];
        NSLog(@"IP: %@", myIP);

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){

        // Failed
        NSLog(@"error: %@", error.description);

    }];

    // Run the Request
    [operation start];

In this example I’m using the free webservice from ip-api.com which returns in the JSON response also the Geolocation data for the request that includes Country, City, Latitude, Longitude, Timezone, ISP, and many more.
To see all information, open the webservice URL in your browser or check the online documentation at: http://ip-api.com/docs/api:json.

In the code above, we started by creating a NSURL with the webservice URL, then we instantiated an AFHTTPClient that will create the online request and defined that the request would have the header text/json. Then we created a NSMutableURLRequest using the AFHTTPClient we instantiated before.

After that, we just created the default operation with the success and failure blocks inside, which means that we can write the code we want to execute in either scenarios right in there, no need to call an extra method or function.

As you could see, the response returns an ID object called JSON, since we are using the AFJSONRequestOperation, this object already comes as an objective-c dictionary, no need to get a new external library like JSONKit.

And to read that object we can use the default [objectName valueForKey:@”JSON Object Key”] passing the key name to get it’s value. In this webservice case, the IP address comes with a key name of “query”. To see all keys, open the webservice URL in your browser.

[update Feb 18th] If you just want to get the IP in this example and not the Geolocation, you can use the URL: http://ip-api.com/line/?fields=query. And you can do this for every field available, just change the ?fields=query to ?fields=XXX

Method 2 – Using NSData To Get IP without Geolocation

The second method is quicker and simple, but it returns a plain NSString with the URL contents in it, so to get the Geolocation, you would have to parse the whole string manually. And that’s why I recommend using the 1st method.

To simply get the user’s IP address, the code you need is:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  NSURL *theURL = [[NSURL alloc] initWithString:@"http://ip-api.com/line/?fields=query"];
  NSString* myIP = [[NSString alloc] initWithData:[NSData dataWithContentsOfURL:theURL] encoding:NSUTF8StringEncoding];

  dispatch_async(dispatch_get_main_queue(), ^{
    // Manipulate the ip on the main queue 
    NSLog(@"IP: %@",myIP);
  });
});

In ther first line we call an async block to prevent the main thread (UI thread) to be blocked while we get the IP.

On the second line we create the NSURL with the webservice URL, in this example, ip-api.com.

The third line is where the magic happens, we instantiate a NSString and initialize it with some content already. This content is a NSData object that gets it’s data from the NSURL we created above using the method dataWithContentsOfURL:encoding:.

The NSData opens that URL and gets all content from it, so if you try to do that with any other website URL, it will return the complete source code. Just make sure to always call dataWithContentsOfURL on a different queue to make sure your application wont be locked while your application download the data.

So the main worry about this 2nd method is that if for some reason the webservice changes anything, like adding an extra white space at the beginning or the end of the string and you do not treat that in your code, your app may break and crash.

You can get the example code by clicking in the link below. Just unzip and run.

Do you have any questions, comments, compliments? hit the comments below.

Thanks

.gm.

Tags: , , , , , ,


About the Author

Founder of the Guilmo.com website and freelance iOS developer for over 2 years. Creator of one of the most used financial app in Brazil and also creator of the iPhone game FlyingMoo. Over 10 years of experience with IT and over 4 years as a Scrum Master for a large multinational IT company.



One Response to How to get user external IP and Geolocation Programmatically in iOS

  1. Bill says:

    This is helpful. Any chance you’ve updated it for AFNetworking 2.0?

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top ↑