Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What can cause NSUserDefaults to be cleared

I've been getting some odd reports for my app where the application settings stored into the NSUserDefaults is being cleared. The reports have all been on iOS 7s

I know you can manually clear the NSUserDefaults by either uninstalling or making a call to

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

But are there any other known causes for an app to clear its settings ?

like image 489
loadedion Avatar asked Apr 18 '14 15:04

loadedion


People also ask

How do you reset NSUserDefaults?

In the simulator top menu: Simulator -> Reset Content and Settings... Show activity on this post. You can use removePersistentDomainForName method available with NSUserDefaults Class.

What is NSUserDefaults in ios?

NSUserDefaults caches the information to avoid having to open the user's defaults database each time you need a default value. When you set a default value, it's changed synchronously within your process, and asynchronously to persistent storage and other processes. Important.


1 Answers

If you don't want to get your data deleted, then you should use KeyChain to store values. A good way to get started: Using KeyChain

Below I am providing an example code how to store and get data back from the KeyChain

Importing required frameworks

#import <Security/Security.h>

Storing values to KeyChain

NSString *key = @"Full Name";
NSString *value = @"Steve Jobs";
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
NSString *service = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *secItem = @{
                              (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : service,
                              (__bridge id)kSecAttrAccount : key,
                              (__bridge id)kSecValueData : valueData,
                              };
    CFTypeRef result = NULL;
    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);
if (status == errSecSuccess)
{
     NSLog(@"Successfully stored the value");
}
else{
     NSLog(@"Failed to store the value with code: %ld", (long)status);
}

Getting values back from KeyChain

NSString *keyToSearchFor = @"Full Name";
NSString *service = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *query = @{
                        (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : service,(__bridge id)kSecAttrAccount : keyToSearchFor,
                        (__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue, };
CFDictionaryRef valueAttributes = NULL;
OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query,
                                       (CFTypeRef *)&valueAttributes);
NSDictionary *attributes =
(__bridge_transfer NSDictionary *)valueAttributes;
if (results == errSecSuccess){
    NSString *key, *accessGroup, *creationDate, *modifiedDate, *service;
    key = attributes[(__bridge id)kSecAttrAccount];
    accessGroup = attributes[(__bridge id)kSecAttrAccessGroup]; creationDate = attributes[(__bridge id)kSecAttrCreationDate]; modifiedDate = attributes[(__bridge id)kSecAttrModificationDate]; service = attributes[(__bridge id)kSecAttrService];
    NSLog(@"Key = %@\n \ Access Group = %@\n \
          Creation Date = %@\n \
          Modification Date = %@\n \
          Service = %@", key, accessGroup, creationDate, modifiedDate, service);
}
else
{
    NSLog(@"Error happened with code: %ld", (long)results);
}
like image 89
E-Riddie Avatar answered Sep 20 '22 16:09

E-Riddie