identifierForVendor and iOS6

后端 未结 5 554
别跟我提以往
别跟我提以往 2020-12-28 21:50

The identifierForVendor require iOS6, so if my app currently supporting iOS4 and therefore I can\'t use it since my updates should always meet my app\'s

相关标签:
5条回答
  • 2020-12-28 22:15

    You can use the following code

    if (NSClassFromString(@"ASIdentifierManager")) {
        return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];           
    } else {
        // return other identifier generated with OpenUDID or some custom method
    }
    

    You can get OpenUDID documentation here

    0 讨论(0)
  • 2020-12-28 22:18

    You don't need preprocessor macros for this, you should check if it response, like this:

    if ([[UIDevice currentDevice]respondsToSelector:@selector(identifierForVendor)]) {
        return [UIDevice currentDevice].identifierForVendor.UUIDString;
    }else{
        // return [UIDevice currentDevice]. uniqueIdentifier
        return [[UIDevice currentDevice] performSelector:@selector(uniqueIdentifier)];
    }
    
    0 讨论(0)
  • 2020-12-28 22:28

    It is always different. UUID includes timestamps, so every time you call this function, you will get a different (random) one. I have followed this approach in IDManager class, This is a collection from different solutions. KeyChainUtil is a wrapper to read from keychain. A similar keychain util is found in github.

    //  IDManager.m
    
    
    /*
     A replacement for deprecated uniqueIdentifier API. Apple restrict using this from 1st May, 2013.
    
     We have to consider,
        * iOS <6 have not the ASIIdentifer API
        * When the user upgrade from iOS < 6 to >6
            - Check if there is a UUID already stored in keychain. Then use that. 
                - In that case, this UUID is constant for whole device lifetime. Keychain item is not deleted with application deletion.
     */
    
    #import "IDManager.h"
    #import "KeychainUtils.h"
    #import "CommonUtil.h"
    
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
        #import <AdSupport/AdSupport.h>
    #endif
    
    #include <sys/socket.h> 
    #include <sys/sysctl.h>
    #include <net/if.h>
    #include <net/if_dl.h>
    
    
    
    /*  Apple confirmed this bug in their system in response to a Technical Support Incident request. They said that identifierForVendor and advertisingIdentifier sometimes returning all zeros can be seen both in development builds and apps downloaded over the air from the App Store. They have no work around and can't say when the problem will be fixed. */
    #define kBuggyASIID             @"00000000-0000-0000-0000-000000000000"
    
    
    #pragma mark 
    
    
    #pragma mark 
    
    @implementation IDManager
    
    + (NSString *) getUniqueID {
    
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
    
        if (NSClassFromString(@"ASIdentifierManager")) {
            NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
            if ([asiID compare:kBuggyASIID] == NSOrderedSame) {
                NSLog(@"Error: This device return buggy advertisingIdentifier.");
                return [IDManager getUniqueUUID];
            } else {
                return asiID;
            }
    
        } else {
    
    #endif
    
            return [IDManager getUniqueUUID];
    
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
        }
    #endif
    
    }
    
    + (NSString *) getUniqueUUID 
    {
        NSError * error;
        NSString * uuid = [KeychainUtils getPasswordForUsername:@"UserName" andServiceName:@"YourServiceName" error:&error];
        if (error) {
            NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
        if (!uuid) {
            DLog(@"No UUID found. Creating a new one.");
            uuid = [IDManager getUUID];
            uuid = [CommonUtil md5String:uuid]; // create md5 hash for security reason
            [KeychainUtils storeUsername:@"UserName" andPassword:uuid forServiceName:@"YourServiceName" updateExisting:YES error:&error];
            if (error) {
                NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
                return nil;
            }
        }
        return uuid;
    }
    
    + (NSString *) readUUIDFromKeyChain {
        NSError * error;
        NSString * uuid = [KeychainUtils getPasswordForUsername:@"UserName" andServiceName:@"YourServiceName" error:&error];
        if (error) {
            NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
        return uuid;
    }
    
    /* NSUUID is after iOS 6. So we are using CFUUID for compatibility with iOS 4.3 */
    + (NSString *)getUUID
    {
        CFUUIDRef theUUID = CFUUIDCreate(NULL);
        CFStringRef string = CFUUIDCreateString(NULL, theUUID);
        CFRelease(theUUID);
        return [(NSString *)string autorelease];
    }
    
    #pragma mark - MAC address
    
    /* THIS WILL NOT WORK IN iOS 7. IT WILL RETURN A CONSTANT MAC ADDRESS ALL THE TIME.
     SEE - https://developer.apple.com/news/?id=8222013a
     */
    
    // Return the local MAC address
    // Courtesy of FreeBSD hackers email list
    // Last fallback for unique identifier
    + (NSString *) getMACAddress
    {
        int                 mib[6];
        size_t              len;
        char                *buf;
        unsigned char       *ptr;
        struct if_msghdr    *ifm;
        struct sockaddr_dl  *sdl;
    
        mib[0] = CTL_NET;
        mib[1] = AF_ROUTE;
        mib[2] = 0;
        mib[3] = AF_LINK;
        mib[4] = NET_RT_IFLIST;
    
        if ((mib[5] = if_nametoindex("en0")) == 0) {
            printf("Error: if_nametoindex error\n");
            return NULL;
        }
    
        if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
            printf("Error: sysctl, take 1\n");
            return NULL;
        }
    
        if ((buf = malloc(len)) == NULL) {
            printf("Error: Memory allocation error\n");
            return NULL;
        }
    
        if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
            printf("Error: sysctl, take 2\n");
            free(buf); // Thanks, Remy "Psy" Demerest
            return NULL;
        }
    
        ifm = (struct if_msghdr *)buf;
        sdl = (struct sockaddr_dl *)(ifm + 1);
        ptr = (unsigned char *)LLADDR(sdl);
        NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
                               *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    
        free(buf);
        return outstring;
    }
    
    + (NSString *) getHashedMACAddress
    {
        NSString * mac = [IDManager getMACAddress];
        return [CommonUtil md5String:mac];
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-28 22:33

    Have a look at NSSelectorFromString and [NSObject performSelector:SEL]. NSSelectorFromString allows you to select a selector by runtime with a string. Use it in combination with a OS version check at runtime.

    0 讨论(0)
  • 2020-12-28 22:35

    You can use this:

    NSString *udid;
    
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0"))
        udid = [UIDevice currentDevice].identifierForVendor.UUIDString;
    else
        udid = [UIDevice currentDevice].uniqueIdentifier;
    

    with pre processor code:

    #define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
    #define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
    #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
    #define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
    #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
    
    0 讨论(0)
提交回复
热议问题