views:

220

answers:

1

I am basically trying to implement an achievement tracking setup in my app.

I have a managedObjectModel class called StatTracker to keep track of all sorts of stats and I want my Achievement tracking class to be notified when those stats change so I can check them against a value and see if the user has earned an achievement.

I've tried to impliment KVO and I think I'm pretty close to making it happen but the problem I'm running into is this:

So in the appDelegate i have an Ivar for my Achievement tracker class, I attach it as an observer to a property value of my statTracker core data entity in the applicationDidFinishLaunching method.

I know its making the connection because I've been able to trigger a UIAlert in my AchievementTracker instance, and I've put several log statements that should be triggered whenever the value on the StatTracker's property changes. the log statement appears only once at the application launch.

I'm wondering if I'm missing something in the whole object lifecycle scheme of things, I just don't understand why the observer stops getting notified of changes after the applicationDidFinishLaunching method has run. Does it have something to do with the scope of the AchievementTracker reference or more likely the reference to my core data StatTracker is going away once that method finishes up.

I guess I'm not sure the right place to place these if that is the case. Would love some help. Here is the code where I add the observer in my appDidFinishLaunching method:

 [[CoreDataSingleton sharedCoreDataSingleton] incrementStatTrackerStat:@"timesLaunched"];

achievementsObserver = [[AchievementTracker alloc] init];
    StatTracker *object = nil;
object = [[[CoreDataSingleton sharedCoreDataSingleton] getStatTracker] objectAtIndex:0];
NSLog(@"%@",[object description]);
[[CoreDataSingleton sharedCoreDataSingleton] addObserver:achievementsObserver toStat:@"refreshCount"];

here is the code in my core data singleton:

-(void) addObserver:(id)observer  toStat:(NSString *) statToObserve {

NSLog(@"observer added");
NSArray *array = [[NSArray alloc] init];
array = [self getStatTracker];
[[array objectAtIndex:0] addObserver:observer forKeyPath:statToObserve options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];

}

and my AchievementTracker:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"achievemnt hit");
//NSLog("%@", [change description]);

     if ([keyPath isEqual:@"refreshCount"] && ((NSInteger)[change valueForKey:@"NSKeyValueObservingOptionOld"] == 60) ) { 
NSLog(@"achievemnt hit inside");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"achievement unlocked" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
    [alert show];

     }

}
+1  A: 

turns out i needed to retain the reference to the stattracker.

nickthedude