2012-07-15 5 views
7

In meiner app, ich möchte eine Konfiguration in der Lage sein zu synchronisieren, die vom Benutzer erstellt wird. Ich wollte iCloud verwenden, um diese Konfiguration so zu synchronisieren, dass sie auf allen Geräten immer gleich ist. Aber ich benutze den Schlüsselbund, um das Passwort zu speichern.iCloud-Sync-Schlüsselanhänger

Gibt es eine Möglichkeit, um auch Schlüsselanhänger Daten zu synchronisieren?

Antwort

3

Nein, Keychain-Synchronisierung ist nicht Teil von iCloud. Es war ein Teil von dot mac syncing, aber das ist nicht mehr verfügbar.

Es wird wahrscheinlich eine Rückmeldung darüber geben, ob dies eine gute Idee ist oder nicht (automatisches Verschieben von Passwörtern von einem Gerät zum anderen), insbesondere in Situationen, in denen mehrere Personen ein iCloud-Konto teilen (wahrscheinlich, aber nicht garantiert).

Wenn Sie der Meinung sind, dass das Passwort auf dem Schlüsselbund des Geräts gespeichert wird und der Benutzer es mindestens einmal pro Gerät eingeben muss, müssen Sie Ihre eigene Verschlüsselung und Sicherheit bereitstellen und die Daten direkt in iCloud speichern. wie im Keystore.

16

iCloud Keychain ist eine neue Funktion in iOS 7.0.3 und OS X Mavericks 10.9. Geben Sie das kSecAttrSynchronizable Attribut, wenn Sie einen Schlüsselbund Artikel mit dem SecItem API hinzugefügt.

+0

#jrc können Sie mir bitte helfen kSecAttrSynchronizable Attribut in Schlüsselbund zu setzen. – iKT

2

für Schlüsselanhänger Dies sind die Utility-Methoden die ich gemacht habe. kSecAttrSynchronizable ist der Grund, warum iCloud Sync funktioniert. Hoffe, dass sie helfen.

  • Schlüsselbund Abfrage.
  • entfernen Artikel
  • Artikel löschen
  • Artikel speichern
  • Last Artikel

    + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { 
        return [NSMutableDictionary dictionaryWithObjectsAndKeys: 
          (__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass, 
          service, (__bridge id)kSecAttrService, 
          service, (__bridge id)kSecAttrAccount, 
          service, (__bridge id)kSecAttrSynchronizable, 
          (__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible, 
          nil]; 
    } 
    
    + (void)save:(NSString *)service data:(id)data { 
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; 
        SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 
        [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData]; 
        SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); 
    } 
    
    + (void)remove:(NSString *)service { 
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; 
        SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 
    } 
    
    +(NSString *)keychainItem:(NSString *)service{ 
        id data = [self load:service]; 
    
        if([data isKindOfClass:[NSString class]]){ 
         return data; 
        } 
        return @""; 
    } 
    
    + (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; 
    } 
    
+0

+1 für die vollständige Antwort und den Code zur Bereitstellung aller Daten müssen archiviert werden. Natürlich muss das (id) Datenobjekt dem Protokoll entsprechen. – loretoparisi