IP Address? - Cocoa

17,226

Solution 1

You can get IP address through two ways:

1- if you want to get the local ip address on the current used netwrok, you can use the following method to retrive it:

-(NSString *)getIPAddress
{
    NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;

    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0)
    {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while(temp_addr != NULL)
        {
            if(temp_addr->ifa_addr->sa_family == AF_INET)
            {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
            }
            temp_addr = temp_addr->ifa_next;
        }
    }

    // Free memory
    freeifaddrs(interfaces);
    return address;
}

2- if you want to get the external IP address then you need to use the following method:

-(NSString*)getIP
{
    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]);
        }
    }
    return externalIP;
}

Solution 2

For determining the IP address, I found this.

As for making it into a Cocoa app, add an NSTextField (label) to your main window in Interface Builder, put in a button, add in an application controller (a subclass of NSObject that you make), put in the outlet and the action, do the proper connenctions, and in the "get IP" method, put in that code and set the value for the label's stringValue.

You can use [[NSHost currentHost] address], but it won't always display what you like. On my system, for example, it gives my IPv6 address.

EDIT: On my system, [[[NSHost currentHost] addresses] objectAtIndex:0] has my IPv4 address.

Solution 3

[[NSHost currentHost] addresses] will get you an array of IPs. Read the documentation for NSHost.

As for displaying that in a GUI, I recommend getting Aaron Hillegass' book Cocoa Programming for Mac OS X, or any Cocoa beginners book should teach that.

Solution 4

I just wrote this, may need some work but seems to work well on my machine...

- (NSString *)getLocalIPAddress
{
    NSArray *ipAddresses = [[NSHost currentHost] addresses];
    NSArray *sortedIPAddresses = [ipAddresses sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    numberFormatter.allowsFloats = NO;

    for (NSString *potentialIPAddress in sortedIPAddresses)
    {
        if ([potentialIPAddress isEqualToString:@"127.0.0.1"]) {
            continue;
        }

        NSArray *ipParts = [potentialIPAddress componentsSeparatedByString:@"."];

        BOOL isMatch = YES;

        for (NSString *ipPart in ipParts) {
            if (![numberFormatter numberFromString:ipPart]) {
                isMatch = NO;
                break;
            }
        }
        if (isMatch) {
            return potentialIPAddress;
        }
    }

    // No IP found
    return @"?.?.?.?";
}

Solution 5

We can use hostWithName: method with current host name. This will return only single local IPv4 and IPv6 IP, which we can filter easily.

We can get the current system host name using [[NSHost currentHost] name].

+(NSString *)getLocalIPAddress{
    NSArray *ipAddresses = [[NSHost hostWithName:[[NSHost currentHost] name]] addresses];
    for (NSString *ipAddress in ipAddresses) {
        if ([ipAddress componentsSeparatedByString:@"."].count == 4) {
            return ipAddress;
        }
    }
    return @"Not Connected.";
}

So, this will solve all the problems mentions in comments of other answers. Also, this significantly work more faster than other solution mention here.

Share:
17,226
lab12
Author by

lab12

Updated on June 04, 2022

Comments

  • lab12
    lab12 almost 2 years

    How would I make a GUI program that displays your Ip address with a click of a button? Please, no difficult explanations, I just started Cocoa not long ago.

    Thanks,

    Kevin