I am developing a system to keep track of achievements and for that I use NSNotificationCenter. When an achievement is unlocked in a object in the app a notification is sent to JMAchievementHandler which sets a string to YES and saves the progress in NSUserDefaults. My problem is that the notifications are not working probably. Here is my code in JMAchievementHandler:
- (id)init {
self = [super init];
if (self) {
//Set strings to NO
achievementOne = @"NO";
achievementTwo = @"NO";
achievementThree = @"NO";
achievementFour = @"NO";
//Add observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationWithName:) name:@"achievement1" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationWithName) name:@"achievement2" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationWithName) name:@"achievement3" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationWithName) name:@"achievement4" object:nil];
//Add observer to observe delegate methods
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationFromDelegate:) name:@"notificationLaunch" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationFromDelegate:) name:@"notificationEnterBackground" object:nil];
}
return self;
}
- (void)receiveNotificationWithName:(NSNotification *)notification {
if ([[notification name] isEqualToString:@"achievement1"] || [achievementOne isEqualToString:@"NO"]) {
//unlock achievement
NSLog(@"%@ is unlocked", [notification name]);
achievementOne = @"YES";
}
else if ([[notification name] isEqualToString:@"achievement2"] || [achievementTwo isEqualToString:@"NO"]) {
//unlock achievement
NSLog(@"%@ is unlocked", [notification name]);
achievementTwo = @"YES";
}
else if ([[notification name] isEqualToString:@"achievement3"] || [achievementThree isEqualToString:@"NO"]) {
//unlock achievement
NSLog(@"%@ is unlocked", [notification name]);
achievementThree = @"YES";
}
else if ([[notification name] isEqualToString:@"achievement4"] || [achievementFour isEqualToString:@"NO"]) {
//unlock achievement
NSLog(@"%@ is unlocked", [notification name]);
achievementFour = @"YES";
}
}
- (void)receiveNotificationFromDelegate:(NSNotification *)notificationDelegate
{
if ([[notificationDelegate name] isEqualToString:@"notificationLaunch"]) {
[self loadDataOnLaunch];
}
else if ([[notificationDelegate name] isEqualToString:@"notificationEnterBackground"]) {
[self saveDataOnExit];
}
}
- (void)loadDataOnLaunch
{
NSLog(@"loadDataOnLaunch");
}
- (void)saveDataOnExit
{
NSLog(@"saveDataOnExit");
}
When I try to post a notification the NSLogs are not called. I use the following code to send notifications from my AppDelegate and ViewController.
- (void)achievement1ButtonPressed:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:@"achievement1" object:self userInfo:nil];
}
I hope you guys can help me out. Thanks a lot
- Jonas
Do you even have a method named
receiveNotificationWithName? When you entered the code, the autocomplete should have barfed on that, offeringreceiveNotificationWithName:instead (unless you wrote it first, withoutNSNotification*, then added it later…Anyway, there is a big difference between the two. Also, your handler is buggy. You should revisit that code.
There are lots of reasons to prefer blocks, and this points to one of them. You can just put your code right in the registration, and not worry about giving the wrong selector.
These look like one-shot notifications, so if you want to unregister the notification handler after it runs one time, do this (note the
__block).