È necessario utilizzare i dati kSecValue come chiave per memorizzare la password (nel formato NSData o CFDataRef).
Il riferimento è un po 'poco chiaro in questo argomento, chiave kSecValueData funziona come chiave di output e chiave di input. Cioè, lo si utilizza quando si esegue una query su un oggetto portachiavi (SecItemCopyMatching) e si specifica una chiave kSecReturnAttributes, quindi il risultato viene restituito come dizionario, la password verrà archiviata in una chiave kSecValueData del dizionario. E lo usi anche quando aggiungi un elemento al portachiavi (SecItemAdd), memorizzando il valore NSData o CFDataRef della tua password nella chiave kSecValueData prima di chiamare il metodo.
Ecco un esempio di entrambi i casi:
Recupero password
NSMutableDictionary *queryDictionary = [[NSMutableDictionary alloc] init];
[queryDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass];
[queryDictionary setObject:service forKey:kSecAttrService];
[queryDictionary setObject:account forKey:kSecAttrAccount];
// The result will be a dictionary containing the password attributes...
[queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnAttributes)];
// ...one of those attributes will be a kSecValueData with the password
[queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnData)];
OSStatus sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)(queryDictionary), (CFTypeRef *)&result);
if (sanityCheck != noErr)
{
NSDictionary * resultDict = (__bridge NSDictionary *)result;
// here's the queried password value
NSData *passwordValue = [resultDict objectForKey:(__bridge id)(kSecValueData)];
}
Aggiunta la password
NSString *passwordString = @"my password value";
NSData *passwordData = [passwordString dataUsingEncoding:NSUTF8StringEncoding];
CFDictionaryRef result = nil;
NSMutableDictionary *addDictionary = [[NSMutableDictionary alloc] init];
[addDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass];
[addDictionary setObject:service forKey:kSecAttrService];
[addDictionary setObject:account forKey:kSecAttrAccount];
// here goes the password value
[addDictionary setObject:passwordData forKey:(__bridge id<NSCopying>)(kSecValueData)];
OSStatus sanityCheck = SecItemAdd((__bridge CFDictionaryRef)(queryDictionary), NULL)
if (sanityCheck != noErr)
{
// if no error the password got successfully stored in the keychain
}
codice migliore, con meno bug, qui: http://stackoverflow.com/questions/19284063/secitemcopymatching-returns-nil-data –