iOS 6: Get strings into array from file line by line - objective-c

I searched the web but everything I can find doesn't work because it uses old code or something...
What filetype would you choose to import a list of words? txt? (about 200 words)
How can I get all of the words out of the file and into an array?
I want to output a random word out of the file into a label.
I tried:
NSString* path = [[NSBundle mainBundle] pathForResource:#"filename"
ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSArray *arr = [content componentsSeparatedByString:#"\n"];
self.biglabel.text = arr[arc4random() % arr.count];
Thanks in advance!
Michael
edit:
works now. I didn't have plain txt files. I renamed a rtf file and that didn't work.
XCode 4.3.3

You could store it as a plist and then turn that directly into an array.
NSString* path = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"plist"];
NSArray* arr = [NSArray arrayWithContentsOfFile:path];
Your plist would look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>...</string>
...
</array>
</plist>

Related

NSMutableArray addObjects NSString

I have an problem with NSString and NSMutableArray
I Have:
NSString *msgID;
NSMutableArray *mArray;
and msgID string is an unique ID for every message and it changes it self every time when you receive a new message.
and now i want to save those IDS into NSMutableArray to put them inside plist file.
but the problem is when i do like the following
a = [[NSMutableArray alloc] init];
[a addObject:msgID];
it save only the first ID not the rest of theme
Example if the output ID is 65465465151 and you received new message after one second with ID 2123545445 the NSMutableArray save only the first output.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>65465465151</string>
</array>
</plist>
how can I make NSMutableArray add all outputs or strings which already output using one NSString ?
Here is my code
NSString *msgID = [viewcontroller.messageID substringFromIndex:[viewcontroller.messageID length] - 21];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"msgIDs.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray *mArray;
if (![fileManager fileExistsAtPath:path]) {
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat: #"msgIDs.plist"] ];
}
if ([fileManager fileExistsAtPath:path]) {
mArray = [[NSMutableArray alloc] init];
[mArray addObject:msgID];
} else {
// If the file doesn’t exist, create an empty dictionary
mArray = [[NSMutableArray alloc] init];
}
[mArray writeToFile:path atomically:YES];
If that's your code, and it's all in one block like that and not spread over several methods, in several different loops, then you're creating a new instance of mArray every time you go through the code block, and, as a result, at most there will be one entry in the array.
Your code looks OK, provided you are not trying to create the array in a loop repeatedly. Each addObject will enlarge the array by one. Make sure you write your plist file after the array is populated the way you expect. Make sure any old plist file is overwritten.

read multi-array from plist

I can't get it work to have the 8 items from the plist below.
I have a plist "settings.plist". Now I wan't from vragen -> category (self.catagorie - 1) -> question. The 8 items. But the array keeps empty.
What am I doing wrong?
Code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"instellingen.plist"];
NSMutableDictionary *instellingen = [NSMutableDictionary dictionaryWithContentsOfFile:path];
NSArray *vragen = [instellingen objectForKey:#"vragen"];
NSArray *cata = [vragen objectAtIndex: (self.catagorie-1)];
NSArray *question = [cata objectAtIndex: 0];
NSLog(#"count: %i", [question count]);
Plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>vragen</key>
<array>
<array> <--catagorydata
<array> <-- questiondata
<string>vraag</string>
<string>A</string>
<string>B</string>
<string>C</string>
<string>D</string>
<string>1</string>
<string>standaard</string>
<string></string>
</array>
<array>
<string>vraag2</string>
<string>A</string>
<string>B</string>
<string>C</string>
<string>D</string>
<string>1</string>
<string>afbeelding</string>
<string>afbeelding.jpg</string>
</array>
</array>
</array>
<key>firstBoot</key>
<true/>
<key>regelAtRuntime</key>
<true/>
</dict>
</plist>
First of all this line
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"instellingen.plist"]; ?
should be
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"settings.plist"];
I also had to delete these from the dictionary:
<--catagorydata
<-- questiondata
Besides the two things above, there is nothing wrong with your code or your dictionary.
After making those changes I tested your code and the output I got was:
tester[69637:c07] size of dict 3
tester[69637:c07] count: 8
which is correct according to the .plist file
So your problem is at the first 4 lines. Make sure your file is in Documents directory (use something like the following code to see whats going wrong)
NSLog(#"Path : %#",path);
I copied the file in the project folder (because I used the simulator) and used the following code and everything worked fine
NSBundle* b=[NSBundle mainBundle];
NSURL* path1=[b URLForResource:#"settings" withExtension:#"plist"];
NSMutableDictionary *instellingen = [NSMutableDictionary dictionaryWithContentsOfURL:path1];
NSLog(#"size of dict %d",[instellingen count]);
NSArray *vragen = [instellingen objectForKey:#"vragen"];
NSArray *cata = [vragen objectAtIndex: 0];
NSArray *question = [cata objectAtIndex: 0];
NSLog(#"count: %i", [question count]);
Just a quick read, but looks like you have an array of "categoryData" items, that contains an array of questionData items; questionData items are strings.
NSArray *vragen = [instellingen objectForKey:#"vragen"]; // count = 1
NSArray *cata = [vragen objectAtIndex: (self.catagorie-1)]; // count = 2
NSString *question = [cata objectAtIndex: 0];
Recommend you add some breakpoints and look at your data. OR, NSLog(#"data = %#", cata); etc.

Problems extracting values from NSMutableArray

I'm trying to parse data from a plist file into a NSMutableArray.
In my plist
Root is a Dictionary containing an Array of 6 Numbers
I've created a label hooked with the IBOutlet UILabel *lbl4 object and I want this label to show the first element of the array made reading the plist. The problem is that the program crashes at the assigning instruction (the last one).
My code is this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSString *plistPath = [docPath stringByAppendingPathComponent:#"settings.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:plistPath]);
{
plistPath = [[NSBundle mainBundle] pathForResource:#"settings" ofType:#"plist"];
}
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSString *err = nil;
NSPropertyListFormat format;
NSDictionary *temp = (NSDictionary *) [NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&err];
if(!temp)
{
NSLog(#"Error reading plist: %#, format: %d", err, format);
}
self.dataSet = [NSMutableArray arrayWithArray:[temp objectForKey:#"Dadi"]];
[lbl4 setText:[NSString stringWithFormat:#"%#", [dataSet objectAtIndex:0]]];
The plist source code is the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Dadi</key>
<array/>
<key>D4</key>
<integer>0</integer>
<key>D6</key>
<integer>0</integer>
<key>D8</key>
<integer>0</integer>
<key>D10</key>
<integer>0</integer>
<key>D12</key>
<integer>0</integer>
<key>D20</key>
<integer>0</integer>
</dict>
</plist>
The Debug output says "2012-09-02 18:29:55.483 Faith[6014:707] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'"
In your plist, the array stored at the dictionary's Dadi key is empty!
<key>Dadi</key>
<array/>
So
self.dataSet = [NSMutableArray arrayWithArray:[temp objectForKey:#"Dadi"]];
Sets self.dataSet to an empty array (i.e. even index:0 is beyond the bounds).
I would check for se.f.dataSet.count == 0 and provide a default in this case.
#warrenm mentioned in the comments that the structure of your plist is not what you might have expected. These are XML files, so any tag which ends with /> is "self-closing", and therefore always empty. To contain those numbers, you need to add an ending tag and place them inside:
<array>
<integer>7</integer>
</array>
Of course, on further evaluation, your existing plist has keys associated with those, so this is possibly also not the right solution. You'll need to evaluate what your needs are for that plist.

How to write an array to a file without html

The code I have right now looks like this:
NSString *path = #"/Users/student/Desktop/conf.txt"
NSArray *myArray = [NSArray arrayWithObjects:#"hello",#"world",#"etc",nil];
[myArray writeToFile:path atomically:YES];
When I look at the text file it writes it ends up looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>hello</string>
<string>world</string>
<string>etc</string>
</array>
</plist>
I don't want to display it as an html, I just want a simple text document with the 3 lines saying, "hello world etc".
Does anybody know how I could fix this?
Thanks
If your array contains strings and you wat to write them to file one per line you can first create string with all your words and then write it to file:
NSString *outString = [myArray componentsJoinedByString:#"\n"];
NSError *error = nil;
[outString writeToFile: path atomically:YES encoding:encoding:NSUTF8Encoding error:&error];
But if you want to serialize your array for future use plist format may be more convenient

NSArray initWithContentsOfFile returns nil

I'm trying to read a plist file into NSArray using initWithContentsOfFile as described here
My code looks like this
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:
#"routes" ofType:#"plist" ];
routes = [[NSArray alloc] initWithContentsOfFile:plistPath ];
NSLog:(#"contents of myArray %#", routes);
routes.plist has a perfectly simple structure of array and 2 string values inside
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Root</key>
<array>
<string>1</string>
<string>2</string>
</array>
</dict>
</plist>
Everything seems to be fine. plistPath initializes with correct value, which means file is copied to the bundle and can be readed. But routes = [[NSArray alloc] initWithContentsOfFile:plistPath ]; returns 0x0 value. I think this is equal to nil
What is wrong with my code?
Actually your plist is a dictionary.
Change this:
<dict>
<key>Root</key>
<array>
<string>1</string>
<string>2</string>
</array>
</dict>
to this:
<array>
<string>1</string>
<string>2</string>
</array>
I think you want to do something like this:
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:
#"routes" ofType:#"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *routes = [dictionary objectForKey:#"Root"];