Hi there,
My macOS application is able to control Powerpoint through AppleScript. The first step of controlling is to see if Microsoft Office installed or not. Here is the worked AppleScript:
set appID to "com.microsoft.Powerpoint"
-- check if the application exists
set doesExist to false
try
tell application "Finder" to get application file id appID
set doesExist to true
end try
return doesExist
If the Office is installed, the script returns "true" and "false" vice versa. The script is working under Script Editor and Xcode 8.3.3.
However I upgraded my Xcode to 10.3, the script always return "false". This stops me to do notarization. How my object-C call AppleScript API is as below:
// AppleScript macro
+ (NSString *)pptIsInstalledOrNot
{
return @"\n\
set appID to \"com.microsoft.Powerpoint\" \n\
-- check if the application exists \n\
set doesExist to false \n\
try \n\
tell application \"Finder\" to get application file id appID \n\
set doesExist to true \n\
end try \n\
\n\
return doesExist \n\
";
}
// AppleScript execution
+ (NSAppleEventDescriptor *)runProcess:(NSString *)script
errorDescription:(NSString **)errorDescription
{
NSDictionary *errorInfo = [[NSDictionary alloc] init];
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script];
NSAppleEventDescriptor *eventResult = [appleScript executeAndReturnError:&errorInfo];
// Check errorInfo
if (!eventResult) {
// Set error message
if ([errorInfo valueForKey:NSAppleScriptErrorMessage]) {
id message = [errorInfo valueForKey:NSAppleScriptErrorMessage];
if (errorDescription) {
*errorDescription = (NSString *)message;
}
}
}
else {
// Set output to the AppleScript's output
}
return eventResult;
}
// main process
Boolean isInstalled = false;
{
NSString *script = [self pptIsInstalledOrNot];
NSString *errorMessage = nil;
NSAppleEventDescriptor *descriptor = [self runProcess:script errorDescription:&errorMessage];
isInstalled = [descriptor booleanValue];
}
I ever tried other ways, still failed. How do I modify my program on XCode 10.3? Appreciate for any ideas and
thanks your time.
we are developing an application to control PowerPoint/Keynote, we found that the AppleScript is the only way controlling PowerPoint and we developed many AppleScript macros to control it.
Fair enough. It’s perfectly feasible to run AppleScripts to control scriptable apps. There are, however, some hoops you need to jump through.
Note As you mentioned notarisation, I’m assuming that you plan to deploy outside of the Mac App Store. If that’s incorrect, and you’re targeting the Mac App Store, things get trickier. Let me know if that’s the case.
On modern systems (10.14 and later) there are two things that you need to do in order to get a non-sandboxed app to script other apps:
string to yourNSAppleEventsUsageDescription
.Info.plist
If you have the hardened runtime enabled — which you’ll need if you want to notarise your app — you must add the Apple Events entitlement (
).com.apple.security.automation.apple-events
With both of those, the following code activates Keynote and starts the current presentation:
static NSString * scriptText = @
"tell application \"Keynote\"\n"
" activate\n"
" start document 1\n"
"end tell"
;
NSAppleScript * script = [[NSAppleScript alloc] initWithSource:scriptText];
assert(script != nil);
NSDictionary * error = nil;
NSAppleEventDescriptor * result = [script executeAndReturnError:&error];
if (result == nil) {
// … look at `error` …
NSLog(@"error: %@", error);
} else {
// … look at `result` …
NSLog(@"result: %@", result);
}
I tested this on 10.14.6 but I believe it’ll also work on 10.15 just fine.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"