Last active
May 25, 2017 10:55
-
-
Save adil-hussain-84/ce3d60a03adfab001399b76c6908e97c to your computer and use it in GitHub Desktop.
Helper class which adds/gets/deletes entries in the iOS Keychain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Class modified from this GitHub repository: | |
// https://github.com/jeremangnr/JNKeychain | |
// | |
#import <Foundation/Foundation.h> | |
@interface MJRKeychainStorage : NSObject | |
/** | |
@abstract Saves the given key-value pair to the Keychain. | |
@param value The value to save. | |
@param key The key identifying the value to save. | |
@return YES iff the key-value pair was saved successfully. | |
*/ | |
- (BOOL)saveValue:(id)value forKey:(NSString *)key; | |
/** | |
@abstract Loads the value from the Keychain which matches the given key. | |
@param key The key identifying the value to load. | |
@return The value identified by key, or nil in case of error. | |
*/ | |
- (id)getValueForKey:(NSString *)key; | |
/** | |
@abstract Deletes the given key from the Keychain. | |
@param key The key identifying the key-value pair to delete. | |
@return YES iff either there is no such key in the Keychain or deletion was successful. | |
*/ | |
- (BOOL)deleteKey:(NSString *)key; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Class modified from this GitHub repository: | |
// https://github.com/jeremangnr/JNKeychain | |
// | |
#import "MJRKeychainStorage.h" | |
@implementation MJRKeychainStorage | |
- (BOOL)saveValue:(id)value forKey:(NSString *)key { | |
[self deleteKey:key]; | |
NSMutableDictionary *query = [self getQueryForKey:key]; | |
query[(__bridge id) kSecValueData] = [NSKeyedArchiver archivedDataWithRootObject:value]; | |
OSStatus status = SecItemAdd((__bridge CFDictionaryRef) query, NULL); | |
return status == errSecSuccess; | |
} | |
- (id)getValueForKey:(NSString *)key { | |
NSMutableDictionary *query = [self getQueryForKey:key]; | |
query[(__bridge id) kSecReturnData] = (__bridge id) kCFBooleanTrue; | |
query[(__bridge id) kSecMatchLimit] = (__bridge id) kSecMatchLimitOne; | |
CFDataRef keyData = NULL; | |
id value = nil; | |
if (SecItemCopyMatching((__bridge CFDictionaryRef) query, (CFTypeRef *) &keyData) == noErr) { | |
@try { | |
value = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *) keyData]; | |
} | |
@catch (NSException *e) { | |
value = nil; | |
} | |
@finally { | |
//nothing to do | |
} | |
} | |
if (keyData) { | |
CFRelease(keyData); | |
} | |
return value; | |
} | |
- (BOOL)deleteKey:(NSString *)key { | |
NSMutableDictionary *query = [self getQueryForKey:key]; | |
OSStatus status = SecItemDelete((__bridge CFDictionaryRef) query); | |
return (status == errSecSuccess) || (status == errSecItemNotFound); | |
} | |
#pragma mark - Private methods | |
- (NSMutableDictionary *)getQueryForKey:(NSString *)key { | |
NSMutableDictionary *query = [NSMutableDictionary dictionary]; | |
query[(__bridge id) kSecClass] = (__bridge id) kSecClassGenericPassword; | |
query[(__bridge id) kSecAttrService] = key; | |
query[(__bridge id) kSecAttrAccount] = key; | |
query[(__bridge id) kSecAttrAccessible] = (__bridge id) kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; | |
return query; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment