我正在研究Xamarin跨平台的本机项目,我必须同时存储令牌(登录后从服务器获取)和Android和IOS端。在Android方面,我使用了SharedPreferences,效果很好,但找不到IOS的解决方案。现在我正在使用KeyChain,但结果总是错误的。
这是我的代码:
KeyChain类:
using System;
using Foundation;
using Security;
namespace BloodNotes.iOS
{
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 == "")
{
if (ValueForKey(key) != "")
RemoveRecord(record);
return;
}
// if the key already exists, remove it
if (ValueForKey(key) != "")
RemoveRecord(record);
var result = SecKeyChain.Add(CreateRecordForNewKeyValue(key, value));
if (result != SecStatusCode.Success)
{
throw new Exception(String.Format("Error adding record: " + result)); // I ALWAYS GET THIS EXCEPTION
}
}
private SecRecord CreateRecordForNewKeyValue(string key, string value)
{
return new SecRecord(SecKind.GenericPassword)
{
Account = key,
ValueData = NSData.FromString(value, NSStringEncoding.UTF8),
};
}
private SecRecord ExistingRecordForKey(string key)
{
return new SecRecord(SecKind.GenericPassword)
{
Account = key,
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;
}
}
}
和TokenService:
using BloodNotes.ViewModel;
using Foundation;
using System.Diagnostics;
namespace BloodNotes.iOS.TokenService
{
class TokenService : Service.ITokenService
{
public const string KEY = "token";
public void SaveToken(string token)
{
KeyChain storage = new KeyChain();
storage.SetValueForKey(token, KEY);
Debug.WriteLine("RESULT: " + storage.ValueForKey(KEY));
}
}
}
请给我建议。
提前感谢您的回答!
答案 0 :(得分:0)
最后,我找到了解决方案。使用NSUserDefaults.StandardUserDefaults代替KeyChain,所以我的TokenService如下:
using Foundation;
using System.Diagnostics;
namespace BloodNotes.iOS.TokenService
{
class TokenService : Service.ITokenService
{
public const string KEY = "token";
public void SaveToken(string token)
{
var storage = NSUserDefaults.StandardUserDefaults;
NSString value = new NSString(token);
NSString key = new NSString(KEY);
storage.SetValueForKey(value, key);
Debug.WriteLine("RESULT: " + storage.ValueForKey(key).ToString());
}
}
}