NSUserDefaults löschen

Antworten:

514

Sie können die persistente Domäne der Anwendung folgendermaßen entfernen:

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

In Swift 3 und höher:

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

Dies ähnelt der Antwort von @samvermette, ist aber IMO ein bisschen sauberer.

Christopher Rogers
quelle
Das hat super geklappt, danke! Vergessen Sie nicht, appDomain danach freizugeben.
IcyBlueRose
15
@IcyBlueRose - bundleIdentifier ist ein automatisch freigegebenes Objekt, da es nicht mit init oder new beginnt, sodass Sie es übermäßig freigeben würden.
Christopher Rogers
1
Gut zu wissen, danke! Aber ich habe über die String-AppDomain gesprochen. Wird das auch automatisch veröffentlicht?
IcyBlueRose
2
@IcyBlueRose Das von bundleIdentifier zurückgegebene Objekt entspricht dem Objekt, auf das von appDomain verwiesen wird.
Christopher Rogers
2
Ich kann nicht mehr scheinen, dass dies auf 10.8 funktioniert. Könnte jemand bitte bestätigen, dass dies funktioniert? Hier ist eine verwandte SO-Frage: stackoverflow.com/questions/13595415/…
DaGaMs
102

Dieser Code setzt die Standardeinstellungen auf die Registrierungsdomäne zurück:

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

Mit anderen Worten, es removeObjectForKey für jeden einzelnen Schlüssel, den Sie jemals in dieser App registriert haben.

Dank an Ken Thomases in diesem Thread des Apple Developer Forums .

Samvermette
quelle
4
Vielen Dank. Warum [NSUserDefaults resetStandardUserDefaults]das nicht so ist, ist mir ein Rätsel.
Jakeboxer
2
@jboxer Ich habe gerade einige Zeit damit verbracht, die Apple-Dokumentation zu studieren und resetStandardUserDefaults löscht den In-Memory-Puffer im Grunde genommen auf die Festplatte und löscht ihn sauber. Wenn Sie also das nächste Mal versuchen, einen Wert abzurufen, muss dieser von der Festplatte abgerufen werden. Der NSManagedObjectContext von Core Data verwendet ebenfalls eine ähnliche "Reset" -Terminologie.
Christopher Rogers
2
Hoppla, ich meinte, dass es den In-Memory-Puffer löscht, ohne ihn auf die Festplatte zu schreiben. Alle Änderungen, die Sie vor der Synchronisierung mit der Festplatte vorgenommen haben, gehen verloren.
Christopher Rogers
4
Christopher, ich denke du hast es rückwärts, obwohl sich vielleicht die Dinge geändert haben. resetStandardUserDefaults ist der verwirrendste Aufruf, den ich bisher in iOS gesehen habe. In den Apple Docs heißt es: "Synchronisiert alle Änderungen, die am Standardobjekt des freigegebenen Benutzers vorgenommen wurden, und gibt es aus dem Speicher frei." Daher sollte es wirklich flushAndReleaseStandardUserDefaults heißen. Ich nehme mir die Zeit, um einen alten Kommentar zu kommentieren, weil ich gerade von diesem Anruf erwischt wurde und verhindern möchte, dass andere verbrannt werden (ich muss jetzt einem Client mitteilen, dass ich 90 Apps aktualisieren muss).
Andy Dent
97

Haben Sie versucht, - zu verwenden removeObjectForKey?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];
sbooth
quelle
Prost sbooth. Sehr geschätzt.
TonyNeallon
5
Gibt es eine Möglichkeit, Objekte für alle vorhandenen Schlüssel zu entfernen?
Samvermette
2
Obwohl ich verstehe, dass dies zu funktionieren scheint, warum ist defunctPreference nicht eine Art systemdefinierte Konstante? Ich wäre sicher nervös, dass es eines Tages aufhören würde zu arbeiten.
David H
Müssen Sie danach synchronisieren?
Travis M.
30

Hier ist die Antwort in Swift:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)
juliensaad
quelle
8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)Einzeiler
Grace Shao
3
Oder sicherer:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin
1
Swift 4 Version von Grace Oneliner:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann
28

Wenn Sie es während der Entwicklung benötigen, können Sie auch Ihren Simulator zurücksetzen und alle löschen NSUserDefaults.

iOS Simulator -> Inhalt und Einstellungen zurücksetzen ...

Beachten Sie, dass auch alle Apps und Dateien im Simulator gelöscht werden.

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

In Swift:

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

Hinweis: Diese Antwort wurde auch für Swift aktualisiert.

Was ist mit einer Zeile?

Erweitern der Antwort von @Christopher Rogers - die akzeptierte.

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

und ja, irgendwann müssen Sie es vielleicht brauchen synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

Ich habe eine Methode dafür erstellt,

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

Schnell ?

Mit Swift ist es noch einfacher.

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

Und Verwendung :

UserDefaults.clean()
Hemang
quelle
6

Ich liebe Erweiterungen, wenn sie den Code sauberer machen:

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

        self.removePersistentDomainForName(domainName)
    }
}

Swift 5

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

Ich habe das gefunden:

osascript -e 'tell application "iOS Simulator" to quit'
xcrun simctl list devices | grep -v '^[-=]' | cut -d "(" -f2 | cut -d ")" -f1 | xargs -I {} xcrun simctl erase "{}"

Quelle: https://gist.github.com/ZevEisenberg/5a172662cb576872d1ab

Daniel Gomez Rico
quelle
2

Alle oben genannten Antworten sind sehr relevant. Wenn jedoch jemand die Benutzerstandards für die gelöschte App immer noch nicht zurücksetzen kann, können Sie die Inhaltseinstellungen Ihres Simulators zurücksetzen, und es funktioniert.Geben Sie hier die Bildbeschreibung ein

iDevAmit
quelle
2

Es ist ein Fehler oder was auch immer, aber das removePersistentDomainForNamefunktioniert nicht, während alle NSUserDefaultsWerte gelöscht werden.

Die bessere Option ist also, das zurückzusetzen PersistentDomainund dies auf folgende Weise zu tun:

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)
Sohil R. Memon
quelle
1

Die Antwort von @ folse erweitern ... Ich glaube, eine korrektere Implementierung wäre ...

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

... Aufruf der persistentDomainForName: -Methode von NSUserDefault. Wie in den Dokumenten angegeben, gibt die Methode "Ein Wörterbuch zurück, das die Schlüssel und Werte in der angegebenen persistenten Domäne enthält". Wenn Sie dictionaryRepresentation aufrufen, wird stattdessen ein Wörterbuch zurückgegeben, das wahrscheinlich andere Einstellungen enthält, da es für einen größeren Bereich gilt.

Wenn Sie einen der zurückzusetzenden Werte herausfiltern müssen, können Sie dies über die Schlüssel wiederholen. Wenn Sie einfach alle Einstellungen für die App ohne Rücksicht auf Nuklearwaffen ändern möchten, ist eine der anderen oben beschriebenen Methoden die effizienteste.

markeissler
quelle
0

Wenn die Anwendungseinstellung, die zurückgesetzt werden muss, nsuserdefault für den Zugriff auf das Mikrofon ist (mein Fall), ist eine einfache Lösung die Antwort von Anthony McCormick ( Iphone - So aktivieren Sie den Anwendungszugriff auf Medien auf dem Gerät? - ALAssetsLibraryErrorDomain Code = -3312 "Global verweigerter Zugriff" ).

Gehen Sie auf dem Gerät zu Einstellungen> Allgemein> Zurücksetzen> Standortwarnungen zurücksetzen

tmr
quelle
0

Versuchen Sie dies, es funktioniert für mich.

Einzelne Codezeile

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Jaywant Khedkar
quelle