2

I am working on a sandboxed app. I am looking to schedule power events (via IOPMSchedulePowerEvent) that allows the app to put the Mac to sleep and wake it up at prescribed times, while retaining the app sandbox.

Currently, the only way I can make the IOPMSchedulePowerEvent work is by running the app as "root" and de-enabling the sandbox. This is achieved by following the steps in one of my previous posts here

Is there a temporary exception entitlement that would allow me to schedule these power events while retaining the app sandbox and not forcing the app to run as root? The closest I have come to finding a solution so far is documented here. I'll admit, I'm fairly inexperienced in working with the temporary exception entitlements, so any insight provided would be most helpful!

is starting off with the com.apple.security.temporary-exception.iokit-user-client-class entitlement the proper place to start? How would I go about actually using the entitlement once it's included in the entitlements file?

Edit I think I've found a workaround that works well enough. I went away from the scheduling power events/entitlements route entirely, and I am instead preventing idle sleep using kIOPMAssertionTypeNoIdleSleep, while still allowing the display to sleep. This re-do of logic is simpler and accomplishes by in large the same goal I was previously trying to achieve. The Stack Overflow post that shows the related documentation is here.

Here's a copy of the code, plus a little extra I included to remove some warnings/deprecations:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

// reasonForActivity is a descriptive string used by the system whenever it needs 
// to tell the user why the system is not sleeping. For example, 
// "Mail Compacting Mailboxes" would be a useful string.

// NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
//    Do what we need to with the string types

NSString *reasonForActivity = @"Put Display to Sleep, Keep Machine Awake";

CFStringRef cfStringReasonForActivity = (__bridge CFStringRef)reasonForActivity;

IOPMAssertionID assertionID;

//    create assertion to prevent system from IDLE sleeping

IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
                                               kIOPMAssertionLevelOn, cfStringReasonForActivity, &assertionID);
if (success == kIOReturnSuccess)
{
//  Add the work you need to do without 
//  the system sleeping here.

success = IOPMAssertionRelease(assertionID);
//  The system will be able to sleep again. 
}
mgwiggles
  • 141
  • 5
  • The usual solution for keeping the main app sandboxed while running code with system privileges would be a combination of SMJobBless and an XPC service. – natevw Mar 15 '18 at 18:20

0 Answers0