Simple Xamarin iOS Keychain code

I had searched and found a few decent examples of KeyChain (iOS) usage in Xamarin

I had searched and found a few decent examples of KeyChain (iOS) usage in Xamarin but not exactly the code I was happy with.

So this is more of a mashup of pieces of the good code I found formed into one utility class.

The key essentials are find an existing key, create a new key, delete a previous key. The examples I saw tried to do all of this in one method, it's better to break things up, have one method per responsilibity.

using Security;
using Foundation;

public class KeyChain
{

    public string ValueForKey(string key)
    {
        var record = ExistingRecordForKey (key);
        SecStatusCode resultCode;
        var match = SecKeyChain.QueryAsRecord(record, out resultCode);

        if (resultCode == SecStatusCode.Success)
            return NSString.FromData (match.ValueData, NSStringEncoding.UTF8);
        else
            return String.Empty;
    }

    public void SetValueForKey(string value, string key) 
    {
        var record = ExistingRecordForKey (key);            
        if (value.IsNullOrEmpty())
        {
            if (!ValueForKey(key).IsNullOrEmpty())
                RemoveRecord(record);

            return;
        }

        // if the key already exists, remove it
        if (!ValueForKey(key).IsNullOrEmpty())
            RemoveRecord(record);

        var result = SecKeyChain.Add(CreateRecordForNewKeyValue(key, value));
        if (result != SecStatusCode.Success)
        {
            throw new Exception(String.Format("Error adding record: {0}", result));
        }
    }

    private SecRecord CreateRecordForNewKeyValue(string key, string value)
    {
        return new SecRecord(SecKind.GenericPassword)
        {
            Account = key,
            Service = ServiceName,
            Label = key,
            ValueData = NSData.FromString(value, NSStringEncoding.UTF8),
        };
    }

    private SecRecord ExistingRecordForKey(string key)
    {
        return new SecRecord(SecKind.GenericPassword)
        {
            Account = key,
            Service = ServiceName,
            Label = key,
        };
    }

    private bool RemoveRecord(SecRecord record)
    {
        var result = SecKeyChain.Remove(record);
        if (result != SecStatusCode.Success)
        {
            throw new Exception(String.Format("Error removing record: {0}", result));
        }

        return true;
    }        
}

Comments

  1. Thank you so much Mark! I just spent the last three hours looking for something this simple. Most examples I had found seemed overly complicated and not generic enough to handle simple key/value data. I can't believe there aren't more examples of using Keychain for Xamarin iOS out there, anyways thank you!

    ReplyDelete
  2. Can You Provide Example of "How to share Keychain between iOS apps in XAMARIN"
    Reference:
    http://stackoverflow.com/questions/4115744/how-to-share-keychain-data-between-ios-applications
    http://evgenii.com/blog/sharing-keychain-in-ios/

    ReplyDelete
  3. what is ServiceName in your code? thanks!

    ReplyDelete
    Replies
    1. Actually not sure, I believe it's an extra value I forgot to take out of the code, there is a Service property on the SecRecord and you can set it to whatever you like. So you could pass in another string into the method (key, value, serviceName). I believe the purpose of Service separates the sets of key values into groups by Service.

      Delete

Post a Comment

Popular posts from this blog

Gradient UINavigationBar in Swift

How to shuffle an array in Swift