NSUserDefaultsのクリア


回答:


514

次のように、アプリケーションの永続ドメインを削除できます。

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

Swift 3以降の場合:

if let bundleID = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: bundleID)
}

これは@samvermetteの回答に似ていますが、IMOが少しすっきりしています。


これはうまくいきました、ありがとう!後でappDomainをリリースすることを忘れないでください。
IcyBlueRose 2011年

15
@IcyBlueRose-bundleIdentifierは、initまたはnewで始まっていないため自動解放されるオブジェクトであり、オーバーリリースすることになります。
Christopher Rogers

1
知ってよかった、ありがとう!しかし、私は文字列appDomainについて話していました。その自動車もリリースされますか?
IcyBlueRose 2011年

2
@IcyBlueRose bundleIdentifierによって返されるオブジェクトは、appDomainによって参照されるオブジェクトと同じです。
Christopher Rogers

2
これを10.8で動作させることができなくなったようです。この動作を確認してください。ここでは、関連のSOの質問です:stackoverflow.com/questions/13595415/...
DaGaMs

102

このコードは、デフォルトを登録ドメインにリセットします。

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];

つまり、removeObjectForKeyそのアプリでこれまでに登録したすべてのキーの1つです。

このApple Developer Forums スレッドの Ken Thomasesへの謝辞


4
本当にありがとう。なぜこれを[NSUserDefaults resetStandardUserDefaults]しないのかは私を超えています。
jakeboxer

2
@jboxer少し時間をかけてAppleのドキュメントを調べたところ、resetStandardUserDefaultsは基本的にメモリ内バッファーをディスクにフラッシュし、クリーンに消去しました。したがって、次に値を取得しようとすると、ディスクから取得する必要があります。Core DataのNSManagedObjectContextも同様の「リセット」用語を使用しています。
クリストファーロジャース

2
おっと、ディスクに書き込むことなくメモリ内のバッファを消去することを意味しました。したがって、ディスクと同期する前に行った変更は失われます。
Christopher Rogers、

4
クリストファー、おそらく状況は変わったかもしれませんが、あなたはそれを逆に持っていると思います。resetStandardUserDefaultsは、これまでiOSで見た中で最も紛らわしい名前の呼び出しです。Apple Docsは、「共有ユーザーのデフォルトオブジェクトに加えられた変更を同期し、メモリから解放する」と述べています。したがって、実際にはflushAndReleaseStandardUserDefaultsと呼ばれる必要があります。私はこのコメントに捕まったばかりで、他の誰かがやけどをしないようにしたいので、古いコメントに時間をかけてコメントしています(90個のアプリを更新する必要があることをクライアントに伝える必要があります)。
Andy Dent

97

使ってみましたremoveObjectForKeyか?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];

歓声ブース。とても有難い。
TonyNeallon、2009

5
既存のすべてのキーのオブジェクトを削除する方法はありますか?
samvermette 2010年

2
これは機能しているように見えますが、なぜdefunctPreferenceが何らかのシステム定義の定数でないのですか?将来いつかは働かなくなると緊張します。
David H

後で同期する必要がありますか?
Travis M.

30

これがSwiftの答えです:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)ワンライナー
Grace Shao

3
またはより安全:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
グレースのワンライナーのSwift 4バージョン:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

開発中に必要な場合は、シミュレータをリセットして、すべてのを削除することもできますNSUserDefaults

iOSシミュレータ->コンテンツと設定をリセット...

シミュレータ上のすべてのアプリとファイルも削除されることに注意してください。


15
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}

7

Swiftの場合:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }

6

注:この回答はSwiftでも更新されています。

それを1行にするにはどうでしょうか?

@Christopher Rogersの回答を拡張すると、受け入れられます。

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];

はい、いつか必要にsynchronizeなるかもしれませんが、

[[NSUserDefaults standardUserDefaults] synchronize];

これを行うメソッドを作成しました

- (void) clearDefaults {
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

スウィフト

迅速で、さらに簡単です。

extension UserDefaults {
    class func clean() {
        guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
        standard.removePersistentDomain(forName: aValidIdentifier)
        standard.synchronize()
    }
}

そして使用法

UserDefaults.clean()

6

コードをきれいにする拡張機能が大好きです:

extension NSUserDefaults {
    func clear() {
        guard let domainName = NSBundle.mainBundle().bundleIdentifier else {
            return
        }

        self.removePersistentDomainForName(domainName)
    }
}

スウィフト5

extension UserDefaults {
    func clear() {
        guard let domainName = Bundle.main.bundleIdentifier else {
            return
        }
        removePersistentDomain(forName: domainName)
        synchronize()
    }
}


2

上記のすべての回答は非常に関連性がありますが、誰かが削除されたアプリのuserdefaultsをリセットできない場合は、シミュレーターのコンテンツ設定をリセットでき、それは機能します。ここに画像の説明を入力してください


2

これはバグなどですが、removePersistentDomainForNameすべてのNSUserDefaults値をクリアしている間は機能しません。

したがって、より良いオプションは、をリセットPersistentDomainすることであり、次の方法で実行できます。

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)

1

@folseの答えを拡張して...より正確な実装は...

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: appDomain];
    for (NSString *key in [defaultsDictionary allKeys]) {
      NSLog(@"removing user pref for %@", key);
      [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
    }

... NSUserDefaultのpersistentDomainForName:メソッドを呼び出します。ドキュメントにあるように、メソッドは「指定された永続ドメインのキーと値を含む辞書を返します」。dictionaryRepresentationを呼び出すと、代わりに、より広いスコープに適用されるため、他の設定が含まれている可能性が高い辞書が返されます。

リセットする値のいずれかをフィルターで除外する必要がある場合は、キーを反復することでそれを行うことができます。言うまでもなく、アプリのすべての設定を考慮せずに処理したい場合は、上記の他の方法のいずれかが最も効率的です。


0

リセットが必要なアプリケーション設定がマイク(私の場合)へのアクセスのnsuserdefaultである場合、簡単な解決策は、Anthony McCormick(Iphone-デバイス上のメディアへのアプリケーションアクセスを有効にする方法?-ALAssetsLibraryErrorDomain Code = -3312 "Global denied access"からの回答です。)。

デバイスで、「設定」>「一般」>「リセット」>「場所の警告をリセット」に移動します


0

これを試してください、それは私のために働いています。

1行のコード

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.