Trying to load a saved NSMutableArray - ios

This is the code I'm using to save an NSMutableArray "names" (after the user presses a save button), and I think it's working without problems, but I'm not sure what the corresponding code would be to then load my array when I reopen my app. Any help would be greatly appreciated!
- (IBAction)save:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/temporaryArray", docDir];
[NSKeyedArchiver archiveRootObject:names toFile:fullFileName];
}

Well, you're halfway there. You've figured out how to archive the object. The question is, how do you unarchive it? As I explained in my comment, this is done with the very aptly named NSKeyedUnarchiver class.
Let's begin with a code sample:
#try {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *defaultPath = [docDir stringByAppendingPathComponent:#"temporaryArray"];.
self.yourArray = [NSKeyedUnarchiver unarchiveObjectWithFile: defaultPath];
if (!self.yourArray) {
NSLog(#"Error!");
} else {
// Success!
}
} #catch (NSException *exception) {
NSLog(#"Some error happened: %#", exception);
}
The NSKeyedUnarchiver class takes a path to a file containing the content archived by NSKeyedArchiver. It will then read this file and return the "root" object -- the object that you told NSKeyedArchiver to archive. It's that simple. (You should, of course, include error handling, which I gave a brief example of above.)
If you want another resource, you can read this great introductory article by the famous Mattt Thompson, which gives a good explanation of the concepts behind the class.
Hope this helps.

If your array's contents are all property list objects (NSString, NSData, NSArray, or NSDictionary objects) then you can do saving and reading in a way other than using NSKeyedArchiever/NSKeyedUnarchiever:
- (IBAction)save:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [docDir stringByAppendingPathComponent:#"temporaryArray"];
[names writeToFile:fullFileName atomically:YES];
}
- (NSMutableArray*)readNames
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [docDir stringByAppendingPathComponent:#"temporaryArray"];
return [NSMutableArray arrayWithContentsOfFile:fullFileName];
}

- (IBAction)save:(id)sender
{
// check for previous data persistancy.
NSArray *arrData = [[NSUserDefaults standardDefaults]objectforkey:#"Paths"];
if(arrData == nil)
{
// Maintain your old data and update it in new one to store the same.
NSMutableArray *arrTempData = [NSMutableArray arrayWithArray:arrData];
//Add Some data to old array based on your bussiness logic.
[arrTempData add object:#"some data"];
// Update in User Defaults
[[NSUserDefaults standardDefaults]setobject:[NSArray arrayWithArray:arrTempData] forkey:#"Paths"];
}
}
Somewhere in your code,put below code to get the data,
NSArray *arrSavedData = [[NSUserDefaults standardDefaults] objectforkey:#"Paths"];

Related

Reading and Writing NSMutableArray to iPhone not working (Works on iOS Simulator)

In an app I am working on I want to have an NSMutableArray (called pathsArray) that I can read from a file in the app's directory, be able create an instance of that array that I can add objects to and/or remove objects from, and then I want to write it back to the file. I have a UILabel that shows the number of contents in this array. My problem: my code below works fine on Xcode's iOS Simulator but when I try to run the app on my actual iPhone the data isn't saved. I know there are a lot of questions on here related to this issue but i can't seem to see what I am doing wrong. Any help would be greatly appreciated.
- (void) loadArrayContents {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingString:#"theArray"];
//Objects contained in an array returned by 'initWithContentsOfFile' are immutable even if the array is mutable
NSArray* contentsArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
pathsArray = [[NSMutableArray alloc] initWithArray:contentsArray];
}
and...
- (void) saveArrayContents {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingString:#"theArray"];
[pathsArray writeToFile:filePath atomically:YES]);
}
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theArray"];
should solve the issue. The problem with
NSString *filePath = [documentsDirectory stringByAppendingString:#"theArray"];
is that it does not add / in the file path.

Plist File cannot be created. iOS+NSDictionary+JSON

I am having problem with creating the Plist File that saves data received from web service using JSON. The Plist File cannot be created. The path is empty and data is saved to nowhere. This problem occurred when I cleaned the derived data. Please suggest any solution for this.
JSON data:
eventID = 2356;
eventName = "Testing Event";
This is how I save in Plist:
NSArray *eventsDictionary = [dataDictionary objectForKey:#"eventList"];
NSDictionary *plistDict = [NSDictionary dictionaryWithObject:eventsDictionary
forKey:#"Events"];
if ([eventsDictionary count]==0) {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:DATA_DICTIONARY_KEY_USER_DEFAULTS];
[plistDict writeToFile:path atomically:YES];
}
else {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
path = [path stringByAppendingPathComponent:DATA_DICTIONARY_KEY_USER_DEFAULTS];
[plistDict writeToFile:path atomically:YES];
}
Thank you very much.
You mentioned in a comment that the data was obtained from a web service as JSON and then converted to a dictionary.
The problem is almost certainly that your JSON data contains null values, which means that your dictionary contains instances of NSNull. You cannot write NSNull to a file like this because it is not one of the property list types. Writing a file like this only works with instances of NSDictionary, NSArray, NSString, NSData, NSNumber, and NSDate. Also any dictionary keys must be strings.
If there's an NSNull (or an instance of any non-property list class) then writing the file like this will fail.
You need to either go through the data and remove all NSNull instances, or else write your file some other way.
Here is the simplest way:
Add your dict to array:
NSMutableArray * mutArr = [NSMutableArray alloc]init];
[mutArr addObject:plistDict];
[self saveToPlistName:#"yourplist" fromArray:mutArr];
and use this method
-(void)saveToPlistName:(NSString *)plistName fromArray:(NSMutableArray*)array
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolder = [path objectAtIndex:0];
NSString *filePath = [documentFolder stringByAppendingFormat:[NSString stringWithFormat:#"/%#.plist",plistName]];
[array writeToFile:filePath atomically:YES];
NSLog(#"SAVE SUCCESS TO DIRECTORY%#",filePath);
}
vote for me if its helpful for you

My plist is not updated when i close my application and open it again

Please,
I created a plist with some Keys and values,
And then I tried to add new item to my Plist and save it.
After that i close my App and open it again, but i don't see my new items on my Table View.
So I don't understand where is my wrong !!!
Please Help!!!
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingString:#"MyProfile.plist"];
NSString *error=nil;
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:MyProfile format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
if (plistData){
[plistData writeToFile:plistPath atomically:YES];
}
else{
NSLog(#"Error in save Data:%#",error);
}
self.profileInfo = [[NSMutableDictionary alloc]initWithContentsOfFile:filePathPlist];
The values in self.profileInfo is not mutable, if the value for a specific key is a array, it will be NSArray not NSMutableArray.
Let's talk about the code below:
self.names = [self.profileInfo objectForKey:#"Names"];
Although you declare the property names as a NSMutableArray, the instance you get here is still a NSArray. So you should send mutableCopy method to id to get a mutable array:
self.names = [[self.profileInfo objectForKey:#"Names"] mutableCopy];
BTW:
You can also save self.profileInfo to file directly using [self.profileInfo writeToFile:path atomically:YES].

iOS Pragmatically Create Plist with 15 Array Objects

I hope someone can help, before asking we're using Plist to slimline the whole app. I am creating a plist when somebody selects a player. However what I want to do is create a plist with 15 blank array objects, this way I can just replace and edit as the user goes.
Any help would be appreciated. Thanks!
To create plist with 15 arrays you can use:
NSMutableArray * mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 15; i++)
{
NSArray *array = [NSArray alloc] init];
[mainArray addObject:array];
}
[self saveToFile:mainArray];
Method for saving:
- (void)saveToFile:(NSArray*)ar
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.plist"];
[ar writeToFile:path atomically:YES];
}
Hope you find it useful.

3 lines of code, one causes EXC_BAD_ACCESS

I have an array that I want to populate with a dictionary, however I get EXC_BAD_ACCESS when I try to view the pickerView that is populated with the array. One of these 3 lines of code causes it.
paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) copy];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"];
Full Code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"];
dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
array = [dictionary allKeys];
[pickerView selectRow:0 inComponent:0 animated:YES];
[pickerView reloadAllComponents];
}
Maybe the NSArray returned by NSSearchPathForDirectoriesInDomains is becoming a Zombie. You could try getting a copy of it like this:
NSArray *paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) copy];
Looks like, with this line, you're trying to save a value into an ivar named "arrays":
array = [dictionary allKeys];
But that's not going to work (unless it's and ARC project, which you say it isn't).
You need to retain that value. Make array a property that's retained (or copied). Or (not quite as good) retain it yourself:
[array autorelease]; // Don't skip this, or it may leak.
array = [[dictionary allKeys] retain];

Resources