iOS 唯一識別碼擷取

來源:互聯網
上載者:User
////  UDIDTools.h//  UDIDTools////  Created by Lovell on 9/9/16.//  Copyright © 2016 Lovell. All rights reserved.//#import <Foundation/Foundation.h>@interface UDIDTools : NSObject/* * @brief obtain Unique Device Identity */+ (NSString*)UDID;@end


////  UDIDTools.m//  UDIDTools////  Created by Lovell on 9/9/16.//  Copyright © 2016 Lovell. All rights reserved.//#import "UDIDTools.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[] = "YOURAPPID.com.cnblogs.smileEvday";@implementation UDIDTools+ (NSString*)UDID{    NSString *udid = [UDIDTools getUDIDFromKeyChain];    if (!udid) {        NSString *sysVersion = [UIDevice currentDevice].systemVersion;        CGFloat version = [sysVersion floatValue];        if (version >= 7.0) {            udid = [UDIDTools _UDID_iOS7];        }        else if (version >= 2.0) {            udid = [UDIDTools _UDID_iOS6];        }        [UDIDTools settUDIDToKeyChain:udid];    }    return udid;}/* * iOS 6.0 * use wifi's mac address */+ (NSString*)_UDID_iOS6{    return [UDIDTools 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: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;    queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&udidValue);    NSMutableDictionary *dict = nil;    [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];    queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&dict);    if (queryErr == errSecItemNotFound) {        NSLog(@"KeyChain Item: %@ not found!!!", [NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]);    }    else if (queryErr != errSecSuccess) {        NSLog(@"KeyChain Item query Error!!! Error code:%ld", queryErr);    }    if (queryErr == errSecSuccess) {        NSLog(@"KeyChain Item: %@", udidValue);        if (udidValue) {            udid = [NSString stringWithUTF8String:udidValue.bytes];            [udidValue release];        }        [dict release];    }    [dictForQuery release];    return udid;}+ (BOOL)settUDIDToKeyChain:(NSString*)udid{    NSMutableDictionary *dictForAdd = [[NSMutableDictionary alloc] init];    [dictForAdd setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];    [dictForAdd setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey: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 ([UDIDTools getUDIDFromKeyChain]) {        // there is item in keychain        [UDIDTools updateUDIDInKeyChain:udid];        [dictForAdd release];        return YES;    }    else {          // add item to keychain        writeErr = SecItemAdd((CFDictionaryRef)dictForAdd, NULL);        if (writeErr != errSecSuccess) {            NSLog(@"Add KeyChain Item Error!!! Error Code:%ld", writeErr);            [dictForAdd release];            return NO;        }        else {            NSLog(@"Add KeyChain Item Success!!!");            [dictForAdd release];            return YES;        }    }    [dictForAdd release];    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:%ld", deleteErr);        [dictToDelete release];        return NO;    }    else {        NSLog(@"delete success!!!");    }    [dictToDelete release];    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;    SecItemCopyMatching((CFDictionaryRef)dictForQuery
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.