Sto utilizzando il portachiavi per memorizzare i dati sul dispositivo locale, ma ho deciso di adattarlo per l'utilizzo su più dispositivi tramite iCloud. Ho abilitato l'autorizzazione iCloud e creato la configurazione necessaria all'interno del Centro membri. Tuttavia, mentre i dati vengono memorizzati, non sembra che sia stato archiviato nel cloud. Sto testando tra il simulatore e il mio dispositivo iPhone. Il simulatore è loggato usando il mio account. Ogni dispositivo continua a salvare i dati ma l'altro dispositivo non vede i risultati.Dati portachiavi non memorizzati in iCloud
Ho aggiunto solo kSecAttrSynchronizable e kCFBooleanTrue all'installazione che ho capito era tutto ciò che era necessario per far sì che il portachiavi usasse il cloud.
Qui il codice utilizzato per la memorizzazione e il richiamo dei dati del portachiavi.
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service
{
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass,
service, (__bridge id)kSecAttrService,
service, (__bridge id)kSecAttrAccount,
(__bridge id)kCFBooleanTrue, (__bridge id)kSecAttrSynchronizable,
(__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data
{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
CFTypeRef result = NULL;
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, &result);
if (status == errSecSuccess) NSLog(@"Succcessfully Stored Value");
else NSLog(@"Failed to store value with code: %ld",(long)status);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
@catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
}
@finally {}
}
if (keyData) CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
}
Un po 'di follow-up. Stavo guardando il portachiavi sul mio Mac mentre utilizzavo l'app sul telefono. Stavo vedendo i dati portachiavi scritti, quindi sembra che funzionino. Tuttavia, avevo l'impressione che anche il simulatore dovesse funzionare e che ci fosse un'opzione "trigger iCloud Sync" in Debug nella simulazione. La documentazione di Apple indica anche che è possibile utilizzare il simulatore. Tuttavia, sembra che non interagisca con la catena di chiavi principale anche se il mio account è entrato nel simulatore. – C6Silver
Quando dici abilitato "iCloud entitlement", intendi che hai attivato la funzionalità portachiavi in "iCloud" nell'app delle impostazioni? O c'è qualche capovolgimento che devi attivare in pList? –
Abilitato in "Funzionalità" nelle impostazioni dei target. Nel Centro membri è stato aggiunto "iCloud" all'app ID (questa è la titolarità che fanno riferimento all'interno della scheda "Funzionalità". – C6Silver