iOS钥匙链:在钥匙链中设置和获取数据时的奇怪行为

iOS钥匙链:在钥匙链中设置和获取数据时的奇怪行为,ios,objective-c,wrapper,keychain,Ios,Objective C,Wrapper,Keychain,这一切都发生在我的模拟器里。 在练习使用钥匙链包装器时,我发现自己处于一种奇怪的境地。我试图学习如何从钥匙链中插入和检索数据,为了做到这一点,我开始了一个新项目,在这个项目中,我所做的唯一一件事就是在我的视图控制器的(void)viewDidLoad“方法中写入默认的用户名,默认的密码,在第二次运行应用程序时存储并尝试检索它们 这本应该是小菜一碟,但我发现我的应用程序正在崩溃。这是我使用的代码: - (void)viewDidLoad{ [super viewDidLoad]; //Keyc

这一切都发生在我的模拟器里。 在练习使用钥匙链包装器时,我发现自己处于一种奇怪的境地。我试图学习如何从钥匙链中插入和检索数据,为了做到这一点,我开始了一个新项目,在这个项目中,我所做的唯一一件事就是在我的视图控制器的(void)viewDidLoad“方法中写入默认的用户名,默认的密码,在第二次运行应用程序时存储并尝试检索它们

这本应该是小菜一碟,但我发现我的应用程序正在崩溃。这是我使用的代码:

- (void)viewDidLoad{

[super viewDidLoad];

//Keychain wrapper definition
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

//Getting DATA:
NSLog(@"Retrieving User DATA");
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
NSLog(@"pwd = %@",password);
NSLog(@"user = %@",username);

//Setting DATA:
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];  
}
Xcode给了我一个n内部一致性异常uncaught。 在玩代码时,我意识到只有在设置新密码时(在我的应用程序第一次运行时或在重置钥匙链后)才会出现问题,只有在我将密码设置在用户名之前,才会出现奇怪的部分。所以重写代码交换

//Setting DATA
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];     
}  
解决了我的问题。谁能解释一下原因吗

最后,我想问一下,在第二次运行我的应用程序时检索我的密码是否会导致密码的加密版本。这是因为我尝试通过两种方式获取密码:

1) 我刚储存好就拿到了

//saving DATA
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];

//getting DATA:
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSLog(@"\nUser: %@ \nPassword: %@",username,password);  
结果是

User: username you are saving
Password: password you are saving
User: username you are saving
Password: <70617373 776f7264 20796f75 20617265 20736176 696e67>
2) 我在第二次运行中获得了密码,并对设置部分进行了注释

//saving DATA
//[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
//[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];

//getting DATA:
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSLog(@"\nUser: %@ \nPassword: %@",username,password);  
结果是

User: username you are saving
Password: password you are saving
User: username you are saving
Password: <70617373 776f7264 20796f75 20617265 20736176 696e67>
User:您正在保存的用户名
密码:
那么这是我的密码的加密版本还是什么


谢谢

我不明白为什么在用户名之前将密码放入钥匙链会导致应用程序崩溃,但我了解到,为了从钥匙链获取密码,必须首先将其存储在NSData中,您应该这样做:

NSData *pwd = [keychainItem objectForKey:(__bridge id)(kSecValueData)]; 
password =    [[NSString alloc] initWithData:pwd encoding:NSUTF8StringEncoding];

它没有加密。这些数字只是字符串“passwordyousaving”的十六进制值。在这种情况下,如果打印
[password class]
的值,您会得到什么?可能是
NSData
而不是
NSString
。我现在尝试了,
[password class]
的结果是:\uu NSCFData所以您是对的。我使用
NSData*p=[keychainItemObjectForkey:(u桥id)(kSecValueData)]解决了我的问题
then
password=[[NSString alloc]initWithData:p encoding:NSUTF8StringEncoding]