NSNotificationCenter addObserver not responding - ios

In my app (game) I'm trying to use the NSNotificationCenter to pause and resume the game when either the center/home or lock button is pressed. This is the code I'm using:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(pauseLayer:)
name:UIApplicationWillResignActiveNotification
object:self.view.layer.sublayers];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(pauseLayer:)
name:UIApplicationDidEnterBackgroundNotification
object:self.view.layer.sublayers];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(resumeLayer:)
name:UIApplicationWillEnterForegroundNotification
object:self.view.layer.sublayers];
I have experimented with putting it in lots of different places like viewDidLoad, viewDidAppear, initWithNibNameOrNil, but although they are all being called, the methods pauseLayer and resumeLayer never get called, even though the app delegate method does. Why doesn't this code work?

change the addObserver calls and remove self.view.layer.sublayers from the object param. change it to nil.
EDIT: more info
Sure. The object param tells NSNotificationCenter which object's notification you want to observe. When you specify self.view.layer.sublayers you are observing UIApplicationWillEnterForegroundNotification et al only sent by the sublayers array. Of course, the sublayers array does not send this notification. When you specify object:nil you are observing the notification from any object. That is appropriate in this case. If you want to specify an object it would be [UIApplication sharedApplication].

Related

How to use UIApplicationDidBecomeActiveNotification

How to use UIApplicationDidBecomeActiveNotification?
Should I declare it in viewDidLoad or viewWillAppear to reload data when coming from background to foreground.
Does UIApplicationDidBecomeActiveNotification gets called only when app comes from background to foreground?
Please help.
Thanks.
Sometimes it is useful to have a listener of UIApplicationDidBecomeActiveNotification when you need to make some action in your view controller on wake up from background (in case you entered to background with this view controller on-screen). In such wake up viewWillAppear will not be triggered!
Example of use:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(someMethod) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)someMethod
{
<YOUR CODE AT WAKE UP FROM BACKGROUND>
}
Of course, you can also implement all you need at your app delegate class life cycle.
You get this notification if your app was interrupted by a phone call or push notification. Generally, if your application is getting active on screen after interruption.
You can register any class, that is loaded in memory by the moment application will become active as observer to this notification.
Use following code in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(someMethod:)
name:UIApplicationDidBecomeActiveNotification object:nil];
Use someMethod to handle this notification. And don't forget to remove this class as observer in dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
The OP asked about system notifications fired when the app is backgrounded and then foregrounded again. The Notification designed to handle this situation is the UIApplicationDidEnterBackgroundNotification and UIApplicationWillEnterForegroundNotification. If you want a notification that fires for a wider range of situations, such as when you have a system notification, take a phone call, a SMS comes in, or you slide up the control pane, as well as being backgrounded then you will want the UIApplicationWillResignActiveNotification and UIApplicationDidBecomeActiveNotification. It's important to recognize that these are different, since you might only need to react if your app is backgrounded, and not for other scenarios.

How do I call multiple methods in #selector for 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)

How to pick a selector inside a class for NSNotification?

keyboard = [[FTKeyboardHelper alloc] init];
I have a keyboard helper class, and would like to call the method keyboardShow that is defined inside the keyboard.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboard.keyboardShow:)
name:UIKeyboardWillShowNotification
object:nil];
However I get the error message Excepted :
Any advice?
What about
[[NSNotificationCenter defaultCenter] addObserver:keyboard
selector:#selector(keyboardShow:)
name:UIKeyboardWillShowNotification
object:nil];
I'm not sure you can "." Separate the selector, it's not a key path.
But I think that would be bad design, you should probably put that code inside your helper.
In the - init and unregister in the - dealloc or use a pair of - register and - unregistermethod to control this outside of the normal life cycle of your object.
But don't forget to unregister before the helper is deallocated, if not, you will crash the next time the keyboard shows up.

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 {
// ????
}
}

NSNotificationCenter: removeAllObserver for self works for several observing objects?

Say if I have several:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(notificationReceived:)
name:NotificationA
object:self.player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(notificationReceived:)
name:NotificationB
object:self.player];
The objects are all self.player but for different notifications, in the end I do:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Is this fine or do I have to use the full method to remove observer for each notification? Currently I'm having issue when the view controller is unloaded but player is still playing in background.
Thanks
The docs say: "removeObserver: Removes all the entries specifying a given observer from the receiver’s dispatch table." So your method call is enough.

Resources