Borrar NSUserDefaults


Respuestas:


514

Puede eliminar el dominio persistente de la aplicación de esta manera:

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

En Swift 3 y posterior:

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

Esto es similar a la respuesta de @samvermette pero es un poco más limpio en mi opinión.


Esto funcionó muy bien, gracias! Simplemente no olvides lanzar appDomain después.
IcyBlueRose

15
@IcyBlueRose: bundleIdentifier es un objeto lanzado automáticamente, ya que no comienza con init o new, por lo que lo liberaría en exceso.
Christopher Rogers

1
¡Es bueno saberlo, gracias! Pero estaba hablando de la cadena appDomain. ¿Ese auto también se lanzó?
IcyBlueRose

2
@IcyBlueRose El objeto devuelto por bundleIdentifier es el mismo que el objeto al que hace referencia appDomain.
Christopher Rogers

2
Parece que ya no puedo hacer que esto funcione en 10.8, ¿alguien podría confirmar que esto funciona? Aquí hay una pregunta SO relacionada: stackoverflow.com/questions/13595415/…
DaGaMs

102

Este código restablece los valores predeterminados al dominio de registro:

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

En otras palabras, es removeObjectForKeypara cada clave que haya registrado en esa aplicación.

Créditos a Ken Thomases en este hilo de los foros de desarrolladores de Apple .


44
Gracias un montón. Por qué [NSUserDefaults resetStandardUserDefaults]no hace esto está más allá de mí.
jakeboxer

2
@jboxer Acabo de pasar un tiempo estudiando la documentación de Apple y resetStandardUserDefaults básicamente vacía el búfer en memoria en el disco y lo limpia. Entonces, la próxima vez que intente recuperar un valor, debe tomarlo del disco. NSManagedObjectContext de Core Data también utiliza una terminología similar de "restablecimiento".
Christopher Rogers

2
Vaya, quise decir que borra el búfer en memoria sin escribirlo en el disco. Por lo tanto, cualquier cambio que haya realizado antes de sincronizar con el disco se perderá.
Christopher Rogers

44
Christopher, creo que lo tienes al revés, aunque tal vez las cosas cambiaron. resetStandardUserDefaults es la llamada con el nombre más confuso que he visto hasta ahora en iOS. Los documentos de Apple dicen "Sincroniza cualquier cambio realizado en el objeto predeterminado del usuario compartido y lo libera de la memoria". por lo que realmente debería llamarse flushAndReleaseStandardUserDefaults. Me estoy tomando el tiempo para comentar un comentario anterior porque esta llamada me atrapó y quiero evitar que alguien más se queme (ahora tengo que decirle a un cliente que necesito actualizar 90 aplicaciones).
Andy Dent

97

¿Intentaste usar - removeObjectForKey?

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

Saludos sbooth. Muy apreciado.
TonyNeallon

55
¿Alguna forma de eliminar objetos para todas las claves existentes?
samvermette

2
Si bien entiendo que esto parece funcionar, ¿por qué defunctPreference no es un tipo de sistema definido constante? Seguramente estaría nervioso porque dejaría de funcionar algún día en el futuro.
David H

¿Tienes que sincronizar después?
Travis M.

30

Aquí está la respuesta en Swift:

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

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

3
O más seguro:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
Versión Swift 4 de la línea de Grace:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

Si lo necesita durante el desarrollo, también puede restablecer su simulador, eliminando todo NSUserDefaults.

Simulador de iOS -> Restablecer contenido y configuración ...

Tenga en cuenta que también eliminará todas las aplicaciones y archivos en el simulador.


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

7

En Swift:

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

6

Nota: Esta respuesta también se ha actualizado para Swift.

¿Qué hay de tenerlo en una línea?

Ampliando la respuesta de @ Christopher Rogers: la aceptada.

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

y sí, en algún momento puede necesitarlo synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

He creado un método para hacer esto,

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

Swift ?

Con Swift es aún más fácil.

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

Y uso :

UserDefaults.clean()

6

Me encantan las extensiones cuando hacen que el código sea más limpio:

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

Todas las respuestas anteriores son muy relevantes, pero si alguien aún no puede restablecer los valores predeterminados del usuario para la aplicación eliminada, puede restablecer la configuración de contenido de su simulador y funcionará.ingrese la descripción de la imagen aquí


2

Es un error o lo que sea, pero removePersistentDomainForNameno funciona mientras se borran todos los NSUserDefaultsvalores.

Por lo tanto, una mejor opción es restablecer el PersistentDomainy que puede hacerlo de la siguiente manera:

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

1

Ampliando la respuesta de @ folse ... Creo que una implementación más correcta sería ...

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

... llamando al método persistentDomainForName de NSUserDefault: método. Como dicen los documentos, el método "Devuelve un diccionario que contiene las claves y los valores en el dominio persistente especificado". Llamar a dictionaryRepresentation: en su lugar, devolverá un diccionario que probablemente incluirá otras configuraciones según se aplique a un alcance más amplio.

Si necesita filtrar alguno de los valores que se van a restablecer, iterar sobre las claves es la forma de hacerlo. Obviamente, si desea eliminar todas las preferencias de la aplicación sin tener en cuenta, entonces uno de los otros métodos publicados anteriormente es el más eficiente.



0

Prueba esto, está funcionando para mí.

Sola línea de código

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.