我的iOS应用程序有一个登录界面。 用户名和密码将保存在NSUserDefaults中,并在再次进入应用程序时再次加载到登录屏幕中(当然,NSUserDefaults是永久的)。
现在,用户可以禁用用户名/密码保存功能。
NSUserDefaults会被清除。
但是在我的应用程序中,我需要这个用户名/密码的数据库查询用户。 所以:哪里存储数据除了NSUserDefaults? (这个地方可以/应该在用户退出应用程序或登出时删除)。
我的iOS应用程序有一个登录界面。 用户名和密码将保存在NSUserDefaults中,并在再次进入应用程序时再次加载到登录屏幕中(当然,NSUserDefaults是永久的)。
现在,用户可以禁用用户名/密码保存功能。
NSUserDefaults会被清除。
但是在我的应用程序中,我需要这个用户名/密码的数据库查询用户。 所以:哪里存储数据除了NSUserDefaults? (这个地方可以/应该在用户退出应用程序或登出时删除)。
当前回答
我尝试使用KeychainItemWrapper (ARC版本),但我发现它的Objective C包装器不如预期的那么健康。
我使用了Kishikawa Katsumi的这个解决方案,这意味着我写了更少的代码,不必使用类型转换来存储NSString值。
存储的两个例子:
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];
检索的两个例子
UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
// or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];
NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];
其他回答
如果您在使用钥匙串包装器检索密码时遇到问题,请使用以下代码:
NSData *pass =[keychain objectForKey:(__bridge id)(kSecValueData)];
NSString *passworddecoded = [[NSString alloc] initWithData:pass
encoding:NSUTF8StringEncoding];
上面的代码中有一个小错误(顺便说一下,戴夫,你的帖子非常有帮助,谢谢你)
在保存凭据的部分,它还需要以下代码才能正常工作。
[self.keychainItem setObject:@"myCredentials" forKey:(__bridge id)(kSecAttrService)];
最有可能的原因是,当我们第二次尝试(重新)使用相同的凭据登录时,它会发现它们已经分配在钥匙链项中,应用程序就会崩溃。使用上面的代码,它就像一个魅力。
如果您需要ARC版本的包装器,请访问https://gist.github.com/1170641 多亏了
更新这个问题:
对于那些使用Swift签出的人来说,Mihai Costea支持的拖放Swift实现访问组:
https://github.com/macostea/KeychainItemWrapper.swift/blob/master/KeychainItemWrapper.swift
使用钥匙串前: 存储密码前要三思。在许多情况下,存储一个身份验证令牌(例如持久性会话id)和电子邮件或帐户名可能就足够了。您可以很容易地使身份验证令牌失效,以阻止未经授权的访问,要求用户在受威胁的设备上再次登录,但不需要重置密码,并且必须在所有设备上再次登录(我们不仅使用Apple是吗?)
我尝试使用KeychainItemWrapper (ARC版本),但我发现它的Objective C包装器不如预期的那么健康。
我使用了Kishikawa Katsumi的这个解决方案,这意味着我写了更少的代码,不必使用类型转换来存储NSString值。
存储的两个例子:
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];
检索的两个例子
UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
// or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];
NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];