c# - 无法从 Xamarin iOS SecKeychain 检索 GUID

标签 c# ios xamarin.ios

在我的 Xamarin iOS 应用程序中,我将 DeviceId 和 AccessToken 存储在钥匙串(keychain)中。为了保存和检索访问 token ,我的代码工作正常,但对于设备 ID(它是一个 GUID),在保存设备 ID 时它给出的结果为 DuplicateItem,在检索设备 ID 时它将结果作为 ItemNotFound。我对设备 ID 和访问 token 使用单独的 key 。这是我的代码

public const string DEVICE_ID = "DEVICE_ID";
public const string ACCESS_TOKEN = "ACCESS_TOKEN";

public static string GetValue(string key)
{
    var query = new SecRecord(SecKind.GenericPassword)
    {
       Generic = NSData.FromString(key)
    };

    SecStatusCode result;
    var match = SecKeyChain.QueryAsRecord(query, out result);
    if (result == SecStatusCode.Success)
    {
       return match.ValueData.ToString();
    }
    return string.Empty;
}

public static void SetValue(string value, string key)
{
    var query = new SecRecord(SecKind.GenericPassword)
    {
       ValueData = NSData.FromString(value),
       Generic = NSData.FromString(key)
    };

    var result = SecKeyChain.Add(query);
}

我通过像这样的方法调用保存并获取设备 ID

SetValue(Guid.NewGuid(), DEVICE_ID); 
string deviceId = GetValue(DEVICE_ID);

它可能看起来很奇怪,但我不知道为什么会这样,有没有人遇到过这个问题或者我的代码中有没有错误。请帮助我。

最佳答案

这是我们用于存储和检索 SecKeyChain 的类,我建议使用我们的类,看看您是否会得到相同的结果。

using Security;
using Foundation;

public class KeyChain
{
    public const string DEVICE_ID = "DEVICE_ID";
    public const string ACCESS_TOKEN = "ACCESS_TOKEN";

    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;
    }        
}

那么您要从中检索信息的类和/或方法将如下所示:

public class OtherClass
{
    Public void GetInfo()
    {
        // Store device id
        KeyChain.SetValueForKey(Guid.NewGuid(), KeyChain.DEVICE_ID);

        // Retrieve device id
        string value = KeyChain.ValueForKey(DEVICE_ID);

        // Store access token
        KeyChain.SetValueForKey(Guid.NewGuid(), KeyChain.ACCESS_TOKEN);

        // Retrie acce token
        string value = KeyChain.ValueForKey(ACCESS_TOKEN);
    }
}

关于c# - 无法从 Xamarin iOS SecKeychain 检索 GUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45235058/

相关文章:

xamarin.ios - 是否有关于 MonoTouch AOT 助手的 ServiceStack.Text.JSConfig 文档?

c# - 如何使用线程模拟 Task.Wait

c# - HttpWebRequest AddRange 方法查询

ios - UIView 从顶部添加填充

ios - 适用于iOS的Facebook SDK权限问题

xamarin.ios - 如何在 monotouch 中使用 objc_setAssociatedObject

c# - Monotouch OpenGL 类型和 Cocos2d

c# - 在 asp.net 中发送具有特定名称而不是发件人电子邮件的电子邮件

c# - 如何在 Azure 应用服务中将 X509Certificate2 与 WCF 结合使用

ios - Objective-c 如何对 textField 进行验证