iOS-iPhone-如何获取WiFi、VPN、移动(蜂窝)iP地址(ipv4/ipv6)-获取当前设备的iP地址的方法!- 源代码在最下面
首先很感谢你看到这片文章,浪费你的时间了! 关于获取iOS iP地址的方法,网上搜索基本上是一模一样的。
只需要知道一点-通过iOS设备本身并不能获取到真正的广域网iP地址-网上所有copy stackoverflow.com 里的代码都不能解决这个问题,就目前我搜索到的来说,
需要知道的是,iOS 获取的Wi-Fi iP地址是局域网的比如 168.192.1.1 - iOS 获取 VPN的地址是可以获取到的 - iOS获取移动网络也就是蜂窝数据获取到的只是运营商的iP地址,比如在国iPv4已经枯竭的情况下,运营商分配给广域网iP地址基本上是不可能的
-- 当前这种获取iP地址的方法跟在Mac终端中输入ifconfig命令或者是Windows命令行中输入ipconfig 获取到的信息一样-所以这并不是 一个好的解决方法-- PS:也许是我使用的方法不对
所以,你需要换一种方法-去获取实际的广域网地址-比如在百度里搜索iP会有第三方显示你的广域网地址-可以找一下-因为我项目有需要才理解的, 只能应该会写 有哪些第三方API会返回当前广域网地址!
Xcode控制台打印和Mac终端打印对比
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"%@",[self getIPAddresses]);
}
- (NSString *)getIPAddress:(BOOL)preferIPv4
{
NSArray *searchArray = preferIPv4 ?
@[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
@[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
NSDictionary *addresses = [self getIPAddresses];
NSLog(@"addresses: %@", addresses);
__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString key, NSUInteger idx, BOOL stop)
{
address = addresses[key];
if(address) *stop = YES;
} ];
return address ? address : @"0.0.0.0";
}
- (NSDictionary *)getIPAddresses
{
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
// Loop through linked list of interfaces
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) / || (interface->ifa_flags & IFF_LOOPBACK) / ) {
continue; // deeply nested code harder to read
}
const struct sockaddr_in addr = (const struct sockaddr_in)interface->ifa_addr;
char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) {
if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 addr6 = (const struct sockaddr_in6)interface->ifa_addr;
if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
type = IP_ADDR_IPv6;
}
}
if(type) {
NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free memory
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
@end