Control Night Shift via AppleScriptObjC

Hi all,

This is my first post in MacScript, I know some basics of AppleScript but not much about objective-c.

Back to the topic, as I digging the solution in google about controlling night shift using AppleScript, I found there’s a project called “nshift” in GitHub that can alter the strength of night shift, it’s achieved by calling some methods of class “CBBlueLightClient” in a private framework “CoreBrightness”, I tried, it works.

Luckily, there’s a complete header file available in GitHub, I tried converting the objective-c code in nshift to Applescript, but the script failed to run:

use framework "CoreBrightness"
use framework "Foundation"

on NightShift(strength)
	set clientOBJ to a reference to current application's CBBlueLightClient's alloc's init
	if not strength = 0 then clientOBJ's setStrength_(strength, true)
	clientOBJ's setEnabled(strength = 0)
end NightShift


Result: error “-[CBBlueLightClient setStrength:]: unrecognized selector sent to instance 0x600003150180” number -10000

My questions are:

  1. why this error occurs while “setStrength” is a method in the header?
  2. There’s a method call “getStrength” in the header file, why does it require a float argument? And Why does it always return 1 no matter what float number I pass to it in applescript,

Any advice is appreciated.

There’s no such method. There are setStrength:commit: and setStrength:withPeriod:commit: methods, but no setStrength or setStrength: methods (that I can see).

Who knows? It’s in a private framework.

See above.

Playing with private frameworks is a matter of trial and error, and also carries an element of risk. But if you’re going to try it, you should follow the conventions of AppleScriptObjC. So your code would look more like this:

on NightShift(strength)
	set clientOBJ to current application's CBBlueLightClient's alloc()'s init()
	if not strength = 0 then clientOBJ's setStrength:strength commit:true -- or false
	clientOBJ's setEnabled:(strength = 0)
end NightShift

Thank your so much! It works! I’ve been stuck for days…

As for “getStrength”, I found someone used it in a swift project (Shifty@GitHub):

var strength: Float = 0
return strength

so this method actually receives a pointer, so I tried:

set testStr to 0
clientOBJ's getStrength:(a reference to testStr)
get testStr

But it doesn’t work as expected, is it the correct way to pass the address? I would also go through the some ApplescriptObjc tutorials.

Try something like:

set {theResult, theStrength} to clientOBJ's getStrength:reference
if theResult as boolean then -- success

Thanks! works like charm!