How do you reset an iPhone App's Keychain?
As all of the answers so far rely on you knowing the identifiers you want to delete, I would like to submit the following solution that deletes ALL existing keys for the app (iOS only)
Objective-C:
-(void)resetKeychain { [self deleteAllKeysForSecClass:kSecClassGenericPassword]; [self deleteAllKeysForSecClass:kSecClassInternetPassword]; [self deleteAllKeysForSecClass:kSecClassCertificate]; [self deleteAllKeysForSecClass:kSecClassKey]; [self deleteAllKeysForSecClass:kSecClassIdentity];}-(void)deleteAllKeysForSecClass:(CFTypeRef)secClass { NSMutableDictionary* dict = [NSMutableDictionary dictionary]; [dict setObject:(__bridge id)secClass forKey:(__bridge id)kSecClass]; OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict); NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%ld)", result);}
Swift 2.2:
func resetKeychain() { self.deleteAllKeysForSecClass(kSecClassGenericPassword) self.deleteAllKeysForSecClass(kSecClassInternetPassword) self.deleteAllKeysForSecClass(kSecClassCertificate) self.deleteAllKeysForSecClass(kSecClassKey) self.deleteAllKeysForSecClass(kSecClassIdentity)}func deleteAllKeysForSecClass(secClass: CFTypeRef) { let dict: [NSString : AnyObject] = [kSecClass : secClass] let result = SecItemDelete(dict) assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))")}
Swift 3:
func resetKeychain() { deleteAllKeysForSecClass(kSecClassGenericPassword) deleteAllKeysForSecClass(kSecClassInternetPassword) deleteAllKeysForSecClass(kSecClassCertificate) deleteAllKeysForSecClass(kSecClassKey) deleteAllKeysForSecClass(kSecClassIdentity)}func deleteAllKeysForSecClass(_ secClass: CFTypeRef) { let dict: [NSString : Any] = [kSecClass : secClass] let result = SecItemDelete(dict as CFDictionary) assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))")}
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"nameOfYourKeychain" accessGroup:nil];[keychainItem resetKeychainItem];
Much simpler :)
Edit: In response to a question asked below - what is KeychainItemWrapper?
It's a class written by Apple that you can download here: http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html
Add it to your project and then import it where you would like to use it. Then use the code snippet I provided above.
Block-based version of Vegard’s solution:
void (^deleteAllKeysForSecClass)(CFTypeRef) = ^(CFTypeRef secClass) { id dict = @{(__bridge id)kSecClass: (__bridge id)secClass}; OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict); NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%d)", (int)result);};deleteAllKeysForSecClass(kSecClassGenericPassword);deleteAllKeysForSecClass(kSecClassInternetPassword);deleteAllKeysForSecClass(kSecClassCertificate);deleteAllKeysForSecClass(kSecClassKey);deleteAllKeysForSecClass(kSecClassIdentity);
For those of us who like to just drop code in without having to have helper methods.