Created
May 14, 2016 08:51
-
-
Save lbj96347/ec3cd3349b0266a32d18455c5128fe74 to your computer and use it in GitHub Desktop.
iOS/tvOS get IP Address from current network ( via Cellular network )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <ifaddrs.h> | |
#import <arpa/inet.h> | |
#import <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" | |
#pragma mark - Get Current Network IP Address | |
+ (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, BOOLBOOL *stop) | |
{ | |
address = addresses[key]; | |
//Get IP address format | |
if([self isValidatIP:address]) *stop = YES; | |
} ]; | |
return address ? address : @"0.0.0.0"; | |
} | |
+ (BOOL)isValidatIP:(NSString *)ipAddress { | |
if (ipAddress.length == 0) { | |
return NO; | |
} | |
NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." | |
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." | |
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." | |
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; | |
NSError *error; | |
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error]; | |
if (regex != nil) { | |
NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])]; | |
if (firstMatch) { | |
NSRange resultRange = [firstMatch rangeAtIndex:0]; | |
NSString *result=[ipAddress substringWithRange:resultRange]; | |
//print resut | |
NSLog(@"%@",result); | |
return YES; | |
} | |
} | |
return NO; | |
} | |
+ (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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment