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

 清醒还是迷惘_123 发布于 2023-02-08 12:49

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

我将这些设备ID保存在服务器中,我最近注意到一些用户为同一个真实设备拥有多个这些ID.我看到的唯一解释是ID没有从Keychain保存或加载,因此设备生成一个新ID.奇怪的是,它在运行相同iOS版本的其他一些设备上运行良好.

关于可能发生什么的任何想法?

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

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由于某种原因没有按预期工作.稍后在应用程序中我注册了推送通知,并将推送令牌连同我用同一条线读取的CFUUID一起[SSKeychain passwordForService:serviceName account:identifier]发送到服务器但是当它被发送到服务器时它不是零(所以我可以看到几个CFUUID与相同的推送令牌).

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

AppDelegate.m

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

-(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方法只是将数据发送到服务器然后回调委托,该部分工作正常.我可以在服务器上看到接收此命令的日志:

"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"
}
]  

我看到2个可能导致奇怪行为的候选者,NSStrings在控制器主体和静态getDevice方法中.但是,我不知道这在许多设备中如何工作,但在其他设备中却失败了.

1 个回答
  • 我遇到了同样的问题,我找到了解决方案.用户将密码设置为解锁手机的设备会出现问题.在iOS7上,某些代码可以在后台运行(推送通知,后台获取),如果您使用标准辅助功能类型在钥匙串中保存了某些内容,则在设备被锁定(并且应用程序在后台运行)时无法读取它.尝试设置:

    [SSKeychain setAccessibilityType:kSecAttrAccessibleAlways];
    

    在你读/写钥匙串之前.希望能帮助到你.

    2023-02-08 12:51 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有