62

I have two NSMutableArray's. They consist of images or text. The arrays are displayed via a UITableView. When I kill the app the data within the UITableView gets lost. How to save array in UITableView by using NSUserDefault?

Suragch
  • 364,799
  • 232
  • 1,155
  • 1,198
user2841148
  • 661
  • 1
  • 8
  • 11

9 Answers9

113

Note: NSUserDefaults will always return an immutable version of the object you pass in.

To store the information:

// Get the standardUserDefaults object, store your UITableView data array against a key, synchronize the defaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:arrayOfImage forKey:@"tableViewDataImage"];
[userDefaults setObject:arrayOfText forKey:@"tableViewDataText"];
[userDefaults synchronize];

To retrieve the information:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayOfImages = [userDefaults objectForKey:@"tableViewDataImage"];
NSArray *arrayOfText = [userDefaults objectForKey:@"tableViewDataText"];
// Use 'yourArray' to repopulate your UITableView

On first load, check whether the result that comes back from NSUserDefaults is nil, if it is, you need to create your data, otherwise load the data from NSUserDefaults and your UITableView will maintain state.

Update

In Swift-3, the following approach can be used:

let userDefaults = UserDefaults.standard

userDefaults.set(arrayOfImage, forKey:"tableViewDataImage")
userDefaults.set(arrayOfText, forKey:"tableViewDataText")
userDefaults.synchronize()

var arrayOfImages = userDefaults.object(forKey: "tableViewDataImage")
var arrayOfText = userDefaults.object(forKey: "tableViewDataText")
Guy Kahlon
  • 4,490
  • 4
  • 25
  • 40
Tim
  • 8,206
  • 3
  • 40
  • 64
46

You can save your mutable array like this:

[[NSUserDefaults standardUserDefaults] setObject:yourArray forKey:@"YourKey"];
[[NSUserDefaults standardUserDefaults] synchronize];

Later you get the mutable array back from user defaults. It is important that you get the mutable copy if you want to edit the array later.

NSMutableArray *yourArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"YourKey"] mutableCopy];

Then you simply set the UITableview data from your mutable array via the UITableView delegate

Hope this helps!

shim
  • 7,170
  • 10
  • 62
  • 95
Philipp Otto
  • 3,722
  • 2
  • 27
  • 47
  • You just declare 2 different mutable arrays and save them for different keys in the user defaults. – Philipp Otto Oct 28 '13 at 12:26
  • If i use this code arrays are not load in UITableview. it show null value in nslog – user2841148 Oct 28 '13 at 12:58
  • As I wrote you will set the ui table view data via the ui table view delegate. Read this one: http://tech.pro/tutorial/1026/how-to-create-and-populate-a-uitableview – Philipp Otto Oct 28 '13 at 13:23
  • Thank you, you are a life saver. The "mutableCopy" bit at the end is vital. Otherwise even if you store the data back in an NSMutableArray, the contents will still be immutable. Thanks so much :) – Supertecnoboff Feb 20 '15 at 18:13
  • 1
    [Note: It is not necessary to call `synchronize` every time you set an `NSUserDefault`](http://stackoverflow.com/questions/9647931/nsuserdefaults-synchronize-method) – shim Jan 26 '16 at 19:07
7

I want just to add to the other answers that the object that you are going to store store in the NSUserDefault, as reported in the Apple documentation must be conform to this:

"The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects."

here the link to property list programming guide

so pay attention about what is inside your array

Meet Doshi
  • 3,983
  • 10
  • 35
  • 76
Manu
  • 778
  • 5
  • 9
3

Save:

NSUserDefaults.standardUserDefaults().setObject(PickedArray, forKey: "myArray")
 NSUserDefaults.standardUserDefaults().synchronize()

Retrieve:

if let PickedArray = NSUserDefaults.standardUserDefaults().stringForKey("myArray") {
    print("SUCCCESS:")
    println(PickedArray)
}
A.G
  • 13,048
  • 84
  • 61
2

Do you really want to store images in property list? You can save images into files and store filename as value in NSDictionary.

define path for store files


NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.basePath = [paths firstObject];

Store and load image:


- (NSString *)imageWithKey:(NSString)key {
    NSString *fileName = [NSString stringWithFormat:@"%@.png", key]
    return [self.basePath stringByAppendingPathComponent:fileName];
}

- (void)saveImage:(UIImage *)image withKey:(NSString)key {
    NSData *imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:[self imageWithKey:key] atomically:YES];
}

- (UIImage *)loadImageWithKey:(NSString)key { {
    return [UIImage imageWithContentsOfFile:[self imageWithKey:key]];
}

And you can store path or indexes in NSMutableDictionary


- (void)saveDictionary:(NSDictionary *)dictionary {
    NSMutableDictionary *dictForSave = [@{ } mutableCopy];
    for (NSString *key in [dictionary allKeys]) {
        [self saveImageWithKey:key];
        dictForSave[key] = @{ @"image" : key };
    }
    [[NSUserDefaults standardUserDefaults] setObject:dictForSave forKey:@"MyDict"];
}

- (NSMutableDictionary *)loadDictionary:(NSDictionary *)dictionary {
    NSDictionary *loadedDict = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyDict"];
    NSMutableDictionary *result = [@{ } mutableCopy];
    for (NSString *key in [loadedDict allKeys]) {
        result[key] = [self imageWithKey:key];
    }
    return result;
}

In NSUserDefaults you can store only simply objects like NSString, NSDictionary, NSNumber, NSArray.

Also you can serialize objects with NSKeyedArchiver/NSKeyedUnarchiver that conforms to NSCoding protocol .

Meet Doshi
  • 3,983
  • 10
  • 35
  • 76
aironik
  • 95
  • 1
  • 4
2

If you need to add strings to the NSMutableArray in ant specific order, or if you are using the NSMutableArray for a UITableView you may want to use this instead:

[NSMutableArray insertObject:string atIndex:0];
Meet Doshi
  • 3,983
  • 10
  • 35
  • 76
Lance
  • 21
  • 2
2

In Swift 3, for an NSMutableArray, you will need to encode/decode your array to be able to save it/ retrieve it in NSUserDefaults :

Saving

//Encoding array
let encodedArray : NSData = NSKeyedArchiver.archivedData(withRootObject: myMutableArray) as NSData

//Saving
let defaults = UserDefaults.standard
defaults.setValue(encodedArray, forKey:"myKey")
defaults.synchronize()

Retrieving

//Getting user defaults
let defaults = UserDefaults.standard

//Checking if the data exists
if defaults.data(forKey: "myKey") != nil {
   //Getting Encoded Array
   let encodedArray = defaults.data(forKey: "myKey")

   //Decoding the Array
   let decodedArray = NSKeyedUnarchiver.unarchiveObject(with: encodedArray!) as! [String]
}

Removing

//Getting user defaults
let defaults = UserDefaults.standard

//Checking if the data exists
if defaults.data(forKey: "myKey") != nil {

    //Removing the Data
    defaults.removeObject(forKey: "myKey")

}
Ugo Marinelli
  • 635
  • 10
  • 14
2

Save information of Array in NSUserdefaults with key.

"MutableArray received from JSON response"

[[NSUserDefaults standardUserDefaults] setObject:statuses forKey:@"arrayListing"];

"Retrieve this information(Array) anywhere in the project with same key"

NSArray *arrayList = [[NSUserDefaults standardUserDefaults] valueForKey:@"arrayListing"];

This helped me in my project and hope, it will help someone.

Dilip Tiwari
  • 1,185
  • 12
  • 29
1

Swift Version:

Save Array in NSUserDefaults:

NSUserDefaults.standardUserDefaults().setObject(selection, forKey: "genderFiltersSelection")

Retrieve Bool Array From NSUserDefaults:

if NSUserDefaults.standardUserDefaults().objectForKey("genderFiltersSelection") != nil{
                selection = NSUserDefaults.standardUserDefaults().objectForKey("genderFiltersSelection") as? [Bool] ?? [Bool]()
   }

Retrieve String Array From NSUserDefaults:

if NSUserDefaults.standardUserDefaults().objectForKey("genderFiltersSelection") != nil{
                selection = NSUserDefaults.standardUserDefaults().objectForKey("genderFiltersSelection") as? [String] ?? [String]()
    }
Mughees
  • 577
  • 1
  • 4
  • 14