Running Script from Script Library Using NSAppleScript

I am having problems running a script that resides in my script library by using NSAppleScript’s executeAndReturnError() method.

If I create a simple handler within a script:
[AppleScript]
script test
on go()
display dialog “hello”
end go
end script
[/AppleScript]

and execute it in Script Debugger or Script Editor using:
[AppleScript]
tell test to go()
[/AppleScript]

It works fine.

If I move the test script to my script library called TRGMusicScripts.scpt and run it in Script Editor with:
[AppleScript]
tell test of script “TRGMusicScripts” to go()



Again, it works fine.

But if I try to run the script from within Xcode using:
[AppleScript]
  func runGoFromLibrary() {
    let myScriptString =
"""
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell test of script "TRGMusicScripts" to go()
"""
    let myScript = NSAppleScript(source: myScriptString)!
    // This will help diagnose problems if the script can't execute
    var error: NSDictionary? = nil
    myScript.executeAndReturnError(&error)
    print("func extractArtworkFromFile: scripting error= \(error)")
  }

It fails with error 1708

What am I missing?

I can provide the entire Xcode code if that is needed.

Apologies if this has been answered previously. I looked, but couldn’t find anything.

macOS 10.15.3, Xcode 11.3.1

Model: Mac Pro 2019
AppleScript: 2.7
Browser: Safari 605.1.15
Operating System: Other

It looks like you’re trying to call a go() handler, but your library doesn’t have such a thing – you’ve buried it inside a script object. Is there some reason for putting it in a script object?

I eliminated the test script that was enclosing the go() handler in my library. Now the library (named myLibrary.scpt and saved at ~/Library/Script Libraries) is simply:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on go()
	display dialog "hello from library"
end go[/AppleScript]

and when I call go() from within Xcode using NSAppleScript as follows:


func runGoFromLibrary() {
let myScriptString =
“”"
use AppleScript version “2.4” – Yosemite (10.10) or later
use scripting additions

tell script “myLibrary” to go()
“”"
let myScript = NSAppleScript(source: myScriptString)!
// This will help diagnose problems if the script can’t execute
var error: NSDictionary? = nil
myScript.executeAndReturnError(&error)
print(“func extractArtworkFromFile: scripting error= (error)”)
}[/AppleScript]

I get error 1728:

But the handler in the library works just fine when called from Script Debugger using:

use AppleScript version “2.4” – Yosemite (10.10) or later
use scripting additions

tell script "myLibrary" to go()[/AppleScript]

Is there some reason myLibrary can't be found when the script is run from within Xcode using NSAppleScript?

Try loading the library with a use statement:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use myLib : script "myLibrary"

tell myLib to go()

I loaded the library with the “use” statement as you suggested. It works fine when run from Script Debugger. But when I embed the code in a string in Xcode and run NSAppleScript’s executeAndReturnError() method, error 1728 results:

It seems as though Xcode and NSAppleScript don’t know where to look for the library, whereas Script Editor (or Script Debugger) know to look in ~/Library/Script Libraries. Is it necessary to fully define the path to the library?

What happens if you call compileAndReturnError() before executeAndReturnError()?

I substituted compileAndReturnError() for executeAndReturnError() and got the same result:

I’m not sure what the issue is, but what you’re doing works fine here in an Objective-C project:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSString *code = @"use scripting additions\nuse myLib : script \"myLibrary\"\nmyLib's go()";
    NSAppleScript *script = [[NSAppleScript alloc] initWithSource:code];
    NSDictionary *__autoreleasing errDict;
    NSAppleEventDescriptor *result = [script executeAndReturnError:&errDict];    
    NSLog(@"Result: %@, error: %@", result, errDict);

2020-02-12 10:39:03.798074+1100 Throw ObjC[88132:3322973] Result: <NSAppleEventDescriptor: { 'bhit':'utxt'("OK") }>, error: (null)

You’re not in a sandboxed app, are you?

I suspect I am in a sandboxed app. My understanding is that apps created in Xcode starting with Mojave are sandboxed by default. I have not turned off sandboxing. However, I have taken several steps suggested by others to circumvent sandboxing-related issues. I modified the info.plist file to allow “Privacy - AppleEvents Sending …”. I have modified the macOS1.entitlements file to get com.apple.security.temporary-exception.apple-events for system events, finder and music apps. And I modified the project file, Signing & Capabilities, Hardened Runtime to allow AppleEvents. These changes were adequate for me to run my script from within Xcode using NSAppleScript when I embedded the entire AppleScript script in the string executed by NSAppleScript. But when I moved the script to my library and tried calling it with a short script string executed by NSAppleScript, that’s when the trouble began.

Update:
Well, your question about sandboxing may have allowed me to solve my own problem. In my macOS1.entitlements file, I changed “App Sandbox” to “NO”, and it looks like that may have solved the problem.

I thought turning off sandboxing was frowned upon, and was usually a basis for Apple to reject an app from inclusion on the App Store. But perhaps that’s the only (or at least the best) way to get something like this to work.

Thanks for your help.

The App Store requires all apps be sandboxed. I wouldn’t be surprised if sandboxing causes the issue you’re seeing, although I can see that at least one sandboxed app (BBEdit) can call script libraries from scripts in its Scripts menu.