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终端打印对比

2018最新-iOS-iPhone-如何获取WiFi、VPN、移动(蜂窝)iP地址(ipv4/ipv6)-获取当前设备的iP地址的方法!
2018最新-iOS-iPhone-如何获取WiFi、VPN、移动(蜂窝)iP地址(ipv4/ipv6)-获取当前设备的iP地址的方法!


#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