253

我正在使用idandersen 的 scifihifi-iphone代码作为钥匙串并使用保存密码

[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
              forServiceName:@"TestService" updateExisting:YES error:&error];

当我从设备中删除应用程序时,密码仍保留在钥匙串中。

当用户从设备中删除应用程序时,我想从钥匙串中删除密码。我怎样才能做到这一点?

4

9 回答 9

425

您可以利用通过卸载应用程序清除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”键/值,以防用户在系统保留之前手动终止应用程序。

于 2011-06-01T15:00:51.877 回答
50

对于寻找@amro 答案的Swift 3.0版本的用户:

let userDefaults = UserDefaults.standard

if !userDefaults.bool(forKey: "hasRunBefore") {
     // Remove Keychain items here

     // Update the flag indicator
     userDefaults.set(true, forKey: "hasRunBefore")
}

*注意 synchronize() 函数已被弃用

于 2016-11-22T02:04:56.937 回答
32

从设备中删除应用程序时,没有执行代码的触发器。对钥匙串的访问取决于用于签署应用程序的配置文件。因此,没有其他应用程序能够访问钥匙串中的此信息。

当用户从设备中删除应用程序时,它对您旨在删除钥匙串中的密码没有帮助,但它应该让您感到安慰的是密码无法访问(仅通过重新安装原始应用程序)。

于 2011-04-19T02:52:04.897 回答
29

对于那些寻找@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
    }
于 2015-10-24T14:18:20.527 回答
10

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);
        }
于 2018-03-02T08:16:12.190 回答
8

当用户卸载应用程序时,文件将从应用程序的文档目录中删除。知道了这一点,您所要做的就是检查文件是否存在作为application:didFinishLaunchingWithOptions:. 之后,无条件地创建文件(即使它只是一个虚拟文件)。

如果在检查时该文件不存在,则您知道这是自最新安装以来的第一次运行。如果您需要稍后在应用程序中知道,请将布尔结果保存到您的应用程序委托成员。

于 2013-09-14T02:19:40.590 回答
8

@amro 的答案翻译为 Swift 4.0:

if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
    UserDefaults.standard.set(false, forKey: "FirstInstall")
    UserDefaults.standard.synchronize()
}
于 2018-05-09T07:55:32.780 回答
3

根据人们在 beta #2 中看到的行为,这似乎是 iOS 10.3 上的默认行为。尚未找到任何有关此的官方文档,因此如果有,请发表评论。

于 2017-02-21T07:39:23.183 回答
0

只需添加一个应用程序设置包并实现一个切换以在应用程序重新启动时重置钥匙串或基于通过设置选择的值(可通过 userDefaults 获得)

于 2020-12-14T17:08:26.753 回答