Notification fired twice even tho adding observer only once - ios

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.

Related

Where should I put removeObserver from NSNotification

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.

pushNotification to another viewController only show when view is active

Notification only called the function when observer_ViewController is active
AppDelegate.m
[[NSNotificationCenter defaultCenter] postNotificationName:kNewShipNotifaction object:ship];
observer_ViewController.m
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newShipCome:) name:kNewShipNotifaction object:nil];
}
- (void)newShipCome:(NSNotification *)notifacation{
[self updateNotifyWithShip:notifacation.object];
}
Notification didn't call the newShipCome:(NSNotification *)notification method when I'm in another viewController. When I switched to the observer_ViewController, the method still didn't get called.
So...how can I get notification update correctly when I'm not in the observer_ViewController ?
remove de-register code form viewWillDisappear it will work

NSNotificationCenter selector method is not called

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).

iOs Remove Observers from ViewController on TabBarController

I have a UITabBarController with some tab and in all of them i have:
-(void)viewDidappear:(BOOL)animated{
......
[[NSNotificationCenter defaultCenter] addObserverForName:kNotificationName object:nil queue: nil, usingBlock{...}
}
and
-(void)viewDidDisappear:(BOOL)animated{
......
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
In another class i post the notification with name kNotificationName:
[[NSNotificationCenter defaultCenter] postNotification:kNotificationName object:nil];
I've set some log on all of this methods, and the order they are called is correct but...if i switch from First to Second tab (and the notification is posted), the first and the second tab receive the notification (but the viewDidDisappear of the first tab is called!).
If from second tab i go to third tab, the first, second, and third tab receive the notification.
I've tried to use:
[[NSNotificationCenter defaultCenter] removeObserver:self name:postNotification:kNotificationName object:nil];
but the behaviour is the same. All observer are notified.
EDIT1:
As suggest to the other topic i've moved all in viewWillAppear: and viewWillDisappear:, but this haven't have any effect.
I've tried to remove the observer after have received the notification, like this:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserverForName:kDLSyncEngineSyncCompletedNotificationName object:nil queue:nil usingBlock:^(NSNotification *note) {
....
[[NSNotificationCenter defaultCenter] removeObserver:self name:kDLSyncEngineSyncCompletedNotificationName object:nil];
}];
}
But, using this (bad) approach too, the notification is received to the first tab too (i've added this code only on the first tab, to check if after press the second tab, the first tab is receiving again the notification).
EDIT2 - SOLVED - (but what is the difference?)
Instead of using *addObserverForName:object:queue:usingBlock*: I've used *addObserver:selector:name:object:* and in this way all works.
Apple documentation say this for the method with usingBlock:
The block is copied by the notification center and (the copy) held
until the observer registration is removed.
Sure, I've called removeObserver....
Inside the block in the addObserver method -
usingBlock:^(NSNotification *notification){
/*
do something
*/
[[NSNotificationCenter defaultCenter] removeObserver:self];
}];
As you might have already checked this in documentation -
Be sure to invoke removeObserver: or removeObserver:name:object: before notificationObserver or any object specified in addObserver:selector:name:object: is deallocated.

Notification Center - Obervers not working properly

I'm developing an app which has to communicate with an external accessory. The app has several requests to send to the external accessory.
My problem:
I'm using observers in different places (classes), I'm adding the following observers in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(observer1:)
name:EADSessionDataReceivedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(observer2:)
name:EADSessionDataReceivedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(observer3:)
name:EADSessionDataReceivedNotification object:nil];
The 1st Observer works very well, but I'm getting problems with the other two. They don't respond until the first one has been used. Do I need to add something else?
The flow is as follows:
Send a request to ext-acc and fire a flag to know which observer will take the returned data
ext-acc responds with data
The receiver method pushes a notification into notification center.
The observer with the flag in 1 will take the data (at this point do I need to remove the notification since no one else will need it?).
Looks you have a misunderstanding regarding how NSNotificationCenter works. You are registering your object (self) to observe the notification EADSessionDataReceivedNotification three times, each with it's own selector (observer1, observer2, observer3).
So, what is happening is correct for your code as written. When EADSessionDataReceivedNotification is posted, NSNotificationCenter sends the specified selector to each observer. There is no conditional logic or way to cancel a notification.
Given your description, it sounds like you should only be observing the notification once and checking your flag to determine how to process. Something like:
// observe notificaton
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(dataReceived:) object:nil];
// notification handler
- (void)dataReceived:(NSNotification *)notification {
if (someCondition) {
[self handleDataCondition1];
}
else if (aSecondCondition) {
[self handleDataCondition2];
}
else if (aThirdCondition) {
[self handleDataCondition3];
}
else {
// ????
}
}

Resources