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];
Related
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.
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].
The development is in Xcode for iOS. I used 2 separate NSmutabledictionary.
I DONĀ“T want to add them (when searching I found that often, but that is not what I try to do)
The app has to store them on the disk and when the app launches it can read the dictionary.
It is not a custom class so initWithCoder and the other one is not necessary (is this right?)
NSArray *data = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [data objectAtIndex:0];
path = [path stringByAppendingPathComponent:#"location"];
[NSKeyedArchiver archiveRootObject:"Dictionary" toFile:path];
This works but when I want to save another dictionary it won't work. My first thought would be to change the objectAtIndex to 1. But Xcode gives me an error when I do that. When I only give another name it simply won't save, but Xcode don't give an error.
What am I doing wrong?
// Find out where the documents folder is
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// Create the file path for a file named 'location' inside the documents folder
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"location"];
// Write an array containing both of your arrays to a file at that path
[NSKeyedArchiver archiveRootObject:#[myFirstArray, mySecondArray] toFile:path];
Then, to read them back:
// Read back the array containing the two arrays
NSArray *arrays = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
// Get the individual arrays from the array
NSMutableArray *myFirstArray = arrays[0];
NSMutableArray *mySecondArray = arrays[1];
I am having difficult accessing the count of a chosen plist. In the previous view controller, the user selects from one of several buttons, each one corresponding to a particular plist. That plist is sent to the current vc as NSString * chosenPlist. I have NSLogged to see that the documents directory and the plistpath seem to be correct, but the array that I want to count is still 0.
How can I count the number of items in the chosen plist?
NSString * chosenPlistPlus = [chosenPlist stringByAppendingString:#".plist"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(#"The documentsdirectory is %#", documentsDirectory);
NSString *myPlistPath = [documentsDirectory stringByAppendingPathComponent:chosenPlistPlus];
NSLog(#"MyPlistPath = %#", myPlistPath);
NSArray *arr = [NSArray arrayWithContentsOfFile: myPlistPath];
//Trying to count the items in the plist, which is an array of dicts.
int count = arr.count;
NSLog(#"Count is %i", count);
here is a log:
2013-11-16 21:13:07.037 GlobalHistoryRegents[70407:70b] The documentsdirectory is /Users/username/Library/Application Support/iPhone Simulator/7.0.3/Applications/896EF347-A35E-40E2-9BE1-8CFAC5303347/Documents
2013-11-16 21:13:07.037 GlobalHistoryRegents[70407:70b] MyPlistPath = /Users/username/Library/Application Support/iPhone Simulator/7.0.3/Applications/896EF347-A35E-40E2-9BE1-8CFAC5303347/Documents/methodologyQuestions.plist
2013-11-16 21:13:07.038 GlobalHistoryRegents[70407:70b] Count is 0
try using,
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:myPlistPath];
NSArray *arr =dictionary[#"Root"];
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];