在我的应用程序中,我需要获取一个NSString对象值,该值等于用户public / internet ip地址的值。我试图解决这个问题,但两者都返回本地IP地址而不是公开。以下是我的两种方法。一个更精确,并始终返回数组中的正确项。另一个没有。 (因为只需选择一个随机索引)......
- (NSString *)getPublicIP {
NSHost *publicIP = [[[NSHost currentHost] addresses] objectAtIndex:0];
return publicIP;
}
其他更精确:(但未获得公共IP)
//start get ip
- (NSString *)getIPWithNSHost {
NSArray *addresses = [[NSHost currentHost] addresses];
NSString *stringAddress;
for (NSString *anAddress in addresses) {
if (![anAddress hasPrefix:@"127"] && [[anAddress componentsSeparatedByString:@"."] count] == 4) {
stringAddress = anAddress;
break;
}
else {
stringAddress = @"IPv4 address not available" ;
}
//NSLog(stringAddress);
}
NSLog (@"getIPWithNSHost: stringAddress = %@ ",stringAddress);
stringAddress = (@"getIPWithNSHost: stringAddress = %@ ",stringAddress);
return stringAddress;
}
无论哪种方式,我只需要一种方法来获取外部/公共/互联网IP地址。 (只是为了澄清外部/公共/互联网IP是可以从whatsmyip.org检索的)
答案 0 :(得分:5)
这是iOS友好版的joshbillions答案:
+(void)getPublicIP:(void(^)(NSString *))block {
NSURL *url = [NSURL URLWithString:@"http://checkip.dyndns.org"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[[NSURLSession sharedSession]dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// consider handling error
} else {
NSString *html = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];
NSString *ipAddr = [[html componentsSeparatedByCharactersInSet:numbers.invertedSet]componentsJoinedByString:@""];
if (block) {
block(ipAddr);
}
}
}]resume];
}
答案 1 :(得分:4)
它像罪一样丑陋,但这对我有用:
NSTask *task = [[[NSTask alloc] init] autorelease];
[task setLaunchPath:@"/usr/bin/curl"];
[task setArguments:[NSArray arrayWithObjects:@"-s",@"http://checkip.dyndns.org", nil]];
NSPipe *outputPipe = [NSPipe pipe];
[task setStandardOutput:outputPipe];
[task launch];
NSData *curlData = [[outputPipe fileHandleForReading] readDataToEndOfFile];
NSString *curlString = [[NSString alloc] initWithData:curlData encoding:NSASCIIStringEncoding];
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:curlString.length];
NSScanner *scanner = [NSScanner scannerWithString:curlString];
NSCharacterSet *numbers = [NSCharacterSet
characterSetWithCharactersInString:@"0123456789."];
while ([scanner isAtEnd] == NO) {
NSString *buffer;
if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
[strippedString appendString:buffer];
} else {
[scanner setScanLocation:([scanner scanLocation] + 1)];
}
}
NSLog(@"IP Address: %@", strippedString);
答案 2 :(得分:3)
由于NAT,您无法指望您的计算机在其任何接口上提供外部IP 获取外部IP的唯一半可靠方法是询问互联网上的机器(如您提到的whatsmyip.org),该机器在通过任何本地路由器/防火墙后会看到您的IP流量。
要求在IP电话中使用此信息的某种标准方法是使用the STUN protocol。
答案 3 :(得分:3)
STUN协议是获取公共IP和端口的一个很好的解决方案 - 检查iOS {ST}的STUN协议实现
答案 4 :(得分:1)
get
为前缀,除非您通过引用传递参数... 但这不能回答你的问题。
回答这个问题需要一个问题;你想做什么?
除了最有限的情况外,您设备的IP地址很可能毫无意义。
如果在蜂窝网络上,它可能不可路由
如果在任何类型的消费者互联网连接上,它可能在某种NAT路由器后面
即使在极少数情况下获得可路由地址,您的设备也可能位于防火墙后面
除了最罕见的[通常非常行政密集的案例]之外,您应该使用Bonjour进行非IP中心服务发现或类似Game Center的事情来进行人与人之间的匹配(或其他特定于域的匹配代理)
答案 5 :(得分:0)
我使用ifconfig.me,这是一个很棒的网站,它使用多种输出格式(包括JSON)来获取您的公共IP地址和其他信息。
- (void)myPublicIPAddressWithCompletitionBlock:(void (^)(NSString *))completitionBlock {
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
[sessionConfiguration setHTTPAdditionalHeaders:@{@"Content-Type": @"application/json"}];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:@"https://ifconfig.me/all.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
NSError *jsonError = nil;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (!jsonError) {
if (jsonResponse[@"ip_addr"]) {
if (completitionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completitionBlock(jsonResponse[@"ip_addr"]);
});
}
return ;
}
}
}
if (completitionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completitionBlock(@"none");
});
}
}];
[task resume];
}