How to get the public IP address of the device

2019-02-06 17:34发布

I found this sample code to get all local IP addresses, but I don't find an easy solution to get the public IP.

A legacy class from Apple allowed to do that ... but it's legacy ...

7条回答
够拽才男人
2楼-- · 2019-02-06 17:52

I find both Andrei and Tarek's answers helpful. Both are relying a web URL to query the "public IP" of the iOS/OS X device.

However, there is an issue with this approach in some part of the world where URL such as "http://www.dyndns.org/cgi-bin/check_ip.cgi" is censored as in andrei's answer:

NSString *theIpHtml = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.dyndns.org/cgi-bin/check_ip.cgi"]
encoding:NSUTF8StringEncoding
                                                  error:&error];

In this case, we will need to use an "uncensored" URL within the region such as http://1212.ip138.com/ic.asp

Note that the web URL could use a different HTML and encoding than what Andrei's answer could parse - in the URL above, some very gentle changes can fix it by using kCFStringEncodingGB_18030_2000 for http://1212.ip138.com/ic.asp

NSURL* externalIPCheckURL = [NSURL URLWithString: @"http://1212.ip138.com/ic.asp"];
encoding:NSUTF8StringEncoding error:nil];

NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);

NSString *theIpHtml = [NSString stringWithContentsOfURL: externalIPCheckURL
                                                   encoding: encoding
                                                      error: &error];
查看更多
男人必须洒脱
3楼-- · 2019-02-06 17:53

I use ipify and with no complaints.

NSURL *url = [NSURL URLWithString:@"https://api.ipify.org/"];
NSString *ipAddress = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSLog(@"My public IP address is: %@", ipAddress);
查看更多
做个烂人
4楼-- · 2019-02-06 17:55

I have used ALSystemUtilities in the past. You basically have to make a call externally to find this out.

+ (NSString *)externalIPAddress {
    // Check if we have an internet connection then try to get the External IP Address
    if (![self connectedViaWiFi] && ![self connectedVia3G]) {
        // Not connected to anything, return nil
        return nil;
    }

    // Get the external IP Address based on dynsns.org
    NSError *error = nil;
    NSString *theIpHtml = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.dyndns.org/cgi-bin/check_ip.cgi"]
                                                   encoding:NSUTF8StringEncoding
                                                      error:&error];
    if (!error) {
        NSUInteger  an_Integer;
        NSArray *ipItemsArray;
        NSString *externalIP;
        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];
        }
        // Check that you get something back
        if (externalIP == nil || externalIP.length <= 0) {
            // Error, no address found
            return nil;
        }
        // Return External IP
        return externalIP;
    } else {
        // Error, no address found
        return nil;
    }
}

Source from ALSystemUtilities

查看更多
Summer. ? 凉城
5楼-- · 2019-02-06 18:00

You have to query an external server to find out the public IP. Either set up your own server (1 line of php code) or use one of the many available ones which return the IP as plain text or json upon http query. Like for example http://myipdoc.com/ip.php .

查看更多
成全新的幸福
6楼-- · 2019-02-06 18:07

It's as simple as this:

NSString *publicIP = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://icanhazip.com/"] encoding:NSUTF8StringEncoding error:nil];
publicIP = [publicIP stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; // IP comes with a newline for some reason
查看更多
走好不送
7楼-- · 2019-02-06 18:18

For those of us using Swift, here's my translation of Andrei's answer with the addition of NSURLSession to run it in the background. To check the network, I use Reachability.swift. Also, remember to add dyndns.org to NSExceptionDomains for NSAppTransportSecurity in your info.plist.

var ipAddress:String?
func getIPAddress() {

    if reachability!.isReachable() == false {
        return
    }

    guard let ipServiceURL = NSURL(string: "http://www.dyndns.org/cgi-bin/check_ip.cgi") else {
        return
    }

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithURL(ipServiceURL, completionHandler: {(data, response, error) -> Void in
        if error != nil {
            print(error)
            return
        }

        let ipHTML = NSString(data: data!, encoding: NSUTF8StringEncoding) as? String

        self.ipAddress = self.scanForIPAddress(ipHTML)

    })

    task.resume()
}

func scanForIPAddress(var ipHTML:String?) -> String? {

    if ipHTML == nil {
        return nil
    }

    var externalIPAddress:String?
    var index:Int?
    var ipItems:[String]?
    var text:NSString?

    let scanner = NSScanner(string: ipHTML!)

    while scanner.atEnd == false {
        scanner.scanUpToString("<", intoString: nil)

        scanner.scanUpToString(">", intoString: &text)

        ipHTML = ipHTML!.stringByReplacingOccurrencesOfString(String(text!) + ">", withString: " ")

        ipItems = ipHTML!.componentsSeparatedByString(" ")

        index = ipItems!.indexOf("Address:")
        externalIPAddress = ipItems![++index!]

    }

    if let ip = externalIPAddress {
        print("External IP Address: \(ip)")
    }

    return externalIPAddress

}
查看更多
登录 后发表回答