Original post https://github.com/onmyway133/blog/issues/88
I 've been using Apple Script to for my Finder extension FinderGo. Because of sandboxing, all scripts must lie inside Application Scripts
folder.
Today, I was rewriting my Xcode extension XcodeWay. Before Xcode 8, we could use Xcode plugin and all kinds of magic to make our dreams come true https://github.com/onmyway133/XcodeWay/blob/1.0/XcodeWay/Helper/FTGEnvironmentManager.m#L50. But then it does not work since Xcode Source Editor Extension was introduced. So I rewrote XcodeWay as an extension https://github.com/onmyway133/XcodeWay/releases/tag/1.1.0
Extension must run inside sandbox. If you switch App Sandbox
in your XcodeWayExtensions.entitlements
to NO
, it won't load. So sandbox restricts me a lot in what kinds of things I want to do. And under Xcode 9, I can't use NSWorkspace
to open Finder
.
So I think I could use Apple Script
too, and it worked like a charm. The only restriction is code reuse, since I only know how to run an entire script. One way is to import other Apple scripts https://stackoverflow.com/questions/2606136/import-applescript-methods-in-another-applescript but I think I will write all the functions inside 1 script, and find out how to call specific function.
By function, I also mean handler, procedure. I come across this snippet Scriptinator that pretty much inspires me, thanks to open source.
So here is my script that contains lots of functions . And here is ScriptRunner that explains how to build NSAppleEventDescriptor
. Note that you need to import Carbon
import Carbon
func eventDescriptior(functionName: String) -> NSAppleEventDescriptor {
var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
let target = NSAppleEventDescriptor(
descriptorType: typeProcessSerialNumber,
bytes: &psn,
length: MemoryLayout<ProcessSerialNumber>.size
)
let event = NSAppleEventDescriptor(
eventClass: UInt32(kASAppleScriptSuite),
eventID: UInt32(kASSubroutineEvent),
targetDescriptor: target,
returnID: Int16(kAutoGenerateReturnID),
transactionID: Int32(kAnyTransactionID)
)
let function = NSAppleEventDescriptor(string: functionName)
event.setParam(function, forKeyword: AEKeyword(keyASSubroutineName))
return event
}
Top comments (0)