Determining how much time has passed since the app was used - objective-c

I am looking to make an app that, after a given time of no use, will close or give a message to the user.
How can I implement this?

UKIDleTimer is what you're looking for. You create a timer that only fires when the system becomes idle and implement the following method in its delegate:
-(void) timerBeginsIdling: (id)sender {
// terminate app
[NSApp terminate];
}

How about:
[NSApp performSelector:#selector(terminate:)
withObject:nil
afterDelay:[your delay...]];

Look at various Hello World examples on the net for Objective C. Once you have a hello world example going, you'll want to add some event listeners to monitor user activity. When any of those event handlers are called as a result of a users' actions, they should set a variable with the time of that action. Finally, set up a timer to check for user inactivity, say once every 30 seconds, which checks that value, to see if it's exceeded the time at which you want the application to close. If so, then send an exit command.

Related

Objective-C: Refreshing FrontmostApplication

I wrote this little program which is supposed to print the current frontmost application twice, with a 3-second break in between.
void printFrontmostApp() {
NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;
NSLog(#"%#",frontmostApplication);
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
printFrontmostApp();
sleep(3);
printFrontmostApp();
}
return 0;
}
When I ran this program, I realised that frontmostApplication is not refreshed when it is called the second time. I found the solution here. But I still have two questions:
1) I want to know why the frontmostApplication is not updated.
2) How do I force it to refresh every time I call it? I don't want to receive a notification every time the frontmost application deactivates, because it is a little inefficient for my purposes.
Edit:
Just to be crystal clear, let's suppose the time now is 10:00:00. I call printFrontmostApp, and it prints "Xcode" to the console, because Xcode is the current frontmost app. Then the program sleeps for 3 seconds. At 10:00:01, I opened another app, say TextEdit. At 10:00:03, my program calls printFrontmostApp for the second time. I expect it to print "TextEdit", which is the current frontmost application. But it prints "Xcode" instead. I can't understand this behaviour.
Can someone please explain what happens at 10:00:03? The function seems to "remember" the value of frontmostApplication at 10:00:00 and retains it when it is called the second time. I thought that any memory will be released once it goes out of scope, so why is this happening?
And how do I get my program to get the frontmost app at 10:00:03? I can get the frontmost app at 10:00:00, I should be able to do the same 3 seconds later right?
The documentation for -[NSWorkspace runningApplications] — not the method you're using, but related — says:
Similar to the NSRunningApplication class’s properties, this property will only change when the main run loop is run in a common mode. Instead of polling, use key-value observing to be notified of changes to this array property.
From the NSRunningApplication documentation:
Properties that vary over time are inherently race-prone. For example, a hidden app may unhide itself at any time. To ameliorate this, properties persist until the next turn of the main run loop in a common mode. For example, if you repeatedly poll an unhidden app for its hidden property without allowing the run loop to run, it will continue to return NO, even if the app hides, until the next turn of the run loop.
It's a near certainty that the same principle applies to -frontmostApplication even though the documentation doesn't say so explicitly. You will never get different results by polling without allowing the run loop to run.
For 1) the answer is the same described in the question you have linked: You have to observe this notification, that tells you when a new application was activated:
NSWorkspaceDidActivateApplicationNotification
About 2) You have different observers for activation and deactivation like:
NSWorkspaceDidDeactivateApplicationNotification
So your are not going to observe notifications that you are not registered, please take a look at NSWorkspace Notifications for a comprehensive list.
Otherwise, please define your question about refreshing/polling (that I think it's not a good idea anyways).

How to use NSTimer to stop an action?

On the main view in my app, there is a refresh button. I would like for NSTimer to start on click and if 15 seconds pass and the app cannot connect to the server, I would like for it to stop trying to refresh and give an alert saying it could not connect. Thanks!
You don't need a timer for this. Use NSURLConnection to connect to the server, and initialize it with a request made with requestWithURL:cachePolicy:timeoutInterval:. If it takes longer than the timeInterval, it will invoke connection:didFailWithError:. You can query that to see if the reason for failure was that the connection timed out, and present your alert.
Implement a cancelConnection method to stop the connection:
- (void)cancelConnection {
... // If the connection is still open, stop it and alert the user
}
Then simply call
[self performSelector:#selector(cancelConnection) withObject:nil afterDelay:15.0]
when you open the connection, and if it is still running 15 seconds later, it will be stopped when the method is called.
Alternatively, you can look at this question for a detailed explanation of NSTimer.

Pausing the Current function for some time iphone

Hi all im trying to pause a function so some time in the middle of execution because ill have to wait for the call back functions from GData api and get my data ready to put in that function i dont know how to do that. I am developing in Xcode 4.2 really need some help
You need to consider redesigning a little bit. What ever portion of code you expect to process after callback happens, let that code called by the callback. That way it will give you the guarantee that it always executes after the callback.
where you want to wait your functionality write this code [self performSelector:#selector(WaitForTwoSecond) withObject:nil afterDelay:2]; and implement - (void)WaitForTwoSecond { //write your code here } this method wait for two second and after that you cant access all data and put it in appropriate place .
we can say that this function is working like in background process

Check if display is at sleep or receive sleep notifications

I have an application utility which becomes useless when there's no user. So, in order to save resources, I'd like it to know when/whether display is at sleep.
There's a dedicated article about wake/sleep notifications by apple, but it deals only with computer sleep and not display sleep.
Is there a way for application to 'hibernate' when display is at sleep?
Thank you
The DisplayWrangler service sends notifications for when the display will power off:
// Doesn't include error checking - just a quick example
io_service_t displayWrangler;
IONotificationPortRef notificationPort;
io_object_t notification;
displayWrangler = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceNameMatching("IODisplayWrangler");
notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
IOServiceAddInterestNotification(notificationPort, displayWrangler, kIOGeneralInterest, displayPowerNotificationsCallback, NULL, &notification);
CFRunLoopAddSource (CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode);
IOObjectRelease (displayWrangler);
Then the callback looks something like this:
void displayPowerNotificationsCallback(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
{
switch (messageType) {
case kIOMessageDeviceWillPowerOff :
// This is called twice - once for display dim event, then once
// for display power off
break;
case kIOMessageDeviceHasPoweredOn :
// Display powering back on
break;
}
}
This is response to a question asked a while ago - but I thought it would be useful to add my answer.
NSWorkspace has a couple of notifications for when displays wake and sleep: NSWorkspaceScreensDidSleepNotification and NSWorkspaceScreensDidWakeNotification
Since I couldn´t find any call issued by the display falling to sleep (maybe the screensaver does that? It´s very likely to kick in before the system falls to sleep), I´d suggest detecting the idle time manually and then comparing it to the display sleep settings.
This article covers how to get the idle time from IOKit and you should be able to easily get the current sleep settings, e.g. with "pmset -g | grep sleep".
Two minutes after posting the above, I discovered an open source command line tool that will probably help you a lot getting there: SleepWatcher seems to be able to do just what you asked for.

How do I pause a function in c or objective-c on mac without using sleep()

Hi I would like to pause the execution of a function in an cocoa project. I dont want to use sleep() because the function needs to resume after user interaction. I also want to avoid doing this with multiple calls to sleep.
Thanks for your responses. Ok I started the code while waiting for some answers. I then realized that sleep or pause would not be usefull to me because it freeses my whole program. I think I might have to do some threading. Here is the situation:
I have a program that uses coreplot. I also use it to debug and develop algorithms so I do lots of plots while the data is being processed (ie in the midfle of the code but I need the flexibility to put it anywhaere so I cant separate my function). I was able to do this with NSRunAlertPanel but having a message box like that doesnt make it very presentable and I cant do much with the main window while an alert is open.
I hope I am not too confusing with my explanation but if I am ill try to one line it here:
I would like to interact with my cocoa interface while one of my functions is stopped in the middle of what it is doing.
Its sounds to me like you're looking for -NSRunLoop runUntilDate:
Apple's Docs: runUntilDate
This code will cause the execution within your method to pause but still let other events like timers and user input occur:
while ( functionShouldPause )
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
Switching functionShouldPause back to false will allow the rest of the method to execute.
It seems more like you are interested in reacting to user events rather than "pausing" the function. You would probably want to put the code that you want to execute into another function that is called as a result of the user's actions.
In C you can use the pause() function in <unistd.h>. This causes the calling program to suspend until it receives a signal, at which point the pause call will return and your program will continue (or call a signal handler; depending on what signal was received).
So it sounds like you want to break the function into two parts; the bit that happens before the sleep and the bit that happens afterward. Before going to sleep, register for a notification that calls the "after" code, and can be triggered by the UI (by an IBAction connected to whatever UI element). Now instead of calling sleep(), run the run loop for the period you want to go to sleep for, then after that has returned post the "after" notification. In the "after" code, remove the object as an observer for that notification. Now, whichever happens first - the time runs out or the user interrupts you - you get to run the "after" code.
Isn't there a clock or timer function? When your button is pressed start running a loop like timeTillAction = 10 and do a loop of timeTillAction = timeTillAction - 1 until it reaches 0 then run whatever code after the 10 seconds.
Sorry if this isn't well explained.