I am trying to use ScriptingBridge to write a small iTunes controller. The problem is to find an efficient way of getting notifyed whenever any changes occur. My first approch was to poll the input in a loop and just keep checking for differences. But I think there must be a more efficient way of getting notifyed about input!
Thanks in advance!
iTunes sends out a notification when something changes so just register for it in your init method of AppDelegate. Here's an example...
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:#selector(receivediTunesNotification:) name:#"com.apple.iTunes.playerInfo" object:nil];
The actual notifcation object in your method "receivediTunesNotification:" will contain information about the changes.
Related
Beginner programmer here, I'm using the Fabric TwitterKit in an XCode project (Objective C) to show some tweets, and I want to log when users interact with those tweets. I see from the documentation that TWTRNotificationConstants.h has some juicy stuff in it, and when I look at that file it includes a comment that "These are posted on the default notification center." I also see lots of potentially useful constants, but unfortunately I don't quite understand how to use the default notification center, nor how to use these constants to run certain code when, for example, a tweet is liked. What is the best way to run some code when a tweet is liked?
I finally figure this out and will answer my own question. TWTRNotificationConstants.h posts notification to the NSNotificationCenter. When you look in TWTRNotificationConstants.h it tells you the name of each notification. You can then set up an observer. For example, the observer below now lives in my FirstViewController.m file:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(likeTweetNotification:) name:#"TWTRDidLikeTweetNotification" object:nil];
You then need to create a method with your selector name to do something when the notification is received. In this example, it might look like this:
- (void)likeTweetNotification:(NSNotification *) notification {
// do something
}
Also note that the notification carries some extra information in the userinfo dictionary that can be a part of NSNotifications. It seems to be the tweet's #username and text. You could access that dictionary by adding some lines to the above method like so:
- (void)likeTweetNotification:(NSNotification *) notification {
NSDictionary *tweetInfoDict = [notification userInfo];
NSLog(#"Dictionary: %#", [tweetInfoDict description]);
}
I'm still picking up ObjC and I'm just trying to make sure I understand the concept of NSNotifications fully:
The [NSNotificationCenter defaultCenter] is a stationary object which is not the sender or the receiver. It merely routes an NSNotification, but in no way, shape, or form handles the event (by default).
Is that correct?
Theory:
Would that allow an AppDelegate to push a notification to the defaultCenter and have something further on in the responder chain / display list (e.g., UITableViewCell) pick up on the action?
Exactly. NSNotificationCenter is just the clearinghouse for the notifications. It keeps track of all the objects observing each notification, so that when a notification is posted, it can be routed to all the right observers.
And yeah, no reason why your AppDelegate can't post a notification that gets picked up by things like a UITableViewCell. NSNotifications are great for situations where an object has to send data to other objects, or tell them that something happened, and you won't know what the recipients should be until runtime.
I'm using MPMusicPlayerController to play a list of mp3 in my app.
The only problem is when I set the volume level, according with app configuration, appears a Volume Level pop up.
I tried to find any property in order to hide it, but I didn't find.
The code I'm using is:
if (audioPlayer)
if ([audioPlayer isPlaying])
[audioPlayer stop];
self.musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handlePlaybackStateChanged:) name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object:self.musicPlayer];
[self.musicPlayer beginGeneratingPlaybackNotifications];
[self.musicPlayer setAccessibilityElementsHidden:YES];
self.musicPlayer.volume = volume;
[self.musicPlayer setQueueWithItemCollection:mediaItemCollection];
self.musicPlayer.repeatMode = MPMusicRepeatModeAll;
[self.musicPlayer play];
My question is, Any way to avoid this pop up?
Thanks.
I found a workaround for this problem in other post
But, there is not a direct way to perform that without using MPVolumeView "invisible"?
Sorry :)
I have two view that when you switch from one to another, they call a notification to the view that's about to get loaded to refresh the content. The weird thing is that the first time the view loads, it will call it once, the next time twice, and so on. I concluded that it's because they keep getting added every time the view loads. Since the dealloc never get's called it's still there and it will keep adding now.
So is there a way to check if the notification exists before getting added to fix this issue?
Here's what I have in my viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ReloadGridNotification:) name:#"ReloadOHGridView" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ReloadBadgeNotification:) name:#"reloadBadge" object:nil];
And my dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Thanks!Coulton
EDIT 1:
I show my views in a UINavigationController and switch between them. Here's my code to refresh the different view:
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadBadge" object:self];
}
Every time you call addObserver, the notification center will add a entry to its internal structures. This means the notification center will call your observer once more every time you call viewDidLoad.
If your view is unloaded for any reason and then reloaded, then viewDidLoad will get called again. Your removeobserver will not get called until the object is destroyed, which may explain why your removeobserver did not work.
You should either check whether you have already called addObserver with a flag, or manually remove the observer with removeObserver when you unload your view in the viewDidUnload method.
Edit1: Alternatively, can you add the observers somewhere else, like in the App Delegate?
When memory gets tight the OS will dump your view, but will first call viewDidUnload; when it has to reload them it calls viewDidLoad. dealloc, however, is only called when all references to your view have been released, which likely doesn't happen until your app quits.
As a result, as #futureelite7 noted, you're adding a new observer every time your view is reloaded but, effectively, are never removing it.
All you need to do is ensure that the observer is added in viewDidLoad and removed in viewDidUnload you won't have the multiple notification problem. No need for a flag or for putting the observer anywhere else.
From your comments it sounds like you might have tried it, but I suggest going through your code and making absolutely certain you're only adding them in DidLoad and are always removing them in DidUnload. It works like a charm in app after app.
Edited to Add
Because your view keeps getting unloaded, which only happens if you do it manually, if all references to it are lost, or if memory gets tight, I suggest looking at all three to help ensure you're doing what you can to keep your view around.
I have a MAAttachedWindow that shows itself when a status bar item is clicked. I need to have it close when its clicked outside of. I found some other directions that say to set it as a delegate and use - (void)windowDidResignKey:(NSNotification *)notification to detect when the user exits the window. I've tried it many times but can't seem to get it working which is probably because I didn't correctly set the delegate. Whats the best way to set the delegate so it will respond to the notification? The code is available here.
Thanks in advance
I found out to get the notification you have to register for it.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(windowDidResignKey:)
name:NSWindowDidResignKeyNotification
object:self];