views:

121

answers:

4

I am trying to get the IP Address using NSHost. With the NSHost object I can use the addresses method to access an array of objects one of which is the IP Address. I fear though that the IP Address may change position in the array from one machine to the other. Is there a way to access this information in a universal way?

There was an attempt to answer this question in a previous post, but as you can see it falls short.

http://stackoverflow.com/questions/1331912/ip-address-cocoa

Here is my code:

+(NSString *) ipAddress {
    NSHost * h = [[[NSHost currentHost] addresses] objectAtIndex:1];
    return h ;  
}
A: 

As the answers to the question you mention above have said, there are a variety of IP addresses that a single machine can have. If that is what you want, then you might be better off using the names method of NSHost to get an array of names, which you can then filter for the suffix (i.e *.lan) to get the name of the host you want with this name. In my case. the .lan address returns my network ip address as a dotted quad.

If you want to find the external ip address, then this is a good answer to look at.

Abizern
+1  A: 

I have used this on many machines without problems.

 -(void) getIPWithNSHost{
    NSArray *addresses = [[NSHost currentHost] addresses];

for (NSString *anAddress in addresses) {
    if (![anAddress hasPrefix:@"127"] && [[anAddress componentsSeparatedByString:@"."] count] == 4) {
         stringAddress = anAddress;
        break;
    } else {
        stringAddress = @"IPv4 address not available" ;
    }
}
        //NSLog (@"getIPWithNSHost: stringAddress = %@ ",stringAddress);    

}

NSString *stringAddress; is declared else where

markhunte
I like this answer, but when I use the code I get a different output from what whatismyipaddress.com gives me (although they are both dotted quads). The reason why I don't understand the difference is definitely due to my ignorance on the subject. I guess this is one of those questions where there is not one simple answer :)
Eric Brotto
It get you private IP address on you network. whatismyipaddress.com will be getting you public Ip address. The one seen from the internet.See my new answer below..
markhunte
A: 

My first Answer is to supply the Private IP address assigned to the Machine on private network from say your router.

If you want to see the public IP, which is the one facing the internet. Normally assigned by your service provider. You may want to look at the answer by Jim Dovey --> here

I tested it and it worked well, but read the rest of the comments and answers which point to ambiguities in trying to get a public IP.

markhunte
Mark, thanks for the explanation. The main problem with Jim Dovey's answer is that it uses PortMapper which only runs on 10.5 and newer (check link to docs). The app I'm working on needs to be able to run on 10.4. If you have any suggestions, I'm all ears ;)http://developer.apple.com/mac/library/samplecode/PortMapper/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007879-Intro-DontLinkElementID_2
Eric Brotto
+1  A: 

Hi Eric,

The only thing I can think of is to use something like "http://www.dyndns.org/cgi-bin/check_ip.cgi" others may have a better way.

This is an example,(i.e a quick cobbled together code)

NSUInteger  an_Integer;
NSArray * ipItemsArray;
NSString *externalIP;

NSURL *iPURL = [NSURL URLWithString:@"http://www.dyndns.org/cgi-bin/check_ip.cgi"];

if (iPURL) {
    NSError *error = nil;
    NSString *theIpHtml = [NSString stringWithContentsOfURL:iPURL 
                                                  encoding:NSUTF8StringEncoding 
                                                     error:&error];
    if (!error) {
                NSScanner *theScanner;
        NSString *text = nil;

        theScanner = [NSScanner scannerWithString:theIpHtml];

        while ([theScanner isAtEnd] == NO) {

                // find start of tag
            [theScanner scanUpToString:@"<" intoString:NULL] ; 

                // find end of tag
            [theScanner scanUpToString:@">" intoString:&text] ;

                // replace the found tag with a space
                //(you can filter multi-spaces out later if you wish)
            theIpHtml = [theIpHtml stringByReplacingOccurrencesOfString:
                    [ NSString stringWithFormat:@"%@>", text]
                                                   withString:@" "] ;
            ipItemsArray =[theIpHtml  componentsSeparatedByString:@" "];
            an_Integer=[ipItemsArray indexOfObject:@"Address:"];

                externalIP =[ipItemsArray objectAtIndex:  ++an_Integer];



        } 


            NSLog(@"%@",externalIP);
    } else {
        NSLog(@"Oops... g %d, %@", 
              [error code], 
              [error localizedDescription]);
    }
}




[pool drain];
return 0;

}

markhunte
@Markhunte. Wow! Thanks so much. I just cut and past the code and worked fine. Well done!
Eric Brotto