首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >存储在SSKeychain中的CFUUID在某些设备中为空

存储在SSKeychain中的CFUUID在某些设备中为空
EN

Stack Overflow用户
提问于 2013-12-24 10:23:31
回答 2查看 2.1K关注 0票数 3

我发布的应用程序使用CFUUIDSSKeychain来识别设备(并且即使应用程序被卸载和重新安装,ID也保持不变)。

我将这些设备ID保存在服务器中,最近我注意到,--一些用户对于同一个实际设备有几个ID。我看到的唯一解释是,ID没有从密钥链中保存或加载,因此设备会生成一个新的ID。奇怪的是,它在运行相同iOS版本的其他设备上工作得很好。

对可能发生的事有什么想法吗?

这是我在(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中的相关代码

代码语言:javascript
运行
复制
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
NSString *retrieveuuid = [SSKeychain passwordForService:serviceName account:identifier];
if (retrieveuuid == nil) {
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    NSString *uuid  = (NSString*) string;
    [SSKeychain setPassword:uuid forService:serviceName account:identifier];
}

编辑:我的猜测是,由于某些原因,retrieveuuid == nil没有像预期的那样工作。稍后,在应用程序中,我注册推送通知,并将推送令牌连同我用相同行[SSKeychain passwordForService:serviceName account:identifier]读取的这个CFUUID一起发送到服务器,但是当发送到服务器时,它不是零(因此我可以看到几个具有相同推送令牌的CFUUID)。

编辑2以附加更多的实际代码。

AppDelegate.m

代码语言:javascript
运行
复制
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //Creating UUID
    NSString *retrieveuuid = [AppDelegate getDeviceId];
    if (retrieveuuid == nil) {
        CFUUIDRef theUUID = CFUUIDCreate(NULL);
        CFStringRef string = CFUUIDCreateString(NULL, theUUID);
        CFRelease(theUUID);
        NSString *uuid  = (NSString*) string;
        [SSKeychain setPassword:uuid forService:serviceName account:identifier];
    }

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}

+ (NSString*) getDeviceId {
    return [SSKeychain passwordForService:serviceName account:identifier];
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    NSString *newToken = [deviceToken description];
    newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];

    _deviceToken = [[NSString alloc] initWithString:newToken];

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    NSString *user = [prefs objectForKey:@"appNameUsername"];

    if(user && ![user isEqualToString:@""]){
        RestClient *rest = [[RestClient alloc] init];
        rest.delegate = self;
        rest.tag = 2;
        [rest updateToken:newToken ForUsername:user];
        [rest release];
    }
}

RestClient.m

代码语言:javascript
运行
复制
-(void) updateToken:(NSString *)token ForUsername:(NSString *)userName{
    NSArray* info = [NSArray arrayWithObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                               userName, @"Username",
                                               token, @"TokenNo",
                                               [[UIDevice currentDevice].model hasPrefix:@"iPad"] ? @"iPad" : @"iPhone", @"Device",
                                               [UIDevice currentDevice].systemVersion, @"OSVersion",
                                               [AppDelegate getDeviceId], @"DeviceID",
                                               @"updateToken", @"CMD",
                                               nil]];
    [self doAction:info];
}

doAction方法只将数据发送到服务器,然后回调委托,该部分工作正常。我可以在服务器上看到接收此命令的日志:

代码语言:javascript
运行
复制
"JSONCMD":"[
{   "TokenNo" : "f0d3aa21758350333b7e6315c38_EDIT_257c1838f49c43049f8380ec1ff63", 
    "AppVersion" : "1.0.4",
    "Username" : "user@server.com", 
    "CMD" : "updateToken", 
    "OSVersion" : "7.0.4", 
    "DeviceID" : "9B794E11-6EF7-470C-B319-5A9FCCDAFD2B", 
    "Device" : "iPhone"
}
]  

我看到了引起这种奇怪行为的两种可能的选择:控制器体中的NSStrings和静态getDevice方法。然而,我看不出这在许多设备中是如何工作的,但在其他设备中却失败了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-10 05:44:58

我也遇到过同样的问题,我找到了解决办法。这个问题发生在用户设置密码解锁手机的设备上。在iOS7上,一些代码可以在后台运行(推送通知、后台获取),如果您用标准可访问性类型在密钥链中保存了一些内容,则当设备被锁定时(应用程序在后台运行),您无法读取它。尝试设置如下:

代码语言:javascript
运行
复制
[SSKeychain setAccessibilityType:kSecAttrAccessibleAlways];

在你读/写钥匙链之前。希望能帮上忙。

票数 7
EN

Stack Overflow用户

发布于 2013-12-24 10:37:39

NSString *retrieveuuid = SSKeychain passwordForService:serviceName帐户:标识符;

检索取决于服务,女巫总是同一件事,但也依赖于帐户。我认为您的问题是,一个用户可以在同一个设备中拥有多个帐户,然后您的代码将为每个帐户生成一个UUID。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20759169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档