Keeping an application alive in C++ on Apple Mac OS-X

If you are writing a cross-platform application you are probably not going to use the Native OS-X app development tools, and you might end up with something in C++, for example with Qt. However, you will be unable to access some internal OS-X functionality. One way to deal with this is writing something in Apple’s Objective-C that talks to the internal OS-X SDK. In this case, I have made a small wrapper to keep an application alive. So we are going to mix Objective-C into C++, which is fine and quite common for OS-X app development.
What this class does is two fold:

  1. Prevents an ‘App Nap’, whatever the hell that entails.
  2. Prevents the system from going automagically to some power-saving mode or idle, (display) sleep or suspend.

! Find the most recent version on GitHub here:
https://github.com/TimZaman/toolkit/blob/master/keepalive.h
https://github.com/TimZaman/toolkit/blob/master/keepalive.mm

keepalive.h

/**
--------------------------------------------------------------------------------
-   Module      :   keepalive.h
-   Description :   A wrapper to keep an app alive, written
-                   in C++ and Objective-C so made for the OSX platform.
-   Author      :   Tim Zaman, 18-FEB-2016
--------------------------------------------------------------------------------
*/
 
/*
 
Copyright (c) 2016 Tim Zaman
 
Permission to use, copy, modify, distribute, and sell this software
for any purpose is hereby granted without fee, provided
that (i) the above copyright notices and this permission notice appear in
all copies of the software and related documentation.
 
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 
*/
 
#ifndef KEEPALIVE_H
#define KEEPALIVE_H
 
class KeepAlive {
 public:
    KeepAlive(){
        KeepAliveMM();
    }
 
    ~KeepAlive(){
        KeepAliveDestructorMM();
    }
 
#ifdef __APPLE__ 
    void KeepAliveMM();
    void KeepAliveDestructorMM();
#else
    // Keep other platforms alive
#endif 
 
};
 
#endif

keepalive.mm

/**
--------------------------------------------------------------------------------
-   Module      :   keepalive.mm
-   Description :   A wrapper to keep an app alive, written
-                   in C++ and Objective-C so made for the OSX platform.
-   Author      :   Tim Zaman, 18-FEB-2016
--------------------------------------------------------------------------------
*/
 
#include "keepalive.h"
#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.
 
IOPMAssertionID assertionID;
 
void KeepAlive::KeepAliveMM(){
    // NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
    CFStringRef reasonForActivity = CFSTR("Program Running.");
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
    if (success == kIOReturnSuccess){
        // @TODO?
    } else {
        // @TODO?
    }
}
 
void KeepAlive::KeepAliveDestructorMM(){
    IOReturn success = IOPMAssertionRelease(assertionID);
}

In your CMakelists.txt just obviously add something along the lines of

add_executable( appname (...) <strong>keepalive.mm</strong>)

And then just call the creator in your main and make sure to keep it allocated.

Above code is free domain, or beerware, whatever.

Tim Zaman

MSc Biorobotics. Specialization in computer vision and deep learning. Works at NVIDIA.

You may also like...