2

I have a OS X agent app (which only runs from the icon in the menu bar). My app creates a NSTimer with random intervals to play a sound.

func setNewTimer(timeInterval: NSTimeInterval) {
    self.timer = NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: "playSound", userInfo: nil, repeats: false)
NSRunLoop.currentRunLoop().addTimer(self.timer!, forMode: NSRunLoopCommonModes)
    NSLog("Timer created for interval: \(timeInterval)")
}

The app works all fine after I start it and keep doing other work in other apps. It plays the sound at random times as expected.

If the computer goes to sleep for a short period and comes back the app will keep playing sounds at random times as expected.

However, if my computer goes to sleep for a long time (e.g. throughout the night), the app will not play sounds anymore.

It may be possible that the problem is that the timer may be disabled if the computer goes to deep sleep? or (preferably) Is there a way to detect that the computer awoke from sleep so I can reset my timer?

Note: Every time I call this function I first self.timer.invalidate() and recalculate the timeInterval. At sleep time (e.g. 23:00 to 08:00 ) the timer will not run, but instead will create an interval from 23:00 to 08:00 so that it 'fires' the next day in the morning.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
gbdavid
  • 1,639
  • 18
  • 40

1 Answers1

2

I've came up with a solution myself after I found that there was no reply for some time. The solution was pretty simple as I only needed to register for sleep and wake notifications (I added the code updated to Swift 3):

// App should get notifified when it goes to sleep
func receiveSleepNotification(_ notification: Notification) {
    NSLog("Sleep nottification received: \(notification.name)")
    // do invalidation work
}

/// App should get notified when the PC wakes up from sleep
func receiveWakeNotification(_ notification: Notification) {
    NSLog("Wake nottification received: \(notification.name)")
    // Reset/Restart tasks
}

func registerForNotitications() {
    //These notifications are filed on NSWorkspace's notification center, not the default
    // notification center. You will not receive sleep/wake notifications if you file
    //with the default notification center.
    NSWorkspace.shared().notificationCenter.addObserver(self, selector: #selector(AppDelegate.receiveSleepNotification(_:)), name: NSNotification.Name.NSWorkspaceWillSleep, object: nil)
    NSWorkspace.shared().notificationCenter.addObserver(self, selector: #selector(AppDelegate.receiveWakeNotification(_:)), name: NSNotification.Name.NSWorkspaceDidWake, object: nil)
}

func deRegisterFromNotifications() {
    NSWorkspace.shared().notificationCenter.removeObserver(self)
}
gbdavid
  • 1,639
  • 18
  • 40