Search code examples
swiftmacosiokit

macOS. How to get CPU temperature programmatically


I need to get CPU temperature using Swift, but I can't find any information except for this.

I think that I should use IOKit.framework but again there's no much information about it.


Solution

  • using https://github.com/lavoiesl/osx-cpu-temp/blob/master/smc.c I got it to work. You have to do a few things:

    Simplify main() to something else:

    double calculate()
    {
        SMCOpen();
        double temperature = SMCGetTemperature(SMC_KEY_CPU_TEMP);
        SMCClose();
        temperature = convertToFahrenheit(temperature);
        return temperature;
    }
    

    Write an ObjC wrapper:

    #import "SMCObjC.h"
    #import "smc.h"   
    @implementation SMCObjC
    
    +(double)calculateTemp {
        return calculate();
    }
    
    @end
    

    Add the header to your Swift bridging header.

    //
    //  Use this file to import your target's public headers that you would like to expose to Swift.
    //
    #import "SMCObjC.h"
    

    If the app is sandboxed, add a security exemption for AppleSMC:

    <dict>
        <key>com.apple.security.app-sandbox</key>
        <true/>
        <key>com.apple.security.files.user-selected.read-only</key>
        <true/>
        <key>com.apple.security.temporary-exception.sbpl</key>
        <array>
            <string>(allow iokit-open)</string>
            <string>(allow iokit-set-properties (iokit-property &quot;AppleSMC&quot;))</string>
            <string>(allow mach-lookup (global-name &quot;com.apple.AssetCacheLocatorService&quot;))</string>
        </array>
    </dict>
    </plist>
    

    Call it from Swift.

    import Cocoa
    
    class ViewController: NSViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let temp = SMCObjC.calculateTemp()
            print("I got \(temp) in swift")
        }
    }