views:

90

answers:

2

I'm working on a Cocoa app that monitors what you're listening to in iTunes, and since I'm targeting Mac OS 10.5 and higher, I've decided to use Scripting Bridge.

If I try to close iTunes too close to the time that my app polls it for the current track, iTunes will immediately relaunch! The only way to reliably prevent this behavior is to quit my app first, then quit iTunes.

Switching to EyeTunes solves the problem, but it's a fairly old codebase and I was hoping that I could accomplish this without an external library. Surely I'm doing something wrong that's causing the relaunch?

Here's some sample code; this snippet is run every few seconds, triggered by an NSTimer.

#import "iTunesBridge.h" // auto-generated according to Apple's docs

-(void)updateTrackInfo {
    iTunesApplication *iTunes = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
    iTunesTrack *currentTrack = [iTunes currentTrack];
    // inspect currentTrack to determine what's being played...
    [iTunes release];
}

Is this a known issue with Scripting Bridge, or am I using it incorrectly?

+1  A: 

It sounds like the application has already closed by the time you send the request so it will relaunch.

SBApplication applicationWithBundleIdentifier:

For applications that declare themselves to have a dynamic scripting interface, this method will launch the application if it is not already running.

stefanB
He's not using `applicationWithBundleIdentifier:`, though.
Peter Hosey
+2  A: 

Is this a known issue with Scripting Bridge, or am I using it incorrectly?

Possibly both, although the documentation is unclear on this.

The applicationWithBundleIdentifier: class method will launch the application if it isn't running, but the documentation doesn't say that about the initWithBundleIdentifier:instance method.

The safest way is to use NSRunningApplication (or the Process Manager for Leopard compatibility) to find running iTunes processes, pick one, and target it by its process identifier. If you don't find any iTunes processes, then, of course, don't try to target one (skip creating and talking to an SBApplication).

Peter Hosey
the only difference between those 2 methods should be that the `applicationWith...` returns `autoreleased` application ...
stefanB
I agree, that *should* be the only difference. ☺ And that does match the behavior he describes, which implies that it is his problem. The solution is, as I suggested, to look for an iTunes process and (only upon finding one) target it by PID, rather to target iTunes by its bundle ID.
Peter Hosey
That worked like a charm! Thanks for your help.
Justin Voss
Make sense ....
stefanB