NSNotification Called, but label will not update - iphone

I have the following code called with NSNotification center, i know its being called because the array is appearing in the NSLog, but my label chipCount is not updating with the new value. Is there perhaps a method I applied wrong when extracting the string from the array?
-(NSString *) dataFilePath {
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [path objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:#"Chips.plist"];
}
-(void)readPlist {
[self dataFilePath];
NSString *filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
chipArray = [[NSArray alloc] initWithContentsOfFile:filePath];
NSLog(#"%#\n", chipArray);
NSLog(#"%#\n", filePath);
NSString *chipcountString = [chipArray objectAtIndex:0];
chipsFloat = [chipcountString intValue];
chipCount.text = [NSString stringWithFormat:#"%i", chipsFloat];
//[arrayForPlist release];
}
}

I think this is a multithread problem. Update UI must in the main thread. Maybe readPlist is
executed in another thread.
Try this code below, maybe it can help you:
[self performSelectorOnMainThread:#selector(theProcess:) withObject:nil waitUntilDone:YES];
- (void) theProcess:(id)sender
{
....
chipCount.text = [NSString stringWithFormat:#"%i", chipsFloat];
}

Assusming that chipcount is a UILabel.. is it possible that you need to tell it to refresh the label?
[chipcount setNeedsDisplay];
Just an idea.

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

Why is my NSMutableDictionary null?

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];

Simple NSSArray regarding strings and NSRangeException

I have a simple question. I am designing some simple highscores code yet I am having alot of trouble with it, specifically storing and saving players names. I have not been programming for very long in obj-c, only 2 weeks. I am not quite sure what is going on when I use NSStrings in an array.
Here is the code for saving strings:
-(NSString *) getFilePath2 {
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"savedFile2.plist"];
}
-(void) savePlayerNameData {
NSArray *highScoreNames = [[NSArray alloc]
initWithObjects:
playerName1,
playerName2,
playerName3,
playerName4,
playerName5,
nil];
[highScoreNames writeToFile:[self getFilePath2] atomically:YES];
}
-(void) loadPlayerNameData{
// load data here
NSString *myPath = [self getFilePath2];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists) {
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
playerName1 = [values objectAtIndex:0];
playerName2 = [values objectAtIndex:1];
playerName3 = [values objectAtIndex:2];
playerName4 = [values objectAtIndex:3];
playerName5 = [values objectAtIndex:4];
}
else {
NSLog(#"first Launch. no file yet");
}
}
I end up getting this error :
2012-08-15 22:25:30.780 Pig Fly![5304:f803] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
*** First throw call stack:
(0x14c5022 0xec5cd6 0x146da48 0x146d9b9 0x14bec30 0xbd21 0x62e2 0x964eb6 0x1499936 0x14993d7 0x13fc790 0x13fbd84 0x13fbc9b 0x13ae7d8 0x13ae88a 0x28626 0x1fdd 0x1f45)
terminate called throwing an exception(lldb)
However, what I find very interesting is that when I write similar code for saving int values, The program runs fine. This is the working int code:
-(NSString *) getFilePath {
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"savedFile.plist"];
}
-(void) saveData {
//save data here
NSArray *highScores = [[NSArray alloc]
initWithObjects:
[NSString stringWithFormat:#"%i",highScore1],
[NSString stringWithFormat:#"%i",highScore2],
[NSString stringWithFormat:#"%i",highScore3],
[NSString stringWithFormat:#"%i",highScore4],
[NSString stringWithFormat:#"%i",highScore5],
nil];
[highScores writeToFile:[self getFilePath] atomically:YES];
}
-(void) loadData{
// load data here
NSString *myPath = [self getFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists) {
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
highScore1 = [[values objectAtIndex:0] intValue];
highScore2 = [[values objectAtIndex:1] intValue];
highScore3 = [[values objectAtIndex:2] intValue];
highScore4 = [[values objectAtIndex:3] intValue];
highScore5 = [[values objectAtIndex:4] intValue];
}
else {
NSLog(#"first Launch. no file yet");
}
}
Can anybody tell me what is going on? What are the differences that need to be kept in mind when writing NSArrays for ints and NSStrings?
Make sure that playerName1 is not NULL.

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.

iPhone: Memory leak when using NSOperationQueue

I'm sitting here for at least half an hour to find a memory leak in my code.
I just replaced an synchronous call to a (touch) method with an asynchronous one using NSOperationQueue.
The Leak Inspector reports a memory leak after I did the change to the code.
What's wrong with the version using NSOperationQueue?
Version without a MemoryLeak
-(NSData *)dataForKey:(NSString*)ressourceId_
{
NSString *cacheKey = [self cacheKeyForRessource:ressourceId_]; // returns an autoreleased NSString*
NSString *path = [self cachePathForKey:cacheKey]; // returns an autoreleased NSString*
NSData *data = [[self memoryCache] objectForKey:cacheKey];
if (!data)
{
data = [self loadData:path]; // returns an autoreleased NSData*
if (data)
{
[[self memoryCache] setObject:data forKey:cacheKey];
}
}
[[self touch:path];
return data;
}
Version with a MemoryLeak (I do not see any)
-(NSData *)dataForKey:(NSString*)ressourceId_
{
NSString *cacheKey = [self cacheKeyForRessource:ressourceId_]; // returns an autoreleased NSString*
NSString *path = [self cachePathForKey:cacheKey]; // returns an autoreleased NSString*
NSData *data = [[self memoryCache] objectForKey:cacheKey];
if (!data)
{
data = [self loadData:path]; // returns an autoreleased NSData*
if (data)
{
[[self memoryCache] setObject:data forKey:cacheKey];
}
}
NSInvocationOperation *touchOp = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(touch:) object:path];
[[self operationQueue] addOperation:touchOp];
[touchOp release];
return data;
}
And of course, the touch method does nothing special too. Just change the date of the file.
-(void)touch:(id)path_
{
NSString *path = (NSString *)path_;
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:path])
{
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSDate date], NSFileModificationDate, nil];
[fm setAttributes: attributes ofItemAtPath:path error:nil];
}
}