tags:

views:

715

answers:

3

I have an NSTimer running in my application that collects some data and sends it to a server periodically. In production the timer will fire every few hours.

I am worried about interfering with automatic sleep. In testing, some combinations of timer and sleep time prevent automatic sleep entirely — the display sleeps, the system keeps running. Setting my NSTimer to one minute always stops it.

Some Mac applications are notorious for interfering with automatic sleep when running (or all the time, if they install a daemon). What actions stop the system from sleeping and how can I run periodic tasks safely?

A: 

Have you looked into launchd? http://developer.apple.com/MacOsX/launchd.html

It is what the OS uses for its own services, so I'm sure sleep was taken into consideration.

pgb
I have indeed looked at launchd, but my process will already be running and I don't want to install a launchd job — or factor everything periodic out into a separate executable, for that matter.
Sidnicious
+1  A: 

I'm a bit confused, bear with me. =)

Activity by your application will reset the machine's sleep timer, so unless the delay between transmits is larger than the inactivity period, the machine won't go to sleep. I'm not completely sure what classifies as "activity" on OS X, but if it's anything like Linux, I expect that network or disk IO would count as would processes in the running state - that is to say crunching numbers or shuffling data around in RAM.

Also, in the event the system did go to sleep, are you expecting the machine to wake up so your app can talk to the remote host?

BonkaBonka
No worries. I don't know what Mac OS X counts as sleep-preventing activity either, and that's half my question. I want to be able to access the disk and network *without* preventing automatic sleep. I don't expect or want to wake up the machine, my app is happy to wait until the user does that.
Sidnicious
+2  A: 

Accessing the disk will prevent your computer from sleeping, according to Apple's article "Mac OS X: Why your Mac might not sleep or stay in sleep mode".

Additionally, my testing has shown that the priority of a thread also has an impact on whether or not a computer will sleep. The following code with a timer will allow a computer to sleep.

@implementation AppController

-(void)timerFired:(NSTimer *)aTimer
{

}

-(void)spawnThread
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   [NSThread setThreadPriority:0.0];

   [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

   while(1) //Run forever!
   {
      [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:300]];
   }

   [pool drain];
}

-(void)awakeFromNib
{
   [NSThread detachNewThreadSelector:@selector(spawnThread) toTarget:self withObject:nil];
}

@end

Removal of the setThreadPriority call will prevent the computer from sleeping.

JimDusseau