Created
December 5, 2012 05:09
-
-
Save kechol/4212481 to your computer and use it in GitHub Desktop.
manager for KeychainAccess. suitable for ARC.
This file contains hidden or 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
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| <plist version="1.0"> | |
| <dict> | |
| <key>application-identifier</key> | |
| <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string> | |
| <key>keychain-access-groups</key> | |
| <array> | |
| <string>$(AppIdentifierPrefix)yourAccessGroup</string> | |
| </array> | |
| </dict> | |
| </plist> |
This file contains hidden or 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
| // | |
| // ZTMKeychainManager.m | |
| // | |
| // Created by Kechol on 2012/11/24. | |
| // Copyright (c) 2012 Kechol. | |
| // | |
| #import "ZTMKeychainManager.h" | |
| #import <Security/Security.h> | |
| @interface ZTMKeychainManager() | |
| @end | |
| @implementation ZTMKeychainManager | |
| static NSString * const kAccessGroup = @"APPPREFIX.yourAccessGroup"; | |
| static NSString * const kService = @"set.your.app.identifier"; | |
| - (id)initWithIdentifier: (NSString *)identifier | |
| { | |
| if (self = [super init]) | |
| { | |
| _defaultDict = [NSMutableDictionary dictionary]; | |
| [_defaultDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
| [_defaultDict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; | |
| #if !TARGET_IPHONE_SIMULATOR | |
| [_defaultDict setObject:kAccessGroup forKey:(__bridge id)kSecAttrAccessGroup]; | |
| [_defaultDict setObject:kService forKey:(__bridge id)kSecAttrService]; | |
| #endif | |
| NSDictionary *query = [NSDictionary dictionaryWithDictionary:_defaultDict]; | |
| CFMutableDictionaryRef dict = NULL; | |
| if (SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dict) == noErr) { | |
| account = [(__bridge NSMutableDictionary *)dict objectForKey:(__bridge id)kSecAttrAccount]; | |
| password = [(__bridge NSMutableDictionary *)dict objectForKey:(__bridge id)kSecValueData]; | |
| } | |
| if(dict) CFRelease(dict); | |
| } | |
| [self dumpItems]; | |
| return self; | |
| } | |
| - (void)setAccount:(NSString *)acct AndPassword:(NSString *)pswd | |
| { | |
| account = acct; | |
| password = [pswd dataUsingEncoding:NSUTF8StringEncoding]; | |
| NSMutableDictionary *query = [NSMutableDictionary dictionaryWithDictionary:self.defaultDict]; | |
| CFMutableDictionaryRef dict = NULL; | |
| NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; | |
| [attributes setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
| [attributes setObject:account forKey:(__bridge id)kSecAttrAccount]; | |
| [attributes setObject:password forKey:(__bridge id)kSecValueData]; | |
| NSLog(@"SecSearchDict: %@", query); | |
| OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dict); | |
| if (err == noErr) { | |
| err = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes); | |
| if (err != noErr) { | |
| NSLog(@"SecItemUpdateError: %ld", err); | |
| } else { | |
| NSLog(@"SecItemUpdateSuccess: %@", attributes); | |
| } | |
| } else if(err == errSecItemNotFound) { | |
| [attributes setObject:kService forKey:(__bridge id)kSecAttrService]; | |
| err = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL); | |
| if (err != noErr) { | |
| NSLog(@"SecItemAddError: %ld", err); | |
| } else { | |
| NSLog(@"SecItemAddSuccess: %@", attributes); | |
| } | |
| } | |
| if(dict) CFRelease(dict); | |
| } | |
| - (NSString *)account | |
| { | |
| NSMutableDictionary *query = [NSMutableDictionary dictionaryWithDictionary:self.defaultDict]; | |
| [query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; | |
| CFMutableDictionaryRef dict = NULL; | |
| OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dict); | |
| if(err == noErr) { | |
| return [(__bridge NSMutableDictionary *)dict objectForKey:(__bridge id)kSecAttrAccount]; | |
| } else { | |
| NSLog(@"SecAccountError: %ld", err); | |
| if(account) return account; | |
| } | |
| if(dict) CFRelease(dict); | |
| return nil; | |
| } | |
| - (NSString *)password | |
| { | |
| NSMutableDictionary *query = [NSMutableDictionary dictionaryWithDictionary:self.defaultDict]; | |
| [query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; | |
| CFMutableDictionaryRef dict = NULL; | |
| NSLog(@"SecSearchDict: %@", query); | |
| OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dict); | |
| if(err == noErr) { | |
| NSData *pswd = [(__bridge NSMutableDictionary *)dict objectForKey:(__bridge id)kSecValueData]; | |
| return [[NSString alloc] initWithData:pswd encoding:NSUTF8StringEncoding]; | |
| } else { | |
| NSLog(@"SecPasswordError: %ld", err); | |
| if(password) return [[NSString alloc] initWithData:password encoding:NSUTF8StringEncoding]; | |
| } | |
| if(dict) CFRelease(dict); | |
| return nil; | |
| } | |
| - (void)deleteItem | |
| { | |
| OSStatus err = noErr; | |
| if (account || password) { | |
| NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; | |
| [attributes setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
| [attributes setObject:kService forKey:(__bridge id)kSecAttrService]; | |
| [attributes setObject:(id)account forKey:(__bridge id)kSecAttrAccount]; | |
| err = SecItemDelete((__bridge CFDictionaryRef)attributes); | |
| if(!(err == noErr || err == errSecItemNotFound)) { | |
| NSLog(@"SecItemDeleteError: %ld", err); | |
| } | |
| } | |
| } | |
| - (void)dumpItems | |
| { | |
| NSMutableDictionary *query = [NSMutableDictionary dictionary]; | |
| [query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
| [query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; | |
| [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; | |
| CFArrayRef result = NULL; | |
| OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query,(CFTypeRef *)&result); | |
| if (err == noErr) { | |
| NSLog(@"SecDumpResult: %@", result); | |
| } else if(err == errSecItemNotFound) { | |
| NSLog(@"SecDumpNotFound: %ld", err); | |
| } else { | |
| NSLog(@"SecDumpError: %ld", err); | |
| } | |
| } | |
| @end |
This file contains hidden or 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
| // | |
| // ZTMKeychainManager.h | |
| // | |
| // Created by Kechol on 2012/11/24. | |
| // Copyright (c) 2012 Kechol. | |
| // | |
| #import <Foundation/Foundation.h> | |
| #import <UIKit/UIKit.h> | |
| @interface ZTMKeychainManager : NSObject { | |
| NSString *account; | |
| NSData *password; | |
| } | |
| @property (nonatomic, retain) NSMutableDictionary *defaultDict; | |
| - (id)initWithIdentifier: (NSString *)identifier; | |
| - (void)setAccount:(NSString *)acct AndPassword:(NSString *)pswd; | |
| - (void)deleteItem; | |
| - (void)dumpItems; | |
| - (NSString *)account; | |
| - (NSString *)password; | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment