Id UUID静态会话?

时间:2013-05-23 10:30:57

标签: iphone ios

我想使用UDID的替代品并找到:

+ (NSString *)GetUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  return [(NSString *)string autorelease];
}

但是在模拟器中,每个会话都会给我不同的结果吗?

这只是在模拟器中吗?

我需要确保在实际设备上该方法总是返回相同的字符串 识别用户。

这是真的吗?

米尔扎

6 个答案:

答案 0 :(得分:1)

每次调用该函数时,CFUUIDCreate都会为您提供通用唯一标识符,因此每次获得不同的结果(根据定义)。

您可以做的是在会话之间使用(例如NSUserDefaults)来保持这一点,以唯一地标识特定用户(或一组用户的设置)。

答案 1 :(得分:1)

CFUUIDRef会在每个会话中创建不同的值。

解决方案1:

将值保存在NSUserDefaults中,然后从NSUserDefaults开始使用它。

解决方案2:

您可以使用identifierForVendor执行此操作。

NSString *udidVendor = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

根据UIDevice Class Reference

  

此属性的值对于来自的应用程序是相同的   在同一设备上运行的同一供应商。返回不同的值   对于来自不同供应商的同一设备上的应用程序,以及   不论供应商如何,都可以在不同的设备上使用。

请检查Unique Identifier In iOS 6

答案 2 :(得分:0)

CFUUID根本不存在。

每当您致电CFUUIDCreate时,系统都会返回一个全新的唯一标识符。

如果您想要保留此标识符,则需要使用NSUserDefaults,Keychain,Pasteboard或其他方法自行执行此操作。

答案 3 :(得分:0)

一次读取一行代码并尝试理解它的作用。 CFUUIDCreate函数每次调用时都会创建一个 new UUID。这可以解释你的发现。您需要首次将值保存在NSUserDefaults *中,并在下次启动应用时使用该值:

+ (NSString *)GetUUID
{
    NSString *string = [[NSUserDefaults standardUserDefaults] objectForKey: @"UUID"];
    if (!string)
    {
        CFUUIDRef theUUID = CFUUIDCreate(NULL);
        string = (NSString*)[CFUUIDCreateString(NULL, theUUID) autorelease];
        CFRelease(theUUID);
        [[NSUserDefaults standardUserDefaults] setObject: string forKey: @"UUID"];
    }
    return string;
}

*使用NSUserDefaults有一个小小的警告 - 如果用户再次卸载并重新安装应用程序,将再次创建UUID。如果您不能忍受这种情况,请考虑将其保存在钥匙串中。或者,您可能需要查看OpenUDID

答案 4 :(得分:0)

总是与众不同。 UUID包含时间戳,因此每次调用此函数时,您将获得一个不同的(随机)函数。 我在IDManager课程中遵循了这种方法, 这是来自不同解决方案的集合。 KeyChainUtil是一个从keychain读取的包装器。在github中可以找到类似的keychain util。

//  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

答案 5 :(得分:0)

该方法将始终返回唯一的字符串。如果应用程序只有一个用户,请在用户第一次启动应用程序时运行此方法,并将该字符串保留在plist,NSUserDefaults或核心数据中(如果您已经使用过它)

以下链接可能有助于此UUID持久性逻辑: UUID for app on iOS5

但是,如果用户随后卸载并重新安装应用程序,则此持久性UUID仍将丢失,并且需要再次生成。

Apple也不再允许使用设备ID。

假设UUID是必需的,因为应用程序连接到服务器,据我所知,您需要用户使用用户名和密码登录服务器。