How to programmatically prevent a Mac from going to sleep?

后端 未结 3 1956
轮回少年
轮回少年 2020-11-27 17:24

Is there way to prevent a Mac from going to sleep programmatically using Objective-C? The I/O kit fundamentals section on Apple\'s dev site tells me that a driver gets notif

相关标签:
3条回答
  • 2020-11-27 17:53

    Apple's Q&A1340 replaces Q&A1160. The latest Q&A answers the question "Q: How can my application get notified when the computer is going to sleep or waking from sleep? How do I prevent sleep?"

    Listing 2 of Q&A1340:

    #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. 
    CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");
    
    IOPMAssertionID assertionID;
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                        kIOPMAssertionLevelOn, reasonForActivity, &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. 
    }
    

    Note that you can only stop idle time sleep, not sleep triggered by the user.

    For applications supporting Mac OS X 10.6 and later, use the new IOPMAssertion family of functions. These functions allow other applications and utilities to see your application's desire not to sleep; this is critical to working seamlessly with third party power management software.

    0 讨论(0)
  • 2020-11-27 18:07

    Here is the official Apple documentation (including code snippet):
    Technical Q&A QA1340 - How to I prevent sleep?

    Quote: Preventing sleep using I/O Kit in Mac OS X 10.6 Snow Leopard:

    #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. 
    CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");
    
    IOPMAssertionID assertionID;
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                        kIOPMAssertionLevelOn, reasonForActivity, &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. 
    }
    

    For older OSX version, check the following:
    Technical Q&A QA1160 - How can I prevent system sleep while my application is running?

    Quote: Example usage of UpdateSystemActivity (the canonical way for < 10.6)

    #include <CoreServices/CoreServices.h>
    
    void
    MyTimerCallback(CFRunLoopTimerRef timer, void *info)
    {
        UpdateSystemActivity(OverallAct);
    }
    
    
    int
    main (int argc, const char * argv[])
    {
        CFRunLoopTimerRef timer;
        CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL };
    
        timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, MyTimerCallback, &context);
        if (timer != NULL) {
            CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
        }
    
        /* Start the run loop to receive timer callbacks. You don't need to
        call this if you already have a Carbon or Cocoa EventLoop running. */
        CFRunLoopRun();
    
        CFRunLoopTimerInvalidate(timer);
        CFRelease(timer);
    
        return (0);
    }
    
    0 讨论(0)
  • 2020-11-27 18:08

    Just create an NSTimer that fires a function with this

    UpdateSystemActivity(OverallAct);
    

    I'm pretty sure that that's exactly what Caffeine does.

    0 讨论(0)
提交回复
热议问题