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/
Related
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,
I would like to perform certain cleanup tasks when the app shuts down. I use an observer like:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appWillResignActiveNotif:) name:UIApplicationWillResignActiveNotification object:nil];
to get notified when the app goes to background.
The problem is that if the app crashes, there is no notification for me to do something.
I saw that testflight.com use a hook to recover crash information, I was wondering if it was possible to also detect crashes and perform some tasks.
My concern is regarding the call to:
CLLocationManager.stopMonitoringSignificantLocationChanges
not being done when app crashes, leaving users with a constant location icon on top. I know that crashes are not supposed to be frequent, but would like to clean as much as possible if I can under these circumstances.
you could install a global exceptionHandler or even a signalHandler
http://www.cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html
but remember: dont continue running after a crash. it is NOT safe :D
I've tried registering for NSWorkspaceDidWakeNotification with [NSNotificationCenter defaultCenter], but it never fires when my MacBook Pro wakes from sleep. Other notifications that I register for fire, so it's not an issue with how I'm registering for it.
Basically I need to get notified when a user's machine has woken from sleep, and the user has logged back in, or the machine has woken and the user is back in their account, in the case that the login screen wasn't displayed to them. If I have to handle that with multiple notifications, that's fine as well.
Any thoughts?
Thanks!
Cody
The notification NSWorkspaceDidWakeNotification does not come from the default notification center. This works:
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:#selector(wakeFromSleep:)
name:NSWorkspaceDidWakeNotification
object:nil];
There exists the Apple Q&A 1340 regarding this question.
This covers only the waking aspect of your question. You don't get a notification when you log in originally, because you app is not running then. But you probably mean the password prompt for unlocking after sleep, and there you are fine.
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.
I have some code that needs to be run when the application terminates. I register my controller for the NSApplicationWillTerminateNotification as follows:
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(applicationWillTerminate:)
name: NSApplicationWillTerminateNotification
object: nil];
Now, if I start my app and quit it within the first 20 seconds or so, applicationWillTerminate gets called. If I quit the application later, it doesn't. What in my application could cause this behaviour? I have also tried to set up my controller as NSApplication's delegate with same results. Any ideas?
Thanks.
Oh, and this is XCode 3.2, Snow Leopard 10.6.1, using 10.5 SDK. Happens in both Debug and Release builds.
There are several reasons why this might be happening.
If you are running GC'd, does your observer get collected and finalized before the termination happens? (I should test this and file a bug if it does as that at least needs to be documented)
Is your app silently crashing or calling exit() directly?
In general, you cannot count on the termination notification being received as the user might go for a force quit for the heck of it.
Also, in Snow Leopard, there is a feature called sudden termination that allows your app to let the system know that it is safe to kill the app instead of going through the normal termination rigamarole. It is documented in the NSProcessInfo documentation.