我正在使用idandersen的scifihifi-iphone代码来操作钥匙串,并保存密码。
[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
forServiceName:@"TestService" updateExisting:YES error:&error];
在设备上删除应用程序后,密码仍然存在于钥匙串中。
我希望在用户从设备中删除应用程序时从钥匙串中删除密码。我该怎么做?
我正在使用idandersen的scifihifi-iphone代码来操作钥匙串,并保存密码。
[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
forServiceName:@"TestService" updateExisting:YES error:&error];
在设备上删除应用程序后,密码仍然存在于钥匙串中。
我希望在用户从设备中删除应用程序时从钥匙串中删除密码。我该怎么做?
你可以利用NSUserDefaults
被应用卸载时清除这一事实。例如:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Clear keychain on first run in case of reinstallation
if (![[NSUserDefaults standardUserDefaults] objectForKey:@"FirstRun"]) {
// Delete values from keychain here
[[NSUserDefaults standardUserDefaults] setValue:@"1strun" forKey:@"FirstRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//...Other stuff that usually happens in didFinishLaunching
}
如果尚未设置,此代码将检查并在应用程序的第一次运行时在NSUserDefaults
中设置“FirstRun”键/值。在您应该放置从密钥链中删除值的代码处有一条注释。可以调用Synchronize来确保“FirstRun”键/值立即持久化,以防用户在系统持久化之前手动杀死应用程序。
对于寻找Swift 3.0版本@amro答案的用户:
let userDefaults = UserDefaults.standard
if !userDefaults.bool(forKey: "hasRunBefore") {
// Remove Keychain items here
// Update the flag indicator
userDefaults.set(true, forKey: "hasRunBefore")
}
*请注意,synchronize()函数已被弃用
if !userDefaults.bool(forKey: "hasRunBefore") {
这样写更简洁。 - nefarianblack当应用程序从设备中删除时,没有触发器执行代码。访问钥匙串取决于用于签署应用程序的配置文件。因此,其他应用程序将无法访问钥匙串中的此信息。
如果用户从设备中删除应用程序,它无法帮助您删除钥匙串中的密码,但应使您感到安心,因为密码是不可访问的(仅通过重新安装原始应用程序才能访问)。
对于那些寻求@amro答案的Swift版本的人:
let userDefaults = NSUserDefaults.standardUserDefaults()
if userDefaults.boolForKey("hasRunBefore") == false {
// remove keychain items here
// update the flag indicator
userDefaults.setBool(true, forKey: "hasRunBefore")
userDefaults.synchronize() // forces the app to update the NSUserDefaults
return
}
C# Xamarin 版本
const string FIRST_RUN = "hasRunBefore";
var userDefaults = NSUserDefaults.StandardUserDefaults;
if (!userDefaults.BoolForKey(FIRST_RUN))
{
//TODO: remove keychain items
userDefaults.SetBool(true, FIRST_RUN);
userDefaults.Synchronize();
}
...并从钥匙串中清除记录(在上面的TODO评论)
var securityRecords = new[] { SecKind.GenericPassword,
SecKind.Certificate,
SecKind.Identity,
SecKind.InternetPassword,
SecKind.Key
};
foreach (var recordKind in securityRecords)
{
SecRecord query = new SecRecord(recordKind);
SecKeyChain.Remove(query);
}
if (VersionTracking.IsFirstLaunchEver) {// remove keychain items}
,您无需编写 userDefaults
的代码。Xamarin.Essentials 会为您封装它。 - Christopher Stephan@amro的答案转换为Swift 4.0:
if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
UserDefaults.standard.set(false, forKey: "FirstInstall")
UserDefaults.standard.synchronize()
}
if !UserDefaults.standard.bool(forKey: "FirstInstall")
,如果键不存在,默认为 false。不需要 .synchronize()。 - CharlesAapplication:didFinishLaunchingWithOptions:
方法中,您只需要首先检查文件是否存在即可。之后,无条件地创建文件(即使它只是一个虚拟文件)。根据beta #2中的观察,这似乎是iOS 10.3的默认行为。如果您有官方文档,请在下面评论。