Keychain はアプリをアンインストールしても消えませんが、NSUserDefaults は消えます。
この違いを利用してアプリの再インストール(アプリを消す => 再度インストール)を検出することができます。
具体的にはアプリ起動時に Keychain, NSUserDefaults にそれぞれ YES を書き込むことにします。
そして、YES を書き込む前に BOOL 値を取得するようにします。この値は下記の表のように定まります。
状況 | Keychain | NSUserDefaults |
---|---|---|
インストールして起動した | NO | NO |
インストールして二回目起動した | YES | YES |
再インストールして起動した | YES | NO |
再インストールして二回目起動した | YES | YES |
再々インストールして起動した | YES | NO |
再々インストールして二回目起動した | YES | YES |
アプデなどで、このアルゴリズムを新規導入して初めて起動 | NO | NO |
この表より、Keychain からは YES, NSUserDefaults からは NO が取得できればアプリが再インストールされたといえます。
お手軽 Keychain ライブラリであるところの LUKeychainAccess
を使えば次のようなコードで再インストールが検出できます。
NSString *kFLMIsReInstallKey = @"FLMIsReInstall";
- (BOOL)isReInstall {
BOOL isReInstall = NO;
BOOL isSetInKeychain = [[[LUKeychainAccess standardKeychainAccess] objectForKey:isReInstallKey] boolValue];
BOOL isSetInUserDefaults = [[NSUserDefaults standardUserDefaults] boolForKey:isReInstallKey];
if (isSetInKeychain == YES && isSetInUserDefaults == NO) {
isReInstall = YES;
}
[[LUKeychainAccess standardKeychainAccess] setObject:@YES forKey:isReInstallKey];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:isReInstallKey];
}
注意点として、このコード片は呼ぶたびに値が変わってしまいます。(再インストール後に呼ぶと YES ですが、さらにもう一度呼ぶと NO になります)
まあどこかしらに値をキャッシュさせておけば OK です。