将电子邮件/密码保存到iOS中的钥匙串 [英] Saving Email/Password to Keychain in iOS
问题描述
我对iOS开发很新,所以如果这是一个新手问题请原谅我。我的应用程序有一个简单的身份验证机制,它采用用户的电子邮件地址和密码。我也有一个开关,上面写着记住我。如果用户切换该开关,我想保留他们的电子邮件/密码,以便将来可以自动填充这些字段。
I'm very new to iOS development so forgive me if this is a newbie question. I have a simple authentication mechanism for my app that takes a user's email address and password. I also have a switch that says 'Remember me'. If the user toggles that switch on, I'd like to preserve their email/password so those fields can be auto-populated in the future.
我已经得到了这个保存到plist文件,但我知道这不是最好的主意,因为密码是未加密的。我找到了一些保存到钥匙串的示例代码,但说实话,我有点迷失了。对于下面的功能,我不知道如何调用它以及如何修改它以保存电子邮件地址。
I've gotten this to work with saving to a plist file but I know that's not the best idea since the password is unencrypted. I found some sample code for saving to the keychain, but to be honest, I'm a little lost. For the function below, I'm not sure how to call it and how to modify it to save the email address as well.
我猜测它会是: saveString(@passwordgoeshere);
感谢您的帮助!!!
+ (void)saveString:(NSString *)inputString forKey:(NSString *)account {
NSAssert(account != nil, @"Invalid account");
NSAssert(inputString != nil, @"Invalid string");
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[query setObject:account forKey:(id)kSecAttrAccount];
[query setObject:(id)kSecAttrAccessibleWhenUnlocked forKey:(id)kSecAttrAccessible];
OSStatus error = SecItemCopyMatching((CFDictionaryRef)query, NULL);
if (error == errSecSuccess) {
// do update
NSDictionary *attributesToUpdate = [NSDictionary dictionaryWithObject:[inputString dataUsingEncoding:NSUTF8StringEncoding]
forKey:(id)kSecValueData];
error = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attributesToUpdate);
NSAssert1(error == errSecSuccess, @"SecItemUpdate failed: %d", error);
} else if (error == errSecItemNotFound) {
// do add
[query setObject:[inputString dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
error = SecItemAdd((CFDictionaryRef)query, NULL);
NSAssert1(error == errSecSuccess, @"SecItemAdd failed: %d", error);
} else {
NSAssert1(NO, @"SecItemCopyMatching failed: %d", error);
}
}
推荐答案
我我写了一个简单的包装器,允许将任何符合NSCoding标准的对象保存到钥匙串中。例如,您可以将您的电子邮件和密码存储在NSDictionary中,并使用此类将NSDictionary存储到钥匙串。
I've written a simple wrapper that allows saving of any NSCoding-compliant object to the keychain. You could, for example, store your email and password in an NSDictionary and store the NSDictionary to the keychain using this class.
SimpleKeychain.h
#import <Foundation/Foundation.h>
@class SimpleKeychainUserPass;
@interface SimpleKeychain : NSObject
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;
@end
SimpleKeychain.m
#import "SimpleKeychain.h"
@implementation SimpleKeychain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassGenericPassword, (id)kSecClass,
service, (id)kSecAttrService,
service, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];
}
@catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
}
@finally {}
}
if (keyData) CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
}
@end
这篇关于将电子邮件/密码保存到iOS中的钥匙串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!