Skip to content

Instantly share code, notes, and snippets.

@kechol
Created December 5, 2012 05:09
Show Gist options
  • Select an option

  • Save kechol/4212481 to your computer and use it in GitHub Desktop.

Select an option

Save kechol/4212481 to your computer and use it in GitHub Desktop.
manager for KeychainAccess. suitable for ARC.
<?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>
//
// 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
//
// 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