当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];
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) ) {
continue;
}
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];
}
}
}
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
+ (NSString *) OpenUDID{
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
#import <Foundation/Foundation.h>
@interface SvUDIDTools : NSObject
+ (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>
static 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;
}
+ (NSString*)_UDID_iOS6
{
return [SvUDIDTools getMacAddress];
}
+ (NSString*)_UDID_iOS7
{
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
#pragma mark -
#pragma mark Helper Method for Get Mac Address
+ (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;
mgmtInfoBase[0] = CTL_NET;
mgmtInfoBase[1] = AF_ROUTE;
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK;
mgmtInfoBase[4] = NET_RT_IFLIST;
if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
errorFlag = @"if_nametoindex failure";
else
{
if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = @"sysctl mgmtInfoBase failure";
else
{
if ((msgBuffer = malloc(length)) == NULL)
errorFlag = @"buffer allocation failure";
else
{
if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
errorFlag = @"sysctl msgBuffer failure";
}
}
}
if (errorFlag != NULL)
{
NSLog(@"Error: %@", errorFlag);
if (msgBuffer) {
free(msgBuffer);
}
return errorFlag;
}
interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);
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);
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];
[dictForQuery setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]
forKey:(NSString *)kSecAttrDescription];
NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier
length:strlen(kKeychainUDIDItemIdentifier)];
[dictForQuery setObject:keychainItemID forKey:(id)kSecAttrGeneric];
NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup];
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
#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];
[dictForAdd setObject:@"" forKey:(id)kSecAttrAccount];
[dictForAdd setObject:@"" forKey:(id)kSecAttrLabel];
NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup];
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
#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]) {
[SvUDIDTools updateUDIDInKeyChain:udid];
return YES;
}
else {
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;
NSMutableDictionary *updateItem = [NSMutableDictionary dictionaryWithDictionary:queryResult];
[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;
}