I know you can use [iTunesDNC addObserver:self selector:#selector(updateInfo:) name:#"com.apple.iTunes.playerInfo" object:nil]; to get a notification every time the player changes song/stops/plays/etc. But what I need is a notification every time information is changed on iTunes (ex. song title changed, lyrics changed, artist, etc)
Any suggestions? Im pretty sure I just need to change com.apple.iTunes.playerInfo to something else that is not playerInfo.
I know it should be posible, because there is an app called SongGenie that will change its info if you edit a song's ID3 tags on iTunes or add lyrics.
Thank you!
Yes, there is a way. Every time song info is changed iTunes posts a "com.apple.iTunes.sourceSaved" notification whose userInfo dictionary is the user's library.
You can check out this and other notifications that iTunes sends by listening to every notificaion posted to the Distributed Notification Center.
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:#selector(allDistributedNotifications:)
name:nil
object:nil];
- (void) allDistributedNotifications:(NSNotification *)note
{
NSString *object = [note object];
NSString *name = [note name];
NSDictionary *userInfo = [note userInfo];
NSLog(#"<%p>%s: object: %# name: %# userInfo: %#", self, __PRETTY_FUNCTION__, object, name, userInfo);
}
or use scripting bridge, https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ScriptingBridgeConcepts/AboutScriptingBridge/AboutScriptingBridge.html#//apple_ref/doc/uid/TP40006104-CH3-SW9
Related
I am trying to implement a OS X (10.10) client for the real time bitcoin exchange rate from bitstamp.com. They offer a great api, unfortunately I can't get the websocket api (https://www.bitstamp.net/websocket/) to work in an OS X Objective C app.
Everyone is pointing me to the libPusher Github project (https://github.com/lukeredpath/libPusher) but I tried literally everything I can think of, I can't get it to receive any pushes on 10.10.
Following the wiki page I downloaded the pre-compiled static library and dragged all files into my projects (I also made sure the "copy" checkbox was checked) and my sample applications compiles. Unfortunately, I never see either the "event through block" or "event through delegate" on the console. However I know that trades happened in the mean time, so that can't be the issue. Any ideas?
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
PTPusher* client = [PTPusher pusherWithKey:#"de504dc5763aeef9ff52" delegate:self encrypted:YES];
[client connect];
PTPusherChannel *channel = [client subscribeToChannelNamed:#"live_trades"];
[channel bindToEventNamed:#"trade" handleWithBlock:^(PTPusherEvent *channelEvent) {
// channelEvent.data is a NSDictionary of the JSON object received
NSLog(#"event through block"); // <-- never called
}];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didReceiveEventNotification:)
name:PTPusherEventReceivedNotification
object:client];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didReceiveChannelEventNotification:)
name:PTPusherEventReceivedNotification
object:channel];
}
- (void)didReceiveEventNotification:(NSNotification *)notification // <-- never called
{
NSLog(#"event through delegate");
PTPusherEvent *event = [notification.userInfo objectForKey:PTPusherEventUserInfoKey];
}
After talking to the developer I found the problem:
In my code, the PTPusher instance is a local variable defined in the .m file.
However, it needs to be a strong variable defined in the .h file:
#property (strong) PTPusher* client;
Then in the .m file, you can easily use it (don't forget to synthesize it!):
self.client = [PTPusher pusherWithKey:#"de504dc5763aeef9ff52" delegate:self encrypted:YES];
[self.client connect];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didReceiveEventNotification:)
name:PTPusherEventReceivedNotification
object:self.client];
PTPusherChannel *channel = [client subscribeToChannelNamed:#"live_trades"];
I have a Book object that listens to a notifications. When I'm trying to remove the book from the view I have this piece of code:
BookItem *book = [books objectAtIndex:bookIndex];
[book removeFromSuperview];
[books removeObject:book];
book = nil;
After I'm done removing books I send a "rearrange" notification and I'm getting an error in the BookItem object, where I'm accessing nulls ...
What could be the problem? how can I stop listening to notifications after I'm removing the object?
You need to stop observing:
[[NSNotificationCenter defaultCenter] removeObserver:book];
Ive set up a notification centre with the following code in a class called ConnectionController
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(aChangeCalendarMethod:) name:#"updateCalendar" object:nil];
And have a sender in another class (MonthFieldValidator)
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateCalendar" object:self];
MonthFieldValidator has a property of NSString type called month which I want to pass the value of back to connection controller.
All I seem to be able to do is get this
Printing description of testObject:
(NSObject *) testObject = 0x4055c00000000000
And the object doesn't have the month property (or at least that I can access).
Presumably I will have to useruser info?
Do this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateCalendar" object:yourMonthStringHere];
Method that will be called is:
-(void)aChangeCalendarMethod:(NSNotification*)notification
{
NSString *strMonth = (NSString *)[notification object]; //retrieve passed string like this
//continue other code
}
So my goal is to deliver a notification to another class with using NSNotificationCenter, I also want to pass object with the notification to the other class, how should I do this?
You must first register a notification name
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(startLocating:) name:#"ForceUpdateLocation" object:nil]; // don't forget the ":"
And then post a notification with a dictionary of parameters
[[NSNotificationCenter defaultCenter] postNotificationName:#"ForceUpdateLocation" object:self userInfo:[NSDictionary dictionaryWithObject:#"1,2,3,4,5" forKey:#"categories_ids"]];
and the method will be
- (void)startLocating:(NSNotification *)notification {
NSDictionary *dict = [notification userInfo];
}
Just call any method for posting notifications as described here, for instance :
to post a notification :
-(void)postNotificationName:(NSString *)notificationName
object:(id)notificationSender
userInfo:(NSDictionary *)userInfo;
where userInfo is a dictionary containing useful objects.
On the other side to register for notifications :
-(void)addObserver:(id)notificationObserver
selector:(SEL)notificationSelector
name:(NSString *)notificationName
object:(id)notificationSender;
You could also check Apple's Notification Programming Topics.
i need a little help, i currently have a method; updateTrackInfo in my Mac OS X application which gets the artist name, the track name and duration of the track currently being played in iTunes
However i want the app to listen for the distributed iTunes notification; com.apple.iTunes.playerInfo then call the method updateTrackInfo when ever the notification is distributed by iTunes. Please could someone help me, on what i would need to write in both the header and implementation file.
Thanks, Sami.
You're looking for -[NSDistributedNotificationCenter addObserver:selector:name:object:]:
NSDistributedNotificationCenter *dnc = [NSDistributedNotificationCenter defaultCenter];
[dnc addObserver:self selector:#selector(updateTrackInfo:) name:#"com.apple.iTunes.playerInfo" object:nil];
Elsewhere in the same class...
- (void) updateTrackInfo:(NSNotification *)notification {
NSDictionary *information = [notification userInfo];
NSLog(#"track information: %#", information);
}
It even gives you a whole bunch of track information in the notification. Isn't that nice?
Thanks for your help, you helped me correct my code, I had this written up:
- (id) init {
self = [super init];
if (!self) return nil;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"com.apple.iTunes.playerInfo"
object:nil];
return self;}
- (void) receiveNotification:(NSNotification *) notification {
if ([#"com.apple.iTunes.playerInfo" isEqualToString:#"com.apple.iTunes.playerInfo"]) {
NSLog (#"Successfully received the test notification!");
}}
But it used NSNotificationCenter instead of NSDistributedNotificationCenter. Which is where I was going wrong.
Thanks, Sami.