关于iOS配置ipv6和ipv4地址不同时的处理办法
来源:互联网 发布:初中优化测试卷答案 编辑:程序博客网 时间:2024/06/05 17:51
当ipv6和ipv4地址不同时的处理:
-(void)getHost{if ([DeviceInfo isIpv6]) { return hostIpv6; } return hostIpv4;}-(void)getBaseUrl{ if ([DeviceInfo isIpv6]) { return baseUrlIpv6; } return baseUrlIpv4;}
具体的DeviceInfo类如下
DeviceInfo.h
#import <Foundation/Foundation.h>@interface DeviceInfo : NSObject+ (NSString *) OpenUDID;+ (BOOL)isIpv6;+ (NSString *)getIPAddress:(BOOL)preferIPv4;@end
DeviceInfo.m
#import "YCX_DeviceInfo.h"#import <AssetsLibrary/AssetsLibrary.h>#import <MobileCoreServices/MobileCoreServices.h>#import "SvUDIDTools.h"#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"@implementation DeviceInfo+ (BOOL)isIpv6{ NSString *ipv6 = [self getIPAddress:NO]; NSInteger count = [ipv6 countOccurencesOfString:@":"]; if (count >= 6) { return YES; } return NO;}+ (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]; __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;}+ (NSString *) OpenUDID{ return [[UIDevice currentDevice].identifierForVendor UUIDString];}
使用到的SvUDIDTools类方法设置如下:
#import <Foundation/Foundation.h>@interface SvUDIDTools : NSObject/* * @brief obtain Unique Device Identity */+ (NSString*)UDID;@end#import "SvUDIDTools.h"#import <Security/Security.h>#include <sys/socket.h>#include <sys/sysctl.h>#include <net/if.h>#include <net/if_dl.h>// replace the identity with your company's domainstatic const char kKeychainUDIDItemIdentifier[] = "UUID";static const char kKeyChainUDIDAccessGroup[] = "请设置你自己的";@implementation SvUDIDTools+ (NSString*)UDID{ NSString *udid = [SvUDIDTools getUDIDFromKeyChain]; if (!udid) { NSString *sysVersion = [UIDevice currentDevice].systemVersion; CGFloat version = [sysVersion floatValue]; if (version >= 7.0) { udid = [SvUDIDTools _UDID_iOS7]; } else if (version >= 2.0) { udid = [SvUDIDTools _UDID_iOS6]; } [SvUDIDTools settUDIDToKeyChain:udid]; } return udid;}/* * iOS 6.0 * use wifi's mac address */+ (NSString*)_UDID_iOS6{ return [SvUDIDTools getMacAddress];}/* * iOS 7.0 * Starting from iOS 7, the system always returns the value 02:00:00:00:00:00 * when you ask for the MAC address on any device. * use identifierForVendor + keyChain * make sure UDID consistency atfer app delete and reinstall */+ (NSString*)_UDID_iOS7{ return [[UIDevice currentDevice].identifierForVendor UUIDString];}#pragma mark -#pragma mark Helper Method for Get Mac Address// from http://stackoverflow.com/questions/677530/how-can-i-programmatically-get-the-mac-address-of-an-iphone+ (NSString *)getMacAddress{ int mgmtInfoBase[6]; char *msgBuffer = NULL; size_t length; unsigned char macAddress[6]; struct if_msghdr *interfaceMsgStruct; struct sockaddr_dl *socketStruct; NSString *errorFlag = nil; // Setup the management Information Base (mib) mgmtInfoBase[0] = CTL_NET; // Request network subsystem mgmtInfoBase[1] = AF_ROUTE; // Routing table info mgmtInfoBase[2] = 0; mgmtInfoBase[3] = AF_LINK; // Request link layer information mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces // With all configured interfaces requested, get handle index if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0) errorFlag = @"if_nametoindex failure"; else { // Get the size of the data available (store in len) if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0) errorFlag = @"sysctl mgmtInfoBase failure"; else { // Alloc memory based on above call if ((msgBuffer = malloc(length)) == NULL) errorFlag = @"buffer allocation failure"; else { // Get system information, store in buffer if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0) errorFlag = @"sysctl msgBuffer failure"; } } } // Befor going any further... if (errorFlag != NULL) { NSLog(@"Error: %@", errorFlag); if (msgBuffer) { free(msgBuffer); } return errorFlag; } // Map msgbuffer to interface message structure interfaceMsgStruct = (struct if_msghdr *) msgBuffer; // Map to link-level socket structure socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1); // Copy link layer address data in socket structure to an array memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6); // Read from char array into a string object, into traditional Mac address format NSString *macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]]; NSLog(@"Mac Address: %@", macAddressString); // Release the buffer memory free(msgBuffer); return macAddressString;}#pragma mark -#pragma mark Helper Method for make identityForVendor consistency+ (NSString*)getUDIDFromKeyChain{ NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init]; [dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass]; // set Attr Description for query [dictForQuery setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:(NSString *)kSecAttrDescription]; // set Attr Identity for query NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier length:strlen(kKeychainUDIDItemIdentifier)]; [dictForQuery setObject:keychainItemID forKey:(id)kSecAttrGeneric]; // The keychain access group attribute determines if this item can be shared // amongst multiple apps whose code signing entitlements contain the same keychain access group. NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup]; if (accessGroup != nil) {#if TARGET_IPHONE_SIMULATOR // Ignore the access group if running on the iPhone simulator. // // Apps that are built for the simulator aren't signed, so there's no keychain access group // for the simulator to check. This means that all apps can see all keychain items when run // on the simulator. // // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the // simulator will return -25243 (errSecNoAccessForItem).#else [dictForQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];#endif } [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive]; [dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; OSStatus queryErr = noErr; NSData *udidValue = nil; NSString *udid = nil; CFTypeRef typeRef = (__bridge CFTypeRef)udidValue; queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeRef); NSMutableDictionary *dict = nil; [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; CFTypeRef typeDict = (__bridge CFTypeRef)dict; queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeDict); if (queryErr == errSecItemNotFound) { NSLog(@"KeyChain Item: %@ not found!!!", [NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]); } else if (queryErr != errSecSuccess) { NSLog(@"KeyChain Item query Error!!! Error code:%d", queryErr); } if (queryErr == errSecSuccess) { NSLog(@"KeyChain Item: %@", udidValue); if (udidValue) { udid = [NSString stringWithUTF8String:udidValue.bytes]; } } return udid;}+ (BOOL)settUDIDToKeyChain:(NSString*)udid{ NSMutableDictionary *dictForAdd = [[NSMutableDictionary alloc] init]; [dictForAdd setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass]; [dictForAdd setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:(NSString *)kSecAttrDescription]; [dictForAdd setValue:@"UUID" forKey:(id)kSecAttrGeneric]; // Default attributes for keychain item. [dictForAdd setObject:@"" forKey:(id)kSecAttrAccount]; [dictForAdd setObject:@"" forKey:(id)kSecAttrLabel]; // The keychain access group attribute determines if this item can be shared // amongst multiple apps whose code signing entitlements contain the same keychain access group. NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup]; if (accessGroup != nil) {#if TARGET_IPHONE_SIMULATOR // Ignore the access group if running on the iPhone simulator. // // Apps that are built for the simulator aren't signed, so there's no keychain access group // for the simulator to check. This means that all apps can see all keychain items when run // on the simulator. // // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the // simulator will return -25243 (errSecNoAccessForItem).#else [dictForAdd setObject:accessGroup forKey:(id)kSecAttrAccessGroup];#endif } const char *udidStr = [udid UTF8String]; NSData *keyChainItemValue = [NSData dataWithBytes:udidStr length:strlen(udidStr)]; [dictForAdd setValue:keyChainItemValue forKey:(id)kSecValueData]; OSStatus writeErr = noErr; if ([SvUDIDTools getUDIDFromKeyChain]) { // there is item in keychain [SvUDIDTools updateUDIDInKeyChain:udid]; return YES; } else { // add item to keychain writeErr = SecItemAdd((CFDictionaryRef)dictForAdd, NULL); if (writeErr != errSecSuccess) { NSLog(@"Add KeyChain Item Error!!! Error Code:%d", writeErr); return NO; } else { NSLog(@"Add KeyChain Item Success!!!"); return YES; } } return NO;}+ (BOOL)removeUDIDFromKeyChain{ NSMutableDictionary *dictToDelete = [[NSMutableDictionary alloc] init]; [dictToDelete setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass]; NSData *keyChainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier length:strlen(kKeychainUDIDItemIdentifier)]; [dictToDelete setValue:keyChainItemID forKey:(id)kSecAttrGeneric]; OSStatus deleteErr = noErr; deleteErr = SecItemDelete((CFDictionaryRef)dictToDelete); if (deleteErr != errSecSuccess) { NSLog(@"delete UUID from KeyChain Error!!! Error code:%d", deleteErr); return NO; } else { NSLog(@"delete success!!!"); } return YES;}+ (BOOL)updateUDIDInKeyChain:(NSString*)newUDID{ NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init]; [dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass]; NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier length:strlen(kKeychainUDIDItemIdentifier)]; [dictForQuery setValue:keychainItemID forKey:(id)kSecAttrGeneric]; [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive]; [dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; NSDictionary *queryResult = nil; CFTypeRef typeQuery = (__bridge CFTypeRef)queryResult; SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeQuery); if (queryResult) { NSMutableDictionary *dictForUpdate = [[NSMutableDictionary alloc] init]; [dictForUpdate setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:(NSString *)kSecAttrDescription]; [dictForUpdate setValue:keychainItemID forKey:(id)kSecAttrGeneric]; const char *udidStr = [newUDID UTF8String]; NSData *keyChainItemValue = [NSData dataWithBytes:udidStr length:strlen(udidStr)]; [dictForUpdate setValue:keyChainItemValue forKey:(id)kSecValueData]; OSStatus updateErr = noErr; // First we need the attributes from the Keychain. NSMutableDictionary *updateItem = [NSMutableDictionary dictionaryWithDictionary:queryResult]; // Second we need to add the appropriate search key/values. // set kSecClass is Very important [updateItem setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; updateErr = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)dictForUpdate); if (updateErr != errSecSuccess) { NSLog(@"Update KeyChain Item Error!!! Error Code:%d", updateErr); return NO; } else { NSLog(@"Update KeyChain Item Success!!!"); return YES; } } return NO;}
阅读全文
0 0
- 关于iOS配置ipv6和ipv4地址不同时的处理办法
- IPv4地址和IPv6地址
- IP 地址的划分 IPV4 IPV6的配置
- iOS ipv4和ipv6转换
- 查询IPv4和IPv6归属地址的工具
- win7下ipv4和ipv6多地址访问的问题
- 检查IPv4和IPv6地址的正则表达式
- 检查IPv4和IPv6地址的正则表达式
- iOS测试:IPV4下搭建IPV6网络 测试app在IPV4和IPV6下的兼容性
- 4.IPv4和IPv6地址长度
- ipv4和ipv6的区别
- IPv4和IPv6的区别
- IPv4和IPv6的区别
- ipv4和ipv6的区别
- IPV4和IPV6的区别
- ipv4和ipv6的区别
- ipv4和ipv6的区别
- ipv4和ipv6的区别
- 环境迁移到新的linux环境
- Redis安装
- 高级权限 suid,sgid,sticky
- html5知识点:CSS3新增选择器
- [POJ](3669)Meteor Shower ---- bfs+预处理
- 关于iOS配置ipv6和ipv4地址不同时的处理办法
- 为何红黄蓝一边在被做空,一边在逆势上涨?
- JVM(1) : Java类的加载机制
- __setup 在内核中的作用
- glActiveTexture glBindTexture
- VBA批量转换:docx转pdf、doc、rtf、txt以及doc转docx
- linux下安装Go环境
- serilizejson 直接用
- Java中的23种设计模式