I'm trying to get NSNotifications to work. At this moment, without success.
In my appDelegate.m file I have:
[[NSNotificationCenter defaultCenter] postNotificationName:#"first" object:nil];
In my mainViewController.m, in the viewDidLoad method I have
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(firstRun)name:#"first" object:nil];
and created a method (in mainViewController.m as well):
-(void) firstRun:(NSNotification *) notification
{
NSLog(#"This works!");
}
However, I do not see any output in the log when running the app.
What is wrong with my code? Please advise.
Wrong selector, should be:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(firstRun:)name:#"first" object:nil];
The answer above, which points out that you had used the wrong selector in the observer method, is definitely a problem.
Another thing that you should check is that you add the observer before the notification is posted. Notifications are synchronous. When posted, they will only be recognized by observers that are already registered.
I recommend that you set a breakpoint on the line where you post the notification, and also on the line where you add the observer, and see which gets hit first.
Related
I have two class which uses NSNotification to communicate with each other.
Currently, i have an issue with notification being fired twice, i've double/triple/even more checked that observer is not added more then 1 time, notification not being posted twice, did global search on my project for same notification.
My code is like below
Added Notification Observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:notification_deleteMediaFromGallery object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationReceiver:) name:notification_deleteMediaFromGallery object:nil];
Notification Receiver
- (void)notificationReceiver:(NSNotification*)notification {
if ([notification.name isEqualToString:notification_deleteMediaFromGallery]) {
if ([[notification.userInfo objectForKey:#"kind"] integerValue]==GalleryKindPhoto) {
//My statements
}
else if ([[notification.userInfo objectForKey:#"kind"] integerValue]==GalleryKindVideo) {
//My statements
}
}
}
Post Notification
dispatch_async(dispatch_get_main_queue(), ^{
[_browser reloadData];
[[NSNotificationCenter defaultCenter] postNotificationName:notification_deleteMediaFromGallery object:nil userInfo:#{#"index":#(_browser.currentIndex), #"kind":#(self.kind), #"function":[NSString stringWithFormat:#"%s",__PRETTY_FUNCTION__]}];
});
I have also tried this solution by EmptyStack but not get it to work.
I'll be very thankful to you if you could help me solve this issue.
Thanks.
Edit
NOTE
I've added observer in my viewdidload, and cant add/remove observer from viewwillappera/viewwillappear or viewdidappear/viewdiddisappear because the next viewcontroller which will be pushed on current viewcontroller will post notifications
I think you need to write dealloc method in your view controller. And remove All Notification observer in dealloc method,
- (void)dealloc
{
// Deregister observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:notification_deleteMediaFromGallery object:nil];
}
Hi please make sure your method is not calling two time from where you are firing notification.
& please add your notification observer in viewWillDisappear method.
I have three viewControllers, and I'm trying to send a notification from viewController 3 to viewController 1 and 2. I think the best way to do this is to use NSNotification. Here's what I have so far:
In class C - Post the notification
[[NSNotificationCenter defaultCenter] postNotficationName:#"Updated "object:self];
In class B
In class A and B - Register first for the notification
// viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleUpdate:) name:#"Updated" object:nil];
-(void)handleUpdate:(NSNotification *)notification {
NSLog(#"recieved");
}
This works so far. But when I de-register it in class A and B:
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
The handleUpdate method doesn't get called. So the obvious problem is when I removeObserver's for the notification.
My question is, if everything I did so far is correct, why isn't it working when I remove the removeObserver? If it's not correct, where can I removeObserver's?
Everything you did is right. this is how the notification work.
If your class A,B always need to handle the update, you won't removeObserver.
Because you add your "addObserver" in viewDidLoad. it means you addObserver only once.
The normal error is that you add "addObserver" in "viewWillAppear" or "viewDidAppear", it will add more than once observer in the class. Then, you have to removeObserver in viewDidDisappear.
Hi i am trying to use NSNotification center in my application.The selector method is not being called from the code.I found similar questions in this site like this, but still i am unable to resolve the error.
i am posting notification in appdelegate did finish launching as:
[[NSNotificationCenter defaultCenter] postNotificationName:#"ualert" object:self userInfo:userDict];
adding an observer in one of the view controller as:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(remoteNotificationReceived:)
name:#"ualert"
object:nil];
my selector method is:
- (void)remoteNotificationReceived:(NSNotification *)notification
{
NSLog(#"Notification: %#", notification.userInfo);
}
removing observer as:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
You are posting ualert in applicationDidFinishLaunching which will necessarily occur before your view controller is loaded (and therefore before you have added the observer for the notification).
Currently I'm only calling one method when application will enter foreground. How do I call various methods in #selector?
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(displayHappyFace)
name:UIApplicationWillEnterForegroundNotification
object:nil];
Just create a separate function for all your other function.
[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(AllFunction)
name:UIApplicationWillEnterForegroundNotification
object:nil];
All functions.
-(void) AllFunction
{
[self displayHappyFace];
[self otherFunction];
}
Add another observer to UIApplicationWillEnterForegroundNotification if you wish to keep the methods' logic separate:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(displayHappyFace)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(callOtherMethod)
name:UIApplicationWillEnterForegroundNotification
object:nil];
#selector supports only one method. Remember to remove self as the observer before releasing its memory, to avoid messages being passed to a nil object.
You can only put one selector there.
Best practice is to create a new method called handleNotificationName: for each notification.
Example:
- (void)handleUIApplicationWillEnterForegroundNotification:(NSNotification *)aUIApplicationWillEnterForegroundNotification { }
This makes it really easy to figure out where your app handles each notification and makes code maintenance easy.
Inside the handler method you can call whatever methods you need to. You can have conditional logic also based on state you have or based the userInfo dictionary of the Notification ( if it has one ).
Don't forget to remove your notification observer in you object's dealloc method (at least, if not somewhere else because you might not want to always receive the notification depending on the use case)
I have a split view controller, and the child masterView is attempting to send out a post notification under certain conditions in the 'viewDidAppear' method. However, the Observer that is located in the parent isn't ever being triggered.
Here is the observer code, implemented inside the viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(customerSearchStatusIsSelected:) name:#"CUSTOMER_ORDER_DID_CHANGE_NOTIFICATION" object:nil];
and this is the post I have in the child masterView's viewDidAppear:
[[NSNotificationCenter defaultCenter] postNotificationName:#"CUSTOMER_ORDER_DID_CHANGE_NOTIFICATION" object:nil userInfo:[NSDictionary dictionaryWithObject:_tableData forKey:#"data"]];
this is my selector method header
-(void)customerSearchStatusIsSelected:(NSNotification *)data
{
//some code
}
The childMasterView definitely sends out the post, but the selector I want the observer to call never gets called. What exactly am I missing here?
solution: needed to move the observer from viewDidLoad to viewDidAppear ... for whatever reason...