2012-07-15 7 views
7

私のアプリでは、ユーザーが作成した設定を同期したいと思っています。私はiCloudを使ってその設定を同期して、すべてのデバイスで常に同じにしたいと思っていました。しかし、私はキーチェーンを使ってパスワードを保存します。iCloud同期キーチェーン

キーチェーンのデータを同期する方法はありますか?

答えて

3

いいえ、キーチェーンの同期はiCloudの一部ではありません。これはドットマック同期の一部でしたが、もう利用できません。

特に、複数の人がiCloudアカウントを共有している場合(最近の保証はありませんが)、これが良いアイデアかどうか(デバイス間でパスワードを自動的に移動する)のフィードバックがあります。

パスワードをデバイスのキーチェーンに保存すると、ユーザーがデバイスごとに少なくとも1回パスワードを入力する必要があると思われる場合は、独自の暗号化と安全性を提供し、データをiCloudに直接保存する必要があります。キーストア内などで使用できます。

16

iCloud Keychainは、iOS 7.0.3およびOS X Mavericks 10.9の新機能です。 SecItem APIを使用してキーチェーン項目を追加するときは、kSecAttrSynchronizable属性を指定します。

+0

#jrcキーチェーンにkSecAttrSynchronizable属性を設定する手助けをしてもらえますか? – iKT

2

これは私がキーチェーン用に作ったユーティリティメソッドです。 kSecAttrSynchronizableはiCloud Syncを動作させるものです。彼らが願っています。

  • キーチェーンクエリ。
  • 項目
  • 削除項目
  • 保存項目
  • 負荷項目は同じことを探し

    + (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と完全な答えを提供するコードはすべてデータをアーカイブする必要があります。もちろん、(id)データオブジェクトはプロトコルに準拠していなければなりません。 – loretoparisi