androidmacoswakelock

Wake lock for Mac OS X


In Android, there's wake lock to keep the screen on. So, is there Mac equivalent to keep the screen on for a PC running Mac OS X? If that is the case, what are the APIs?


Solution

  • Yes, in OS X it is done at the OS level through IOPMLib, the Power Management subsystem, which is also the subsystem that controls AppNap under OS X Mavericks.

    Here's an example of what we do when performing heavy calculations. In our case, we keep the CPU from sleeping, but you can prevent the display from sleeping by using kIOPMAssertionTypePreventUserIdleDisplaySleep where we used kIOPMAssertionTypePreventUserIdleSystemSleep.

    @property IOPMAssertionID currentPowerAssertion;
    
    
    - (void)assertPowerRequirement:(NSString*)reason
    {
        // don't re-assert if we're already here
        if (_currentPowerAssertion)
            return;
    
        IOPMAssertionID assertionID;
    
        IOReturn success = IOPMAssertionCreateWithName( 
                kIOPMAssertionTypePreventUserIdleSystemSleep,   // prevent CPU from going to sleep 
                kIOPMAssertionLevelOn,                          // we are turning this on
                (__bridge CFStringRef)reason,                   // here's why
                &assertionID);                                  // reference for de-asserting
    
        if (success == kIOReturnSuccess) {
            _currentPowerAssertion = assertionID;
        } else {
            NSLog(@"Power assert failed");
        }
    }
    
    - (void)deassertPowerRequirement
    {
        if (!_currentPowerAssertion)
            return;
    
        IOReturn success = IOPMAssertionRelease(_currentPowerAssertion);
        if (success !=kIOReturnSuccess) {
            NSLog(@"Power de-assert failed");
        }
    
        _currentPowerAssertion = 0;
    }
    

    In this case, this is in our App delegate, and we have the currentPowerAssertion property to keep track. Since we only use one assertion state and only for one purpose, we use a single storage mechanism. However, you can assert multiple times from different parts of your program, as long as you balance the assertions with de-assertions and use appropriate reason. Specifications from Apple mandate a reason be given (not NULL), and suggest that the Application name and task be described in the assertion.

    It's important to make sure that you de-assert when you don't need this any longer, although assertions are kept on a per-app basis, so when your App quits, they will automatically be de-asserted.