Re: delayed NSWorkspaceDidTerminateApplicationNotification under 10.6?
Re: delayed NSWorkspaceDidTerminateApplicationNotification under 10.6?
- Subject: Re: delayed NSWorkspaceDidTerminateApplicationNotification under 10.6?
- From: Dave Keck <email@hidden>
- Date: Wed, 8 Sep 2010 13:18:10 -0400
>
> After the release of Snow Leopard, it seems that [iTunes isRunning]
> returns YES for a short while even after the application has quit (I
> believe this applies to all apps, not just iTunes, but I haven't
> confirmed this yet). As a result, my app would relaunch iTunes,
> assuming it was still running. Not cool.
>
I can't comment decisively on your problem with Scripting Bridge, but I
experienced some relaunching issues with NSAppleScript when attempting to
control an application other than iTunes. Since both NSAppleScript and
Scripting Bridge are based on Apple events, I imagine we experienced the
same underlying problem. Anyway, I ended up using the Process Manager APIs
to check whether the app in question was running before executing an
AppleScript to issue commands to it. (It seems NSRunningApplication is the
modern API for 10.6+.)
In your case, I would try something like this:
==========
BOOL iTunesOpen = NO;
ProcessSerialNumber currentPSN;
for (currentPSN.highLongOfPSN = kNoProcess, currentPSN.lowLongOfPSN =
kNoProcess;;)
{
OSErr getNextProcessResult = 0;
getNextProcessResult = GetNextProcess(¤tPSN);
// For production code we should of course be handling errors
gracefully.
assert(getNextProcessResult == noErr || getNextProcessResult ==
procNotFound);
if (getNextProcessResult == procNotFound) break;
if ([[[(id)ProcessInformationCopyDictionary(¤tPSN,
kProcessDictionaryIncludeAllInformationMask) autorelease]
objectForKey: (NSString *)kCFBundleIdentifierKey]
isEqualToString: @"com.apple.iTunes"])
{
iTunesOpen = YES;
break;
}
}
// Only if iTunes is open will we attempt to request its player position,
to avoid relaunching it.
if (iTunesOpen) return [iTunes playerPosition];
return -1;
==========
Finally I tried replacing ScriptingBridge with NSAppleScript:
>
> currentTimeScript = [[NSAppleScript alloc] initWithSource:@"try\n\
> if application
> \"iTunes\" is running then\n\
> tell application
> \"iTunes\"\n\
> if player state is
> not stopped then\n\
> return player
> position\n\
> end if\n\
> end tell\n\
> end if\n\
> on error\n\
> return 0\n\
> end try"];
>
> This yielded somewhat better results. iTunes now quits gracefully most
> of the time, but is still relaunched every now and then (some users
> report it still happens each and every time). Now I'm out of ideas...
> What did I miss? Should I file a radar?
I only know enough about AppleScript to avoid it, but I believe iTunes is
being launched necessarily for the NSAppleScript to compile. (Meaning that
regardless of what checks you surround your "critical" AppleScript with, I
believe it will still launch iTunes if the script contains "tell application
'iTunes'".) If for some reason you choose the AppleScript route, I got
around this by only allowing the "tell application 'iTunes'" AppleScript to
compile if we're sure iTunes is already running. For example, after checking
iTunes' running state using the code above:
==========
// Only compile/execute the script if iTunes is already running, to
prevent it from relaunching.
if (iTunesOpen)
[[[[NSAppleScript alloc] initWithSource: @"tell application id
\"com.apple.iTunes\" to play"] autorelease] executeAndReturnError: nil];
==========
Of course this technique has a race between the time that we check whether
iTunes is running and the time that we actually tell it to do something, but
I imagine this window is small enough to be acceptable.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden