有没有办法使用Objective-C编程阻止Mac进入睡眠状态?苹果公司的开发网站上的I/O kit基础知识部分告诉我,驱动程序会收到空闲/系统睡眠的通知,但我找不到阻止系统进入睡眠状态的方法。这是否可能?
我已经找到一些使用Caffeine、jiggler、sleepless甚至AppleScript的解决方案,但我想用Objective-C来实现。谢谢。
有没有办法使用Objective-C编程阻止Mac进入睡眠状态?苹果公司的开发网站上的I/O kit基础知识部分告诉我,驱动程序会收到空闲/系统睡眠的通知,但我找不到阻止系统进入睡眠状态的方法。这是否可能?
我已经找到一些使用Caffeine、jiggler、sleepless甚至AppleScript的解决方案,但我想用Objective-C来实现。谢谢。
这里是包括代码片段在内的苹果官方文档:
Technical Q&A QA1340 - 如何防止睡眠?
引用: 在Mac OS X 10.6 Snow Leopard使用I/O Kit来防止睡眠:
#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.
}
对于较旧的OSX版本,请查看以下内容:
技术问答QA1160 - 我如何在我的应用程序运行时防止系统休眠?
引用: UpdateSystemActivity的使用示例(<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);
}
苹果的Q&A1340替代了Q&A1160。最新的Q&A回答了以下问题:“Q:我的应用程序如何在计算机即将进入睡眠或从睡眠中唤醒时得到通知?如何阻止睡眠?”
Q&A1340的第2个清单:
#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.
}
注意,您只能停止闲置时间的睡眠,而不能停止用户触发的睡眠。CFStringRef*
赋值时,XCode给了我“不兼容的指针类型”的错误。我必须在CFSTR()
调用之前添加(CFStringRef *)
来修复它。另外,你可能需要提到需要将IOKit.framework
添加到项目中。这两个都是正确的吗? - VolomikeIOPMAssertionCreateWithName()
调用中,我不得不添加一个星号 *reasonForActivity
以便让它编译通过。 - VolomikeCFStringRef reasonForActivity= CFSTR("Describe Activity Type");
。我很惊讶这么长时间以来没有人注意到并进行更正。 - c00000fdUpdateSystemActivity(OverallAct);
我非常确定那正是Caffeine所做的。