Storing data from a plist file into an array - objective-c

I have spent all of yesterday trying to figure this out with no luck at all. Here is the code im working with.
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *array = [NSArray arrayWithArray:[dict objectForKey:#"root"]];
for(int num = 0; num < 5; num++)
{
NSLog(#"my array:%#", array);
}
NSLog(#"items in my array: %lu", (unsigned long) [array count]);
Here are the views for the plist file im working with.
<plist version="1.0">
<dict>
<key>New item</key>
<string>hello</string>
<key>New item - 2</key>
<string>world</string>
<key>New item - 3</key>
<string>again</string>
<key>New item - 4</key>
<string>and</string>
<key>New item - 5</key>
<string>again</string>
</dict>
</plist>
This code does not return null like when i tried using an NSArray over the NSDictionary, but when i run it console does not print out any data retrieved from the plist. It just prints out:
my array:{}
my array:{}
my array:{}
my array:{}
my array:{}
items in my array: 0
If i try to print out dict by changing the NSLog to NSLog(#"my array:%#", array); i get this.
my array:(NULL)
my array:(NULL)
my array:(NULL)
my array:(NULL)
my array:(NULL)
items in my array: 0

Everything you could print for such plist is
NSLog(dict[#"new item"]);
Also you probably should use
for(int num = 0; num < array.count; num++)
{
NSLog(#"my array:%#", array[i]);
}
instead of
for(int num = 0; num < 5; num++)
{
NSLog(#"my array:%#", array);
}

Don't know what keys are in dictionary? No need to concern about keys in this case. Try this
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
if(dict.count != 0)
{
NSArray *array = [dict allKeys];
for(int num = 0; num < array.count; num++)
{
NSLog(#"my array item:%#", [dict objectForKey:array[num]]);
}
}
else
{
NSLog(#"Your dictionary is empty.");
}

Are you trying to put all the values form the dict into the array ?
If so add:
NSArray *array = [NSArray arrayWithArray:[dict allValues]];
//Check for file;
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:path])
NSLog(#"NO FILE AT PATH: %#", path);

I found the issue. I had to create a build phase and add the plist files to it. That way when i use the pathToResource ofFile it has a file to find when i use the rest of the code.

Related

Show contents of two merged directory listings

I would like to merge the two directories listings (already done and works they show up in NSTableView), but also display the contents of the files in an NSScrollview, now the problem lies in iterating through the list, and I couldn't figure out how I would come about that problem, I tried different techniques.
For now I get: "-[NSTextView replaceCharactersInRange:withString:]: nil NSString given.", probably because the iteration code is incorrect...
NSInteger row = [logsTableView selectedRow];
NSString *path1 = [NSHomeDirectory() stringByAppendingPathComponent:#"Library/Logs/"];
NSString *path2 = #"/Library/Logs/";
NSArray *directoryList1 = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path1 error:nil]
pathsMatchingExtensions:[NSArray arrayWithObjects:#"log", nil]];
NSArray *directoryList2 = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path2 error:nil]
pathsMatchingExtensions:[NSArray arrayWithObjects:#"log", nil]];
NSMutableArray *directoryList = [NSMutableArray array];
[directoryList addObjectsFromArray:directoryList1];
[directoryList addObjectsFromArray:directoryList2];
for (NSUInteger i = 0; i < directoryList.count; i++)
{
if (row == i)
{
for (NSUInteger i = 0; i < directoryList1.count; i++)
{
NSString *filePath = [NSHomeDirectory() stringByAppendingFormat:#"Library/Logs/%#", [directoryList objectAtIndex:i]];
NSString *content = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:NULL];
[logsScrollViewTextView setString:content];
}
for (NSUInteger i = directoryList.count - directoryList1.count; i < directoryList.count; i++)
{
NSString *filePath = #[#"/Library/Logs/%#", [directoryList objectAtIndex:i]];
NSString *content = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:NULL];
[logsScrollViewTextView setString:content];
}
}
}
You don't need to iterate. All you need to do is to check which array the file name came from.
Assuming you aren't sorting the list, this is if (row >= directoryList1.count). This check tells you which list it came from so you can set the prefix.
If you are sorting and the names are unique you could use [directoryList1 containsObject:...).

How do I initialize all positions in an array of numbers?

I want to store the same number in an array 100 times. These numbers will change later on, but I want to write an if statement using a counter to populate all 100 slots initially with the value of 0. Is there an easy way to do this?
Something like this, where 'block01' needs to change to 'block02', 'block03' etc.:
int block01 = 0;
NSMutableDictionary* myDict = [[NSMutableDictionary alloc] init];
if(myDict)
{
[myDict setObject:block01 forKey:#"block01stored"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *path = [documentPath stringByAppendingPathComponent:#"blocks.save"];
BOOL successfulWrite = [myDict writeToFile: path atomically: YES];
if(successfulWrite == NO)
}
This should help you. It's a loop that will execute 99 times (1 - 100) adding zero as the object for a key formatted to include the current number.
NSMutableDictionary* myDict = [[NSMutableDictionary alloc] init];
for (int i = 1; i <= 100; i ++) {
if(myDict)
{
[myDict setObject:[NSNumber numberWithInt:0] forKey:[NSString stringWithFormat:#"block%.3istored",i]];
}
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *path = [documentPath stringByAppendingPathComponent:#"blocks.save"];
BOOL successfulWrite = [myDict writeToFile: path atomically: YES];
if(successfulWrite == NO)
EDIT: To get the value for a certain key you can use the following:
int myInt = [[myDict objectForKey:#"block050stored"] intValue];
And if you want to replace the object for a certain key it's as easy as:
[myDict setObject:[NSNumber numberWithInt:1] forKey:#"block020stored"];
Now, the %.3i tells the string to add a number (i) formatted to always be three digits long. (000, 001, 010, 099, 100)
[NSString stringWithFormat:#"block%.3istored",i]
So the above line basically means, create a string with the words "block" and "stored" with a three digit representation of what ever the current value of the int "i" is in between them.
You can create NSNumber (which is an object, but int is not) and then store it into NSMutableDictionary:
NSNumber* num = [NSNumber numberWithInt:0];
for (int i = 1; i<=100; i++) {
[myDict setObject:num forKey:[NSString stringWithFormat:#"block%dstored",i]];
}

Replacing a specified dictionary in NSMutableArray

I'm trying to replace a dictionary in a mutable array.
Steps 1 through 4 should be good, but I'm having some trouble in step 5 - 6. Can you show me what has to be done to make this function work:
- (void) updatePlist {
// 1: String with plist path:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory
stringByAppendingPathComponent:#"Object.plist"];
// 2: Create a mutable dictionary containing current object and write
// "Yes" to the "Favorite" string:
NSMutableDictionary *mutDict = [NSMutableDictionary
dictionaryWithDictionary:[detailsDataSource objectAtIndex:detailIndex]];
[mutDict setObject:#"Yes" forKey:#"Favorite"];
// 3: Make a string containing current object name:
NSString *nameString = [[detailsDataSource objectAtIndex:detailIndex]
valueForKey:#"Name"];
// 4: Make a mutable array containing all objects:
NSArray *allObjectsArray = [[NSArray alloc] initWithContentsOfFile:path];
NSMutableArray *tmpMutArr = [NSMutableArray arrayWithArray:allObjectsArray];
// 5: Search for the dictionary in tmpMutArr with "Name" value matching nameString:
int *index;
for(int i=0;i<[tmpMutArr count];i++)
{
if([[tmpMutArr objectAtIndex:i] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *tempDict = [tmpMutArr objectAtIndex:i];
if([[tempDict valueForKey:#"Name"] isEqualToString:[NSString
stringWithFormat:#"%#", nameString]])nameString];)
{
index = i;
}
}
}
// 6: Replace the old dictionary with the new one and write array to plist:
[tmpMutArr replaceObjectAtIndex:index withObject:
[NSDictionary dictionaryWithDictionary:mutDict]];
allObjectsArray = nil;
allObjectsArray = [[NSArray alloc] initWithArray:tmpMutArr];
[allObjectsArray writeToFile:path atomically:YES];
}
EDIT:
Now the problem is:
for(int i=0;i<[tmpMutArr count];i++)
{
if([[tmpMutArr objectAtIndex:i] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *tempDict = [tmpMutArr objectAtIndex:i];
if([[tempDict valueForKey:#"Name"] isEqualToString:
[NSString stringWithFormat:#"%#", nameString]])nameString];)
{
index = i; // Here 1
}
}
}
// ---------------------------- v And here 2
[tmpMutArr replaceObjectAtIndex:index withObject:
[NSDictionary dictionaryWithDictionary:mutDict]];
1: Incompatible integer to pointer conversion assigning to 'int' from 'int'; take the adress with &
2: Incompatible pointer to integer conversion sending 'int *' to parameter of type NSUInteger' (aka 'unsigned int')
Replace the line:
if([tempDict valueForKey:#"Name" == [NSString stringWithFormat:#"", nameString];)
with this line:
if([[tempDict valueForKey:#"Name"] isEqualToString: [NSString stringWithFormat:#"%#", nameString]])
since you are using string comparison here.
As pointed out in the comments by Martin R, you are trying to save an int value into a int pointer variable.
int index; //instead of 'int *index;'
That change should do the trick.
It could have worked if you had written int *index; and then index = &i;, since you are saving a pointer to an integer that way. But it doesn't seem to be what you are trying to do.
The second error is due you are providing an int pointer instead of an integer to this method:
[tmpMutArr replaceObjectAtIndex:index withObject:
[NSDictionary dictionaryWithDictionary:mutDict]];
But declaring index as an integer solves both errors already.

replace an object inside nsmutablearray

I have a NSMutableArray where i want to replace the sign | into a ; how can i do that?
NSMutableArray *paths = [dic valueForKey:#"PATH"];
NSLog(#"pathArr ", paths)
pathArr (
(
"29858,39812;29858,39812;29925,39804;29936,39803;29949,39802;29961,39801;30146,39782;30173,39779;30220,39774;30222,39774|30215,39775;30173,39779;30146,39782;29961,39801;29949,39802;29936,39803;29925,39804;29858,39812;29858,39812;29856,39812;29800,39819;29668,39843;29650,39847;29613,39855;29613,39855;29613,39856;29605,39857;29603,39867;29603,39867;29599,39892;29596,39909;29587,39957;29571,40018;29563,40038;29560,40043"
)
)
Update
This is where i got my path from
NSArray *BusRoute = alightDesc;
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSLog (#"BusRoute = %#", [BusRoute objectAtIndex: i]);
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSMutableArray *paths = [dic valueForKey:#"PATH"];
}
Provide that your object in the array path is string, you can do this
NSMutableArray *path2=[[NSMutableArray alloc]initWithArray:nil];
for (NSObject *obect in path) {
for (NSString *string in (NSArray*)obect) {
[path2 addObject:[string stringByReplacingOccurrencesOfString:#"|" withString:#","]];
}
}
NSLog(#"pathArr %# ", path2);
your array paths contains an another array which has string as object.
Hope this helps
//Copy the Array into a String
NSString *str = [paths componentsJoinedByString: #""];
//then replace the "|"
str = [str stringByReplacingOccurrencesOfString:#"|" withString:#";"];
i did this to replace a string in a .plist so it might work for you
array1 = [NSMutableArray arrayWithContentsOfFile:Path1];
NSString *item = [#"dfdfDF"];
[array1 replaceObjectAtIndex:1 withObject:item];
[array1 writeToFile:Path1 atomically:YES];
NSLog(#"count: %#", [array1 objectAtIndex:1]);
you may cast or convert paths to NSString and then do:
paths = (NSString *) [paths stringByReplacingOccurrencesOfString:#"|" withString:#";"];
if this does't work, create new NSString instance that containing pathArr text, invoke replaceOccurrences method and do invert conversion
NSMutableString *tempStr = [[NSMutableString alloc] init];
for (int i = 0; i < [paths count]; i++)
{
[tempStr appendString:[path objectAtIndex:i]];
}
then use this method for tempStr. And then try:
NSArray *newPaths = [tempStr componentsSeparatedByString:#";"];
may be last method not completely correct, so try experiment with it.
Uh, why don't you just go:
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
If there are more than one nested array, you can go
for(int i = 0; i < [[dic valueForKey:#"PATH"] count]; i++)
{
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:i] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
// do something with cleanedString
}

finding a number in array

I have an Array {-1,0,1,2,3,4...}
I am trying to find whether an element exist in these number or not, code is not working
NSInteger ind = [favArray indexOfObject:[NSNumber numberWithInt:3]];
in ind i am always getting 2147483647
I am filling my array like this
//Loading favArray from favs.plist
NSString* favPlistPath = [[NSBundle mainBundle] pathForResource:#"favs" ofType:#"plist"];
NSMutableDictionary* favPlistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:favPlistPath];
NSString *favString = [favPlistDict objectForKey:#"list"];
NSArray *favList = [favString componentsSeparatedByString:#","];
//int n = [[favList objectAtIndex:0] intValue];
favArray = [[NSMutableArray alloc] initWithCapacity:100];
if([favList count]>1)
{
for(int i=1; i<[favList count]; i++)
{
NSNumber *f = [favList objectAtIndex:i];
[favArray insertObject:f atIndex:(i-1)];
}
}
That's the value of NSNotFound, which means that favArray contains no object that isEqual: to [NSNumber numberWithInt:3]. Check your array.
After second edit:
Your favList array is filled with NSString objects. You should convert the string objects to NSNumber objects before inserting them in favArray:
NSNumber *f = [NSNumber numberWithInt:[[favList objectAtIndex:i] intValue]];