標籤:
寫在前面
最近做關於網路介面部分,有時候為了介面安全,需要在請求介面的時候,跟後服務端約好,每一個介面需要傳遞特定的簽名資料,關於簽名演算法,服務端和移動端保持一致;當然這不是主要的,主要的是,如何擷取裝置的ip地址;廢話不多說,直接上代碼;
小tips:
Mac 終端擷取電腦ip: ifconfig | grep "inet " | grep -v 127.0.0.1
主要參考:stackoverflow
1 http://stackoverflow.com/questions/7072989/iphone-ipad-osx-how-to-get-my-ip-address-programmatically/10803584#10803584
1 匯入標頭檔 2 #include <ifaddrs.h> 3 #include <arpa/inet.h> 4 #include <net/if.h> 5 6 #define IOS_CELLULAR @"pdp_ip0" 7 #define IOS_WIFI @"en0" 8 #define IOS_VPN @"utun0" 9 #define IP_ADDR_IPv4 @"ipv4"10 #define IP_ADDR_IPv6 @"ipv6"11 12 13 14 #pragma mark - 擷取ip地址15 + (NSString *)getIPAddress:(BOOL)preferIPv4{16 NSArray *searchArray = preferIPv4 ?17 @[ 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 ] :18 @[ 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 ] ;19 20 NSDictionary *addresses = [self getIPAddresses];21 22 // NSLog(@"addresses: %@", addresses);23 24 __block NSString *address;25 [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)26 {27 address = addresses[key];28 //篩選出IP地址格式29 if([self isValidatIP:address]) *stop = YES;30 } ];31 return address ? address : @"0.0.0.0";32 33 }34 35 + (BOOL)isValidatIP:(NSString *)ipAddress {36 if (ipAddress.length == 0) {37 return NO;38 }39 NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."40 "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."41 "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."42 "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";43 44 NSError *error;45 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error];46 47 if (regex != nil) {48 NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])];49 50 if (firstMatch) {51 NSRange resultRange = [firstMatch rangeAtIndex:0];52 NSString *result=[ipAddress substringWithRange:resultRange];53 //輸出結果54 // NSLog(@"%@",result);55 return YES;56 }57 }58 return NO;59 }60 61 + (NSDictionary *)getIPAddresses62 {63 NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];64 65 // retrieve the current interfaces - returns 0 on success66 struct ifaddrs *interfaces;67 if(!getifaddrs(&interfaces)) {68 // Loop through linked list of interfaces69 struct ifaddrs *interface;70 for(interface=interfaces; interface; interface=interface->ifa_next) {71 if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {72 continue; // deeply nested code harder to read73 }74 const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;75 char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];76 if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {77 NSString *name = [NSString stringWithUTF8String:interface->ifa_name];78 NSString *type;79 if(addr->sin_family == AF_INET) {80 if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {81 type = IP_ADDR_IPv4;82 }83 } else {84 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;85 if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {86 type = IP_ADDR_IPv6;87 }88 }89 if(type) {90 NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];91 addresses[key] = [NSString stringWithUTF8String:addrBuf];92 }93 }94 }95 // Free memory96 freeifaddrs(interfaces);97 }98 return [addresses count] ? addresses : nil;99 }
親測可用,萬能的stackoverflow,非常感謝!
擷取iOS裝置ip地址