NSNotificationCenter Observer stops receiving events when app is out of focus on Lion
-
01-03-2021 - |
Question
I have an app that subscribes to a specific kind of notifications from the default NSNotificationCenter.
On OSX Lion, it works fine, except that when the app loses the focus (another app becomes active), it stops receiving the events. When the app gains the focus, it starts receiving events again. The app did not have this behavior on previous versions of OSX, it always received notifications, even when it was out of focus.
What can I do to change this behavior?
Thanks! Nathan
Solution 3
It looks like the default behavior when adding an observer to a NSDistributedNotificationsCenter has changed to NSNotificationSuspensionBehaviorCoalesce, that does not deliver notifications when the app is inactive.
OTHER TIPS
I know its a bit late to answer this, still for my records and if some one still searching.
My OS X Menu bar app had the same problem. I wanted the app to observe all states.
Reason:
When the app looses focus,the observer is suspended.
ie. When the application becomes in-active it calls the method
-(void)applicationDidResignActive:(NSNotification *)notification
and by default the NSDistributedNotificationCenter object gets suspended.
Solution: I created an object for NSDistributedNotificationCenter
NSDistributedNotificationCenter *center=[NSDistributedNotificationCenter defaultCenter];
and then when the app looses focus its call the applicationDidResignActive method and inside that the NSDistributedNotificationCenter object is made to regain from suspended state by sending NO to setSuspended method.
-(void)applicationDidResignActive:(NSNotification *)notification
{
[center setSuspended:NO];
}
and then app starts observing even when it looses focus.
According to NSDistributionNotificationCenter
reference
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDistributedNotificationCenter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000396-BCICEHHB
The NSApplication class automatically suspends distributed notification delivery when the application is not active. Applications based on the Application Kit framework should let AppKit manage the suspension of notification delivery. Foundation-only programs may have occasional need to use this method.
You can either
set the observer's behavior when suspended to NSNotificationSuspensionBehaviorDeliverImmediately
using
- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(NSString *)notificationSender suspensionBehavior:(NSNotificationSuspensionBehavior)suspendedDeliveryBehavior
or set deliverImmediately
to YES when posting
- (void)postNotificationName:(NSString *)notificationName object:(NSString *)notificationSender userInfo:(NSDictionary *)userInfo deliverImmediately:(BOOL)deliverImmediately
to send notifications immediately under suspended state.
And make sure you're not periodically killing distnoted
.
I forgot I had an old launch agent script to killall distnoted
to avoid memory leaks.