アプリのアンインストール時にキーチェーンアイテムを削除する


238

私はキーホルダーにidandersenのscifihifi-iphoneコードを使用しており、使用してパスワードを保存しています

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

デバイスからアプリケーションを削除しても、パスワードはキーチェーンに残ります。

ユーザーがデバイスからアプリケーションを削除したときに、キーチェーンからパスワードを削除したいのですが。これどうやってするの?


13
アプリケーションが削除されている間はコードが実行されないため、これを行う方法はありません。
ジョナサングリンスパン、2011年

1
キーチェーンアイテムはアプリ内からのみ削除でき、アンインストール前には削除できないと思います。SFHFKeychainUtilsのdeleteItemメソッドを見て、キーチェーンからユーザー名またはパスワードを削除できます。
matteodv

回答:


406

あなたは事実を利用することができます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
}

これにより、「FirstRun」キー/値がNSUserDefaultsまだ設定されていない場合は、アプリの最初の実行時にチェックされ、設定されます。キーチェーンから値を削除するためのコードを配置する必要があるコメントがあります。Synchronizeを呼び出して、システムが永続化する前にユーザーがアプリを手動で終了した場合に備えて、「FirstRun」キー/値がすぐに永続化されるようにすることができます。


2
アプリケーションの最初の実行時にキーチェーンを削除/パージできることにアムロは同意します。これにより、アプリが最後にアンインストールされる前に設定されていたすべてがクリアされます。私はFacebook / Twitterの認証情報を保存するアプリの1つでこれを行いましたが、設定されているキーチェーンにアクセスできるのはアプリだけであることを知っているので、うまく機能しています。
XCool

このヒントをありがとう。
iOSAppDev 2013

3
ユーザーがアプリを手動で終了しても、NSUserDefaultsはクリアされません。その場合、設定した値だけsynchronizeが失われますが、システム(定期的)またはまだディスクと同期していない(を呼び出すことによる)値は失われます。最初の実行キーを設定した後、synchronizeを呼び出すことをお勧めします。そして、はい、NSUserDefaultsは、デバイスがリセットされたときに(バックアップから復元されずに)クリアされます。この場合は問題ありません。
Amro 2013

5
あなたは間違っており、おそらくユーザーのデフォルトをクリアする原因となっていることをしています。NSUserDefaultsの全体のポイントは、設定を保存し、それらの設定を複数のアプリケーションの起動を通じて保持することです。繰り返しますが、デバイスをリセットするか、アプリを削除すると、ユーザーのデフォルトが削除されます。この回答に賛成票を投じた人の数を調べ、コードを確認してください。次に、ドキュメントを読みます。では、関連するコードを送ってください。あなたが間違っていることをお見せします。iOS 2.0以降、このようになっています。反対票を投じますが、最初に、分離された単純なテストケースを作成することをお勧めします。
Amro

9
このためにNSUserDefaultを使用することに自信はありません。どうして?そのスレッドを見てください:stackoverflow.com/questions/20269116/…。アプリをバックグラウンドで起動した場合、NSUserDefaultsのカスタムキーが設定されていない場合があります。この回答を適用すると、キーチェーンのカスタムキーが削除されてしまいますが、実際には削除したくありません。
Aurelien Porte 2014

40

@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()関数は廃止されることに注意してください


2
if !userDefaults.bool(forKey: "hasRunBefore") {ただきれいです。
nefarianblack

1
同期呼び出しは削除する必要があります。
ポチ

30

アプリがデバイスから削除されたときにコードを実行するトリガーはありません。キーチェーンへのアクセスは、アプリケーションの署名に使用されるプロビジョニングプロファイルによって異なります。したがって、他のアプリケーションはキーチェーン内のこの情報にアクセスできません。

ユーザーがデバイスからアプリケーションを削除するときに、キーチェーン内のパスワードを削除することは目的としては役立ちませんが、(元のアプリケーションの再インストールからのみ)パスワードにアクセスできないという安心感を与えるはずです。


したがって、アプリケーションのプロビジョニングプロファイルを変更すると、キーチェーンに以前に保存された値にアクセスできるようになります。
Moaz Saeed

27

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

9

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

1
if (VersionTracking.IsFirstLaunchEver) {// remove keychain items}Xamarin.Essentialsから使用することで、のコードは必要ありませんuserDefaultsXamarin.Essentialsがそれをラップします
クリストファーステファン

7

ユーザーがアプリをアンインストールすると、アプリのドキュメントディレクトリからファイルが削除されます。これを知って、あなたがしなければならないのは、ファイルがで最初に起こることとして存在するかどうかをチェックすることだけですapplication:didFinishLaunchingWithOptions:。その後、無条件にファイルを作成します(たとえダミーファイルであっても)。

チェック時にファイルが存在しなかった場合、これは最新のインストール以降の最初の実行であることがわかります。後でアプリで知る必要がある場合は、ブール結果をアプリデリゲートメンバーに保存します。


7

@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()は不要です。
CharlesA

3

これは、人々がベータ2で目撃ている行動に基づくiOS 10.3のデフォルトの行動のようです。これに関する公式のドキュメントはまだ見つかりません。コメントがあればコメントしてください。


7
ベータ5までだったと思います。iOS10.3のパブリックリリースにはこの変更含まれていません
JakubTruhlář2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.