Suppression de NSUserDefaults


Réponses:


514

Vous pouvez supprimer le domaine persistant de l'application comme ceci:

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

Dans Swift 3 et versions ultérieures:

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

Ceci est similaire à la réponse de @samvermette mais est un peu plus propre OMI.


Cela a très bien fonctionné, merci! N'oubliez pas de libérer appDomain par la suite.
IcyBlueRose

15
@IcyBlueRose - bundleIdentifier est un objet libéré automatiquement car il ne commence pas par init ou new, vous devriez donc le sur-relâcher.
Christopher Rogers

1
Bon à savoir, merci! Mais je parlais de la chaîne appDomain. Est-ce que cette voiture est également sortie?
IcyBlueRose

2
@IcyBlueRose L'objet renvoyé par bundleIdentifier est le même que l'objet référencé par appDomain.
Christopher Rogers

2
Je n'arrive plus à faire fonctionner cela sur 10.8, est-ce que quelqu'un pourrait confirmer que cela fonctionne? Voici une question SO connexe: stackoverflow.com/questions/13595415/…
DaGaMs

102

Ce code réinitialise les valeurs par défaut au domaine d'enregistrement:

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

En d'autres termes, cela removeObjectForKeypour chaque clé que vous avez déjà enregistrée dans cette application.

Crédits à Ken Thomases sur ce fil de discussion des développeurs Apple .


4
Merci beaucoup. Pourquoi [NSUserDefaults resetStandardUserDefaults]ne fait pas cela me dépasse.
jakeboxer

2
@jboxer Je viens de passer un peu de temps à étudier la documentation Apple et resetStandardUserDefaults vide essentiellement le tampon en mémoire sur le disque et l'efface. Donc, la prochaine fois que vous essayez de récupérer une valeur, il doit la récupérer sur le disque. NSManagedObjectContext de Core Data utilise également une terminologie de «réinitialisation» similaire.
Christopher Rogers

2
Oups, je voulais dire qu'il efface le tampon en mémoire sans l'écrire sur le disque. Ainsi, toutes les modifications apportées avant la synchronisation sur le disque seront perdues.
Christopher Rogers

4
Christopher, je pense que tu l'as à l'envers bien que les choses aient peut-être changé. resetStandardUserDefaults est l'appel le plus déroutant que j'ai vu jusqu'à présent dans iOS. Les Apple Docs disent "Synchronise toutes les modifications apportées à l'objet par défaut de l'utilisateur partagé et le libère de la mémoire." il faut donc vraiment l'appeler flushAndReleaseStandardUserDefaults. Je prends le temps de commenter un ancien commentaire parce que je viens de me faire prendre par cet appel et que je veux éviter que quelqu'un d'autre ne soit brûlé (je dois maintenant dire à un client que je dois mettre à jour 90 applications).
Andy Dent

97

Avez-vous essayé d'utiliser - removeObjectForKey?

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

Bravo sbooth. Très appréciée.
TonyNeallon

5
Est-il possible de supprimer un objet pour toutes les clés existantes?
samvermette du

2
Bien que je comprenne que cela semble fonctionner, pourquoi defunctPreference n'est-il pas une sorte de système défini constant? Je serais certainement nerveux que cela cesserait de fonctionner un jour à l'avenir.
David H

Devez-vous synchroniser après?
Travis M.

30

Voici la réponse dans Swift:

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

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)one-liner
Grace Shao

3
Ou plus sûr:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
Version Swift 4 de la doublure de Grace:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

Si vous en avez besoin lors du développement, vous pouvez également réinitialiser votre simulateur, en supprimant tous les NSUserDefaults.

iOS Simulator -> Réinitialiser le contenu et les paramètres ...

Gardez à l'esprit qu'il supprimera également toutes les applications et tous les fichiers du simulateur.


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

7

Dans Swift:

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

6

Remarque: Cette réponse a également été mise à jour pour Swift.

Qu'en est-il de l'avoir sur une seule ligne?

Étendre la réponse de @Christopher Rogers - celle qui est acceptée.

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

et oui, parfois vous en aurez besoin synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

J'ai créé une méthode pour ce faire,

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

Rapide ?

Avec rapide, c'est encore plus facile.

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

Et l'utilisation :

UserDefaults.clean()

6

J'adore les extensions quand elles rendent le code plus propre:

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


2

Toutes les réponses ci-dessus sont très pertinentes, mais si quelqu'un ne peut toujours pas réinitialiser les paramètres utilisateur pour l'application supprimée, vous pouvez réinitialiser les paramètres de contenu de votre simulateur, et cela fonctionnera.entrez la description de l'image ici


2

C'est un bug ou autre mais le removePersistentDomainForNamene fonctionne pas en effaçant toutes les NSUserDefaultsvaleurs.

Donc, la meilleure option est de réinitialiser le PersistentDomainet que vous pouvez faire de la manière suivante:

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

1

Développer la réponse de @ folse ... Je pense qu'une mise en œuvre plus correcte serait ...

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

... appel de la méthode persistentDomainForName: de NSUserDefault. Comme l'indique la documentation, la méthode "Renvoie un dictionnaire contenant les clés et les valeurs dans le domaine persistant spécifié". Appel à dictionaryRepresentation: renvoie un dictionnaire qui inclura probablement d'autres paramètres, car il s'applique à une portée plus large.

Si vous devez filtrer l'une des valeurs à réinitialiser, alors itérer sur les clés est le moyen de le faire. De toute évidence, si vous souhaitez simplement supprimer toutes les préférences de l'application sans égard, l'une des autres méthodes publiées ci-dessus est la plus efficace.



0

Essayez ça, ça marche pour moi.

Une seule ligne de code

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.