I need a list of all the distributed notifications that iTunes and Spotify publish. I can't seem to find such a thing on SO or Google, so I wanted to see if maybe I could just subscribe to all the notifications and just note down which ones are triggered. I've successfully subscribed to one, but I can't subscribe to all of them.
// Works just fine
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(itunesNotification)
name:#"com.apple.iTunes.playerInfo" object:nil];
[center addObserver:self selector:#selector(spotifyNotification)
name:#"com.spotify.client.PlaybackStateChanged" object:nil];
// Doesn't work :(
[center addObserver:self selector:#selector(itunesNotification)
name:#"com.apple.iTunes" object:nil];
[center addObserver:self selector:#selector(itunesNotification)
name:#"com.apple.iTunes.*" object:nil];
// Same result with com.spotify.client and .*
Again, if I could have a list of all the iTunes/Spotify notifcations, that would work as well. My intention is not to subscribe to all notifications in the end, but rather to see what's out there and pick a few. Hope that makes sense, thanks a bunch!
I figured it out! You can observe all of the distributed notifications on your Mac by supplying nil as the name.
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(allNotifications:) name:nil object:nil];
Related
I add an observer
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:#selector(handleScreenBrightnessMonitoringNotification:)
name:UIScreenBrightnessDidChangeNotification
object:nil];
In one of my methods, I hope to call handleScreenBrightnessMonitoringNotification directly without using postNotification. Is there any way I can do it?
I am using the Reachability class to check whether the network is available or not in my tvOS app.
When I try the notification kReachabilityChangedNotification its not calling the the method.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleNetworkChange:) name:kReachabilityChangedNotification object:nil];
The method handleNetworkChange is not getting called.
Did you actually post that notification?
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:nil];
I have a method in a view controller that sets up some notifications:
- (void)processState
{
MYGame *game = [[MYGameManager sharedInstance] getGameAtIndex:self.indexPath.row];
if(game)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notification_gameUpdated:) name:kMYNotificationGameUpdated object:game];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notification_gameEnded:) name:kMYNotificationGameEnded object:game];
}
}
Then there's a game updated method, which is called every so often:
- (void)notification_gameUpdated:(NSNotification *)notification
{
MYGame *game = notification.object;
_game_status = (game.entity.bet.isWinning) ? MYGameStatusWin : MYGameStatusLose;
}
And finally, when the game ends:
- (void)notification_gameEnded:(NSNotification *)notification
{
MYGame *game = notification.object;
// Clear the notifications
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameUpdated object:game];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameEnded object:game];
self.gameIsActive = NO;
}
Trouble is, that even when I remove the observers (and a breakpoint shows that this is happening), then the notification_gameUpdated: method is still being called. If I change it to
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMYNotificationGameUpdated object:nil];
This still won't clear it. But if I change it to
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:game];
Then that does clear it. As does
[[NSNotificationCenter defaultCenter] removeObserver:self];
But I'm not keen on doing either, because I'd rather the code was clean and I don't want any "gotchas" further down the line if I need to add more observers. I've checked the rest of the code and cannot find any other classes adding observers to this object, although other view controllers do listen to the same messages.
Is processState called more than once? That would explain the behavior you are seeing.
If it is, one way to fix the issue would be to always remove listeners before adding them. See e.g. this answer.
edit #2
try registering with object:nil and when you post the notification include the reference to game in the userInfo dictionary. then, in the receiver, you can compare against game and perform whatever action you want if it is a match. this should get you the same behavior as if you were using object:game, although it does not explain why your current implementation isn't working
when you register for notifications like this:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(notification_gameUpdated:)
name:kMYNotificationGameUpdated
object:game];
the #selector will only be performed if that particular instance of game is the sender.
is it possible that you're re-initializing your shared instance of game after registering? that could cause the behavior you're experiencing
try registering for notifications with object:nil and see what happens. (assuming there are not multiple games running concurrently)
So it turned out that the reason for the issue was Method Swizzling. The project I'm working on has addObserver:selector:name:object: and removeObserver:name:object: swizzled. The issue was that although addObserver has been handled correctly, removeObserver is only removing objects on specific conditions. This will obviously need to be changed...
But I post this as a warning to others... Swizzling can be dangerous to your health!
Apologies for any time wasted.
I have an app which has to work in both portrait and landscape more and the UITabBar should adjust to current orientation (it has custom background and selected items). So, for the rest of views I just override the - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method and it works perfectly.
How would I do that for the .moreNavigationController of UITabBarController ? I've tried adding an observer (the selector is in extension of UITabBarController):
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:self.moreNavigationController];
but it never get called.
Am I missing something or what would be the best way to handle this situation ?
Solution: somewhy UIDeviceOrientation is not firing correctly, so better to use statusBarOrientation, works as a charm.
the final code which work is this:
in main UITabBarController, viewDidLoad:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
the didRotate selector method:
- (void) didRotate:(NSNotification *)notification{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(UIInterfaceOrientationIsPortrait(orientation)) {
// Portrait
} else {
// Landscape
}
}
Thanks for help.
You are registering your UITabBarController for a notification which never gets posted. Take a look at the documentation NSNotificationCenter Reference for the addObserver:selector:name:object method
- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender
notificationSender:
The object whose notifications the observer wants to receive; that is, only notifications sent by this sender are delivered to the observer.
If you pass nil, the notification center doesn’t use a notification’s sender to decide whether to deliver it to the observer.
so, if you specify the . moreNavigationController as the sender, you wont get those notifications, because it never posts such ones. Instead pass nil to ignore the sender and listen to the status bar change regardless of who sent it.
By the way, in this SO Answer is a summary of how you can react to orientation change.
And at last. If it still doesn't work, you can try this:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Yes, you forgot to post notification, which will call you own notification:
[[NSNotificationCenter defaultCenter] postNotificationName: UIApplicationDidChangeStatusBarOrientationNotification object:self];
or if you dont wont to send anything just set object as nil:
[[NSNotificationCenter defaultCenter] postNotificationName: UIApplicationDidChangeStatusBarOrientationNotification object:nil];
The best way to implement the same is first addObserver and then remove observer to avoid the crash:-
-(void)viewDidLoad{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:#"UIDeviceOrientationDidChangeNotification" object:nil];
}
//Now Remove Observer
-(void)viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self #"UIDeviceOrientationDidChangeNotification" object:nil];
}
Settting up the observer code:
NSNotificationCenter *defaultCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
[defaultCenter addObserver:self
selector:#selector(updateLog:)
name:#"Update Log"
object:nil];
Sending the notification code:
[[NSNotificationCenter defaultCenter] postNotificationName:#"Update Log" object:self];
With the method defined as:
-(void)updateLog: (NSNotification *) notification {
NSLog(#"Update Log"); }
The text "Update Log" does not appear in the log when the notification is sent.
Thanks for any ideas for why this code is not working.
There is a difference between "the notification center for workspace notifications" Apple:
[[NSWorkspace sharedWorkspace] notificationCenter]
and "the process’s default notification center" Apple:
[NSNotificationCenter defaultCenter]
You need to pick one of those to use.