Question

I'm using sskeychain (https://github.com/soffes/sskeychain) to store my accounts and passwords in the IOS keychain. I assume, that if I store an account, it should be available on my other device. But it doesn't appear there.

I read my accounts with this code:

NSArray *arr=[SSKeychain accountsForService:@"Login"];
for (NSString *s in arr) {
    NSLog(@"Account: %@",s);
}

and get this (only shown one entry, the others are similar):

Account: {
acct = "friXXXXXter@XXXX.com";
agrp = "3B4384Z34A.de.gondomir.LocalButler";
cdat = "2014-05-09 22:55:08 +0000";
mdat = "2014-05-09 22:55:08 +0000";
pdmn = ak;
svce = Login;
sync = 0;
tomb = 0;
}

But this doesn't appear on the other device. Both devices have IOS 7.1.1. I store the password with this line:

  [SSKeychain setPassword:self.passwortField.text forService:@"Login" account:self.userField.text];

I have switched on keychain sharing in Xcode and have a keychain group "de.gondomir.LocalButler" listed there.

Am I missing something? Must the service name something special?

Thanks!

Was it helpful?

Solution

In case this is still relevant for you I managed to find the solution. (works for >=iOS7)

Don't use the static methods of SSKeychain to write your credentials. Instead use SSKeychainQuery and set the synchronizationMode to SSKeychainQuerySynchronizationModeYes like this

NSError *error; 
[SSKeychain setAccessibilityType:self.keychainAccessibilityType];
SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
query.service = service;
query.account = account;
query.password = password;
query.synchronizationMode = SSKeychainQuerySynchronizationModeYes;
[query save:&error];
if (error) {
    NSLog(@"Error writing credentials %@", [error description]);
}

The static convenience methods on SSKeychain use the default synchronization mode SSKeychainQuerySynchronizationModeAny causing credentials not to be synchronized with the iCloud keychain.

Additionally, make sure your devices have Keychain via iCloud enabled (Settings>iCloud>Keychain). You might also want to enable Keychain Sharing in your targets Capabilities.

OTHER TIPS

After I have a new project I tried the answer of MarkHim, it works. I used swift now, so here is my working code:

    let account = defaults.objectForKey("Sync_toPhoneNumber") as? String
    SSKeychain.setAccessibilityType(kSecAttrAccessibleAfterFirstUnlock)

    var error:NSError?
    let lookupQuery = SSKeychainQuery()
    lookupQuery.synchronizationMode = .Yes
    lookupQuery.service = "DasDing"
    lookupQuery.account = account

    let password = SSKeychain.passwordForService("DasDing", account: account, error: &error)
    if error == nil {
        commandKey = password!
    } else {
        print("Error für \(account): \(error!.localizedDescription)")
        commandKey = ""
    }


    // query all accounts for later use
    let allQuery = SSKeychainQuery()
    allQuery.service = "DasDing"
    do {
        let dict = try allQuery.fetchAll()
        print("Accounts:")
        for acc in dict {
            print(acc["acct"]!)
        }
    } catch let error as NSError {
        print("keine Accounts")
        print("Error: \(error.localizedDescription)")
    }

That's for reading, for writing you must delete the account first (if you want to change the password):

    let account = defaults.objectForKey("Sync_toPhoneNumber") as? String
    SSKeychain.setAccessibilityType(kSecAttrAccessibleAfterFirstUnlock)

    SSKeychain.deletePasswordForService("DasDing", account: account)

    let newQuery = SSKeychainQuery()
    newQuery.service = "DasDing"
    newQuery.account = account

    newQuery.password = str?.uppercaseString
    newQuery.synchronizationMode = .Yes
    try! newQuery.save()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top