Sono riuscito a implementare TouchID con portachiavi e condivisione di portachiavi (sincronizzando gli elementi portachiavi tra più dispositivi) separatamente. Quando provo a eseguire entrambi, viene visualizzato un errore "-50" che non è valido. Dal codice qui sotto, rimuovendo sia kSecAttrAccessControl o kSecAttrSynchronizable funziona come previsto.È possibile utilizzare l'autenticazione Touch-ID e la condivisione del portachiavi in un'app iOS?
base della mia esperienza (leggere - un paio di giorni di frustrazione) finora, e in base alle capacità di alcuni portachiavi API semplificazione tools come UICKeychainStore, sembra come se uso touch ID di autenticazione, portachiavi condivisione wouldn' t lavoro e viceversa. Sto cercando una documentazione Apple che lo dichiarerebbe, ma non riuscendo a trovarlo.
Ho passato attraverso la pagina di Apple SecItem.h, e informazioni utili Ho trovato afferma, a proposito kSecAttrAccessible e kSecAttrSynchronizable: “Se entrambi gli attributi sono specificati su entrambi OS X o iOS, il valore per il kSecAttrAccessible chiave può essere solo uno il cui nome non termina con “ThisDeviceOnly", come quelli che non possono sincronizzare a un altro dispositivo.”Tuttavia, non sto usando 'ThisDeviceOnly' (attualmente sto usando kSecAttrAccessibleAlways a scopo di test)
Puoi aiutare a segnalare se e dove Apple ha documentato questo limitazione? Questo mi aiuterebbe a documentarlo per i record e andare avanti. Grazie.
- (void)addKeychainItemWithIdentifier:(NSString *)identifier andData:(NSData *)data {
CFErrorRef error = NULL;
SecAccessControlRef sacObject;
sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleAlways,
kSecAccessControlUserPresence, &error);
if(sacObject == NULL || error != NULL)
{
NSString *msg0 = [NSString stringWithFormat:NSLocalizedString(@"SEC_ITEM_ADD_CAN_CREATE_OBJECT", nil), error];
[self printResultWithMessage:msg0];
return;
}
NSDictionary *attributes = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecValueData: data,
(__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleAlways,
(__bridge id)kSecAttrService: identifier,
(__bridge id)kSecAttrSynchronizable:(__bridge id)kCFBooleanTrue,
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
NSError *statuserror = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
[self printResultWithMessage:[self keychainErrorToString:status]];
});
}
buona domanda !! –