I use a PLIST to populate a TableView in my app. I want the TableView to be in order of how items were added, due to needing a good way to edit it later on, so the indexPath.row will match up with the indexPath of the PLIST. I get the TableView populated by going from the PLIST to NSDictionary to NSArray. The issue is that the TableView keeps listing everything in alphabetical order and not the order it was listed
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:self.selectedCountry];
_plist = [NSMutableDictionary dictionaryWithContentsOfFile: plistPath];
_content = [_plist allKeys];
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"];
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.
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.
I have an existing PList in my project called "Account.plist" ... it loads my initial Tableview ... and it sends said data to the detail view. I created another detail view called AddViewcontroller ... I have 5 blank text fields ... I created a button and the button action executes this code below: but I cannot find either an update to my "Account.plist" or where a new copy of my "Accounts.plist" in my Library folder for the project. any assistance would be appreciated. thank you in advance.
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:AcctName.text];
[array addObject:AcctNum.text];
[array addObject:DayDue.text];
[array addObject:paymnt.text];
[array addObject:remBalance.text];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *plistPath = [documentPath stringByAppendingPathComponent:#"Accounts.plist"];
[array writeToFile:plistPath atomically: true];