Why is my NSMutableDictionary null? - iphone

Here's my delegate method for UIAlertView. I have no idea why myWordsDictionary is null when running the app. (Note: _dailyWords is an NSDictionary object and bookmarked is an NSString object.)
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"Clicked button index !=0");
// Add the action here
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *myWordsPath = [documentPath stringByAppendingPathComponent:#"MyWords.plist"];
NSMutableDictionary *myWordsDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:myWordsPath];
[myWordsDictionary setValue:[_dailyWords objectForKey:bookmarked] forKey:bookmarked];
[myWordsDictionary writeToFile:myWordsPath atomically:YES];
NSLog(#"%#", [myWordsDictionary description]);
[myWordsDictionary release];
} else {
NSLog(#"Clicked button index = 0");
// Add another action here
}
}
Thanks in advance.

myWordsPath may not contain any valid file, and you are initializing your NSMutableDictionary from content of the the file present at that path. That's why you are getting a null dictionary.

First, try check myWordsPath, if it returns null, you should look and find correct path.
Second, how you generate your plist? MyWords.plist must contain valid format. If you unsure, you should create from within XCode, there is plist object.

NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:
#"MyWords" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc]
initWithContentsOfFile:plistPath];

please try this code..
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
documentPath = [documentPath stringByAppendingPathComponent:#"MyWords.plist"];
NSMutableDictionary *myWordsDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:documentPath];

Related

loading data from plist to another class

In my app, plist files are being saved to the documents directory, each file name is the current date+time.
I'm loading the list of files from the documents directory to a table: filesTableVC.m.
Each time I want to load the chosen file to a new class: oldFormVC.m
but this class is opened empty.
I'm not sure where the problem is.
filesTableVC.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
oldFormVC *oldForm = [[oldFormVC alloc] initWithNibName:nil bundle:nil];
//load previous data:
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:[fileList objectAtIndex:indexPath.row]];
// check to see if Data.plist exists in documents
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
// if not in documents, get property list from main bundle
plistPath = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
}
// read property list into memory as an NSData object
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSString *errorDesc = nil;
NSPropertyListFormat format;
// convert static property liost into dictionary object
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
if (!temp)
{
NSLog(#"Error reading plist: %#, format: %d", errorDesc, format);
}
// assign values
self.theDate = [temp objectForKey:#"theDate"];
self.theTime = [temp objectForKey:#"theTime"];
self.carNumber = [temp objectForKey:#"carNumber"];
self.driverName = [temp objectForKey:#"driverName"];
[self presentViewController:oldForm animated:YES completion:nil];
}
oldFormVC.m:
- (void)viewDidLoad
{
[super viewDidLoad];
dateField.text = theDate;
timeField.text = theTime;
carNumberField.text = carNumber;
driverNameField.text = driverName;
}
Write your code in viewDidAppear
- (void)viewDidAppear:(BOOL)animated
{
dateField.text = theDate;
timeField.text = theTime;
carNumberField.text = carNumber;
driverNameField.text = driverName;
}
Also, change this code in filesTableVC.m:
oldForm.dateField = [temp objectForKey:#"theDate"];
oldForm.theTime = [temp objectForKey:#"theTime"];
oldForm.carNumber = [temp objectForKey:#"carNumber"];
oldForm.driverName = [temp objectForKey:#"driverName"];
Hope it helps you

Searching for objects in array by name

is there a possibility to check for an object in an array by name.
At some point in my app I need to access the plist and pull information stored under an object which I found by its name.
The reason I need to do this is because I don't have the integer number under which where the object is placed in my array.
I have started the usual procedure but i'm not getting anywhere. Maybe its just getting a little too late for me....
This is how my plist looks
Array
Dictionary
title ...
text ...
ect ...
Dictionary
title ...
text ...
ect ...
Dictionary
title ...
text ...
ect ...
My code so far isn't helping at all. I'm definitely doing something wrong.
-(NSString*)nameFromPlist:(NSString*)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"Orte.plist"];
_regionArray = [NSArray arrayWithContentsOfFile:writableDBPath];
NSString *string = [[NSString alloc]init];
for(NSDictionary *dict in _regionArray) {
string = [[dict objectForKey:name] valueForKey:#"title"];
}
return [NSString stringWithFormat:#"%#",string];
}
My string is just returning null.
Any ideas anyone?
Thanks a lot!
ANSWER:
Here is the code for everyone:
-(NSString*)nameFromPlist:(NSString*)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tmpFileName = [[NSString alloc] initWithFormat:#"Orte.plist"];
NSString *path = [documentsDirectory stringByAppendingPathComponent:tmpFileName];
NSString *string;
NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:path];
NSDictionary *dict = [[NSDictionary alloc] init];
NSString *title;
for (int i=0; i<[array count]; i++) {
dict = [array objectAtIndex:i];
title = [dict valueForKey:#"title"];
if([title isEqualToString:name]) {
string = [dict valueForKey:#"title"];
NSLog(#"Titel: %#", string);
}
}
return [NSString stringWithFormat:#"%#",string];
}
Thank a lot everyone!
First you don't need to alloc the NSString, 'cause you'll get a different one from valueForKey.
Then if I understood right what you want to get a better code may be something that make use of NSPredicate or the block-based indexOfObjectPassingTest. Both iterate across the array and perform a test on the elements to get you the matching elements (or the index of them).
NSString* plistPath = [[NSBundle bundleForClass:[self class]] pathForResource:#"<PlistFileName>" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:plistPath];
NSMutableArray* titles = [[NSMutableArray alloc] init];
for (NSDictionary* d in array)
[titles addObject:[d objectForKey:#"title"]];
NSLog(#"Object found at index %i", [a indexOfObject:#"<Your object name>"]);
Make sure you're testing against NSNotFound for failure to locate, and not (say) 0.

Can not save NSDictionary to a file

i think the title says all. I use some example code i found here but the file will not be created.
- (id)init {
[[NSBundle mainBundle] loadNibNamed:#"PadContent" owner:self options:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:[self filePathOfBookmarks]]) {
bookmarks = [[NSMutableDictionary alloc]
initWithContentsOfFile:[self filePathOfBookmarks]];
} else {
bookmarks = [[NSMutableDictionary alloc] init];
NSLog(#"file does not exist");
}
return self;
}
- (void)addBookmark:(id)sender{
[bookmarks setObject:[dataInstance chapter] forKey:[[dataInstance chapter]title]];
[bookmarks setObject:[dataInstance chapter] forKey:#"test"];
NSLog(#"count: %d", [bookmarks count]);
NSLog([self filePathOfBookmarks]);
[bookmarks writeToFile:[self filePathOfBookmarks] atomically:YES];
}
- (NSString *) filePathOfBookmarks {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [paths objectAtIndex:0];
return [docDirectory stringByAppendingPathComponent:#"bookmarks"];
}
What's in your dictionary? There are only certain base objects that can be written out and read back without any additional work on your part. If your dictionary includes a custom object that you defined, you'll need to use another mechanism to write and read back the data, such a an NSArchiver. I am guessing that whatever [dataInstance chapter] yields is not among these basic object types.
See the documentation for NSDictionary's writeToFile:atomically: for the data types that can be read and written automatically. Also look at NSArchiver and the NSCoding protocol.

Plist file path error?

I am trying to save an NSMutableArray containing text to a plist file using this code:
- (IBAction)saveDoc:(id)sender
{
NSString *typedText = typingArea.text;
NSMutableArray *totalFiles = [[NSMutableArray alloc] initWithObjects:typedText, nil];
NSLog(#"Created: %#", totalFiles);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"savedFiles.plist"];
NSLog(#"Found Path: %#", path);
//[totalFiles addObject:typedText];
[totalFiles writeToFile:path atomically:YES];
NSLog(#"File Written: %# to: %#", totalFiles, path);
[totalFiles release];
NSLog(#"Released: %#", totalFiles);
}
All of the NSLogs return appropriate values as expected. I use this code to crate a new NSMutableArray with the contents of the plist:
- (void)viewDidLoad {
file = [[NSBundle mainBundle] pathForResource:#"savedFiles" ofType:#"plist"];
NSLog(#"Got Path: %#", file);
array = [NSMutableArray arrayWithContentsOfFile:file];
NSLog(#"Loaded Array into new array: %#", array);
//UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"fdsfasdf" message:[dic objectForKey:#"item1"] delegate:self cancelButtonTitle:#"ldfghjfd" otherButtonTitles:nil] autorelease];
//[alert show];
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
//self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
The NSLogs in this code come back with a slightly different path than the first one returned with. It also said the array is (null)
How should I load the contents from a plist file?
Thanks in advance,
Tate
Try initialising your array first:
array = [[NSMutableArray alloc] initWithContentsOfFile:file];

How to write a plist on a device? Objective C iphone

I have this code:
#define ALERT(X) {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info" message:X delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];[alert show];[alert release];}
- (id)readPlist:(NSString *)fileName {
NSData *plistData;
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"plist"];
plistData = [NSData dataWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
[error release];
}
return plist;
}
- (void)writeToPlist: (NSString*)a
{
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"data.plist"];
NSMutableArray* pArray = [[NSMutableArray alloc] initWithContentsOfFile:finalPath];
[pArray addObject:a];
[pArray writeToFile:finalPath atomically: YES];
ALERT(#"finished");
/* This would change the firmware version in the plist to 1.1.1 by initing the NSDictionary with the plist, then changing the value of the string in the key "ProductVersion" to what you specified */
}
- (void)viewDidLoad {
[super viewDidLoad];
[self writeToPlist:#"this is a test"];
NSArray* the = (NSArray*)[self readPlist:#"data"];
NSString* s = [NSString stringWithFormat:#"%#",the];
ALERT(s);
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
On the simulator the second alert shows the content of the file correctly but on the device it shows nothing?? What's i'm doing wrong? Please show a code/snippet....
The problem is that you could not write a file into mainBundle folder, only Documents folder is accessable on your Device.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];