How to call function inside Apple Script

Issue #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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
}

Comments