Launch Mac application when iTunes starts without background process (like last.fm) - itunes

I would like to start my OSX application when iTunes loads, without having a background process to monitor when iTunes launches. The last.fm client seems to do this; I can find no background process when iTunes is closed, but as soon as it starts the last.fm app opens right along with it. Perhaps it is using some kind of iTunes plugin that can start another process?
It seems to be fairly trivial to do this with a background process, but I'd like to do it without one so my program isn't using system resources.
One option with a background process is to use NSWorkspace's notification center, such as:
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:#selector(appDidLaunch:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]
However, this obviously requires a background process. Another option I found was to use ProcessNotif, something like this:
ProcessNotif *x = [[ProcessNotif new] autorelease];
[x setProcessName: #"iTunes"];
[x setTarget: self];
[x setAction: #selector(doStuff)];
[x start];
This is probably even less ideal than the NSWorkspace method, and it too requires a background process.
So, is there some way to launch from iTunes when it launches, no background process required?
Thanks!

The last.fm client achieves that by installing an iTunes plugin. This plugin gets loaded when iTunes starts and then has a chance to start the last.fm app. To create a plugin you need the iTunes PlugIn SDK available here.

Related

Mac OS X -- receive notification when frontmost window changes

I am wondering whether there is a way in Mac OS X to receive a notification when the frontmost window switches to a different window -- either an Objective-C solution, or Python, or AppleScript, or something else. I want to look at the whole system, not just within my application. My app is trying to keep track of what file the user is currently working on, and I have a polling solution that gets the frontmost app and frontmost window every so often by running an AppleScript, but it would simplify my life if I could run that check only when I knew that the frontmost window had changed.
I've also looked at NSDistributedNotificationCenter and global event monitors for NSEvents, which are both useful in different ways, but don't seem able to give me the specific front-window-change notification that I'm ideally looking for.
Any ideas on directions I should try, or whether this is even possible, would be greatly appreciated!
I don't know of a way to get a notification when a window changes, however in objective-c you can get a notification when things happen at the application level. That might help you.
You want to register for NSWorkspace notifications...
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:#selector(nsworkspaceNotification:) name:nil object:nil];
Look at the bottom of the NSWorkspace class documentation for the notifications. Some that would help you are: NSWorkspaceDidLaunchApplicationNotification, NSWorkspaceDidActivateApplicationNotification, NSWorkspaceDidDeactivateApplicationNotification, NSWorkspaceDidHideApplicationNotification, NSWorkspaceDidUnhideApplicationNotification. There may be others.
Good luck.
I think you would capture NSWindowDidBecomeMainNotification. The notification object contains NSWindow.
best,

NSWorkspaceDidActivateApplicationNotification called before application is ready to use (launched)

I'm using both NSWorkspaceDidActivateApplicationNotification and NSWorkspaceDidLaunchApplicationNotification notifications to know which app the user is interacting with.
The problem is that, if an application is just opened and still launching, I first receive a activate notification, and soon afterwards a launch notification.
Is there any way to know within the activate method that the app is still launching and not yet ready for use? (Still bouncing in the dock)
I see that the ichat sample project by apple does not use the above approach and instead only listens to launch notifications. It then uses kAXApplicationActivatedNotification to add an AXObserver to the app. Is this the preferred way? (And also NSRunningApplications to add an observer to all already loaded apps).
I wanted to keep using just plain simple NSNotifications because I think it may be less memory intensive. (No need to keep an observer around for each and every app loaded).
check the NSRunningApplication object passed in the userinfo of the NSWorkspaceDidActivateApplicationNotification
NSRunningApplication *app = [note.userInfo objectForKey:NSWorkspaceApplicationKey];
if(app.isFinishedLaunching)
NSLog(#"up");

monitor external application with nsarray (noob)

I'm new to Objective-C and programming in general but I'm beginning to grasp the syntax and have a mostly working application however I'm struggling with one part. I'd like to be able to use the application I'm writing to monitor the activity of another application, namely wether it's open or not.
Ideally when a user clicks a button it will launch remote desktop client and then monitor when remote desktop client closes. I want to know when it closes so that I can either bring my application to the forefront or to restart the computer. Mostly my problems revolve around watching for when remote desktop client closes. Here's what I was thinking of trying:
do {
NSArray* apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:#"com.microsoft.rdc"];
} while ([apps count] >= 1);
The problem with the approach you've posted is that that while loop will block the main thread, preventing your application from doing anything else. You could run that on a background thread to prevent that problem, but that's probably not the best approach.
Instead, take a look at the NSWorkspace class's notifications. One of them is NSWorkspaceDidTerminateApplicationNotification. You should be able to do something like this:
// Put this part in your app delegate's applicationDidFinishLaunching: method, or some other appropriate place
NSNotificationCenter *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
[nc addObserver:self selector#selector(anotherAppDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
- (void)anotherAppDidTerminate:(NSNotification *)notification
{
NSRunningApplication *app = [[notification userInfo] objectForKey:NSWorkspaceApplicationKey];
if ([app.bundleIdentifier isEqualToString:#"com.microsoft.rdc"]) {
// RDC closed, so do whatever it is you want to here
}
}

NSURLConnection and multitasking in iOS

I'm using NSURLConnection to download resources asynchronously in iOS. (They are large-ish PDF files, so it takes some time on a slow connection.)
Now I'm updating my app from iOS 3 to iOS 4. As my app is none of location-aware, voip, and background music, I guess I need to do something.
My question is, then, what happens to the NSURLConnection currently running? Is it suspended and magically resumed when the app comes back to the foreground, or is it outright killed? If it is the latter, what is the standard strategy to resume it automatically later? Is there a open-source subclass of NSURLConnection which automatically does that?
You can start a task that will run for at most 10 minutes. Look at using the beginBackgroundTaskWithExpirationHandler: API for this purpose. Just be aware, if your task takes too long, it will be killed by the OS.
The NSURLConnection is indeed suspended and started again when the app enters the foreground. Just make sure you kill the connection if the app moves from suspended to not running like so:
- (void)applicationWillTerminate:(UIApplication *)application {
if (self.downloadConnection != nil){
[self.downloadConnection cancel];
}
}

LaunchAgent - Is there something like RunAtScreenSaver?

I am looking for a way to execute my app (it's a background task) at times, where the machine is "idle". A good incident would be when the screensaver launches. I already read the manual auf launchd and already use a LaunchAgent to lauch my app at certain intervals, but I found nothing that might help me launching my app when the screensaver is active.
Is there any possibility to do that?
Thanks in advance!
Josh
Have another process that runs in the background and listens for distributed notifications named com.apple.screenIsLocked and com.apple.screenIsUnlocked. (That's for Snow Leopard. Leopard used different notification names. Use Notification Watcher and experimentation to find out what they are.) When one of those notifications comes in, launch or nicely-quit* your real app, as appropriate.
*You'll want to use an Apple Event for this.
For Snow Leopard the screenIsLocked and screenIsUnlocked notifications aren't available anymore. What I've used successfully are these:
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:#selector(locked:) name:NSWorkspaceScreensDidSleepNotification object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:#selector(unlocked:) name:NSWorkspaceScreensDidWakeNotification object:nil];
I'm a new user, so I can't comment on or vote up portenkirchner's suggestion. Matt Swann has moved his ScriptSaver.
It does exactly what I want, run an AppleScript program when I unlock the screensaver.
You can use ScriptSaver by Matt Swann. This is a Mac OS X screensaver which can run AppleScripts when it activates and deactivates.
http://swannman.wordpress.com/projects/scriptsaver/