Last active
March 30, 2021 07:05
-
-
Save darrarski/c586ce379d3e7e91a57d89ed557192ec to your computer and use it in GitHub Desktop.
Get Mac OS X system idle time in Swift or Objective-C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Dariusz Rybicki on 17/04/16. | |
// Copyright © 2016 Darrarski. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
/** | |
Returns number of seconds since system became idle | |
@return `double` System idle time in seconds or -1 when unable to retrieve it | |
*/ | |
double SystemIdleTime(void) { | |
double idleSeconds = -1; | |
io_iterator_t iter = 0; | |
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) { | |
io_registry_entry_t entry = IOIteratorNext(iter); | |
if (entry) { | |
CFMutableDictionaryRef dict = NULL; | |
kern_return_t status; | |
status = IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0); | |
if (status == KERN_SUCCESS) { | |
CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime")); | |
if (obj) { | |
int64_t nanoseconds = 0; | |
if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) { | |
idleSeconds = (double) nanoseconds / NSEC_PER_SEC; | |
} | |
} | |
CFRelease(dict); | |
} | |
IOObjectRelease(entry); | |
} | |
IOObjectRelease(iter); | |
} | |
return idleSeconds; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Dariusz Rybicki on 17/04/16. | |
// Copyright © 2016 Darrarski. All rights reserved. | |
// | |
import Foundation | |
/** | |
Returns number of seconds since system became idle | |
returns: `Double?`: System idle time in seconds or nil when unable to retrieve it | |
*/ | |
public func SystemIdleTime() -> Double? { | |
var iterator: io_iterator_t = 0 | |
defer { IOObjectRelease(iterator) } | |
guard IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iterator) == KERN_SUCCESS else { return nil } | |
let entry: io_registry_entry_t = IOIteratorNext(iterator) | |
defer { IOObjectRelease(entry) } | |
guard entry != 0 else { return nil } | |
var unmanagedDict: Unmanaged<CFMutableDictionaryRef>? = nil | |
defer { unmanagedDict?.release() } | |
guard IORegistryEntryCreateCFProperties(entry, &unmanagedDict, kCFAllocatorDefault, 0) == KERN_SUCCESS else { return nil } | |
guard let dict = unmanagedDict?.takeUnretainedValue() else { return nil } | |
let key: CFString = "HIDIdleTime" | |
let value = CFDictionaryGetValue(dict, unsafeAddressOf(key)) | |
let number: CFNumberRef = unsafeBitCast(value, CFNumberRef.self) | |
var nanoseconds: Int64 = 0 | |
guard CFNumberGetValue(number, CFNumberType.SInt64Type, &nanoseconds) else { return nil } | |
let interval = Double(nanoseconds) / Double(NSEC_PER_SEC) | |
return interval | |
} |
@gbbr here is swift 3 version
public func SystemIdleTime() -> Double? {
var iterator: io_iterator_t = 0
defer { IOObjectRelease(iterator) }
guard IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iterator) == KERN_SUCCESS else {
return nil }
let entry: io_registry_entry_t = IOIteratorNext(iterator)
defer { IOObjectRelease(entry) }
guard entry != 0 else { return nil }
var unmanagedDict: Unmanaged<CFMutableDictionary>? = nil
defer { unmanagedDict?.release() }
guard IORegistryEntryCreateCFProperties(entry, &unmanagedDict, kCFAllocatorDefault, 0) == KERN_SUCCESS else { return nil }
guard let dict = unmanagedDict?.takeUnretainedValue() else { return nil }
let key: CFString = "HIDIdleTime" as CFString
let value = CFDictionaryGetValue(dict, Unmanaged.passUnretained(key).toOpaque())
let number: CFNumber = unsafeBitCast(value, to: CFNumber.self)
var nanoseconds: Int64 = 0
guard CFNumberGetValue(number, CFNumberType.sInt64Type, &nanoseconds) else { return nil }
let interval = Double(nanoseconds) / Double(NSEC_PER_SEC)
return interval
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Couldn't get this to work for Swift 3 / macOS, but it would be super useful :)